The loop that feeds git update-index MUST NOT panic
This commit is contained in:
parent
711f483767
commit
e9092641a9
@ -68,6 +68,7 @@ func checkoutFromFetchChan(include []string, exclude []string, in chan *lfs.Wrap
|
|||||||
|
|
||||||
// Launch git update-index
|
// Launch git update-index
|
||||||
c := make(chan *lfs.WrappedPointer)
|
c := make(chan *lfs.WrappedPointer)
|
||||||
|
|
||||||
var wait sync.WaitGroup
|
var wait sync.WaitGroup
|
||||||
wait.Add(1)
|
wait.Add(1)
|
||||||
|
|
||||||
@ -142,7 +143,19 @@ func checkoutAll() {
|
|||||||
// Populate the working copy with the real content of objects where the file is
|
// Populate the working copy with the real content of objects where the file is
|
||||||
// either missing, or contains a matching pointer placeholder, from a list of pointers.
|
// either missing, or contains a matching pointer placeholder, from a list of pointers.
|
||||||
// If the file exists but has other content it is left alone
|
// If the file exists but has other content it is left alone
|
||||||
|
// Callers of this function MUST NOT Panic or otherwise exit the process
|
||||||
|
// without waiting for this function to shut down. If the process exits while
|
||||||
|
// update-index is in the middle of processing a file the git index can be left
|
||||||
|
// in a locked state.
|
||||||
func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
|
func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
|
||||||
|
// Get a converter from repo-relative to cwd-relative
|
||||||
|
// Since writing data & calling git update-index must be relative to cwd
|
||||||
|
repopathchan := make(chan string, 1)
|
||||||
|
cwdpathchan, err := lfs.ConvertRepoFilesRelativeToCwd(repopathchan)
|
||||||
|
if err != nil {
|
||||||
|
Panic(err, "Could not convert file paths")
|
||||||
|
}
|
||||||
|
|
||||||
// Fire up the update-index command
|
// Fire up the update-index command
|
||||||
cmd := exec.Command("git", "update-index", "-q", "--refresh", "--stdin")
|
cmd := exec.Command("git", "update-index", "-q", "--refresh", "--stdin")
|
||||||
updateIdxStdin, err := cmd.StdinPipe()
|
updateIdxStdin, err := cmd.StdinPipe()
|
||||||
@ -154,13 +167,10 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
|
|||||||
Panic(err, "Could not update the index")
|
Panic(err, "Could not update the index")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a converter from repo-relative to cwd-relative
|
// From this point on, git update-index is running. Code in this loop MUST
|
||||||
// Since writing data & calling git update-index must be relative to cwd
|
// NOT Panic() or otherwise cause the process to exit. If the process exits
|
||||||
repopathchan := make(chan string, 1)
|
// while update-index is in the middle of updating, the index can remain in a
|
||||||
cwdpathchan, err := lfs.ConvertRepoFilesRelativeToCwd(repopathchan)
|
// locked state.
|
||||||
if err != nil {
|
|
||||||
Panic(err, "Could not convert file paths")
|
|
||||||
}
|
|
||||||
|
|
||||||
// As files come in, write them to the wd and update the index
|
// As files come in, write them to the wd and update the index
|
||||||
for pointer := range in {
|
for pointer := range in {
|
||||||
@ -172,24 +182,27 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
|
|||||||
// File has non-pointer content, leave it alone
|
// File has non-pointer content, leave it alone
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
Panic(err, "Problem accessing %v", pointer.Name)
|
LoggedError(err, "Problem accessing %v", pointer.Name)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
if filepointer != nil && filepointer.Oid != pointer.Oid {
|
if filepointer != nil && filepointer.Oid != pointer.Oid {
|
||||||
// User has probably manually reset a file to another commit
|
// User has probably manually reset a file to another commit
|
||||||
// while leaving it a pointer; don't mess with this
|
// while leaving it a pointer; don't mess with this
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// OK now we can (over)write the file content
|
|
||||||
repopathchan <- pointer.Name
|
repopathchan <- pointer.Name
|
||||||
cwdfilepath := <-cwdpathchan
|
cwdfilepath := <-cwdpathchan
|
||||||
// smudge but set auto-download to false
|
|
||||||
err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, nil)
|
err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == lfs.DownloadDeclinedError {
|
if err == lfs.DownloadDeclinedError {
|
||||||
// acceptable error, data not local (fetch not run or include/exclude)
|
// acceptable error, data not local (fetch not run or include/exclude)
|
||||||
LoggedError(err, "Skipped checkout for %v, content not local. Use fetch to download.", pointer.Name)
|
LoggedError(err, "Skipped checkout for %v, content not local. Use fetch to download.", pointer.Name)
|
||||||
} else {
|
} else {
|
||||||
Panic(err, "Could not checkout file")
|
LoggedError(err, "Could not checkout file")
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,5 +214,4 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
|
|||||||
if err := cmd.Wait(); err != nil {
|
if err := cmd.Wait(); err != nil {
|
||||||
Panic(err, "Error updating the git index")
|
Panic(err, "Error updating the git index")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user