The loop that feeds git update-index MUST NOT panic

This commit is contained in:
rubyist 2015-08-07 15:35:43 -04:00
parent 711f483767
commit e9092641a9

@ -68,6 +68,7 @@ func checkoutFromFetchChan(include []string, exclude []string, in chan *lfs.Wrap
// Launch git update-index
c := make(chan *lfs.WrappedPointer)
var wait sync.WaitGroup
wait.Add(1)
@ -142,7 +143,19 @@ func checkoutAll() {
// 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.
// 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) {
// 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
cmd := exec.Command("git", "update-index", "-q", "--refresh", "--stdin")
updateIdxStdin, err := cmd.StdinPipe()
@ -154,13 +167,10 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
Panic(err, "Could not update the index")
}
// 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")
}
// From this point on, git update-index is running. Code in this loop MUST
// NOT Panic() or otherwise cause the process to exit. If the process exits
// while update-index is in the middle of updating, the index can remain in a
// locked state.
// As files come in, write them to the wd and update the index
for pointer := range in {
@ -172,24 +182,27 @@ func checkoutWithChan(in <-chan *lfs.WrappedPointer) {
// File has non-pointer content, leave it alone
continue
}
Panic(err, "Problem accessing %v", pointer.Name)
LoggedError(err, "Problem accessing %v", pointer.Name)
continue
}
if filepointer != nil && filepointer.Oid != pointer.Oid {
// User has probably manually reset a file to another commit
// while leaving it a pointer; don't mess with this
continue
}
// OK now we can (over)write the file content
repopathchan <- pointer.Name
cwdfilepath := <-cwdpathchan
// smudge but set auto-download to false
err = lfs.PointerSmudgeToFile(cwdfilepath, pointer.Pointer, false, nil)
if err != nil {
if err == lfs.DownloadDeclinedError {
// 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)
} 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 {
Panic(err, "Error updating the git index")
}
}