Check error when creating local storage directory

When we have an error creating the local storage directory, such as if
the permissions are wrong, we fail to produce a helpful error message,
since we fail to check the error we produce.

Let's take the error we get in such a case and pass it through to the
transfer queue, where we can handle it as any other error.  This means
that if only one directory has a problem, we can transfer the rest of
the objects and fail for only the one problematic object.
This commit is contained in:
brian m. carlson 2020-02-10 15:52:15 +00:00
parent c3b776db6e
commit a514c7cf43
No known key found for this signature in database
GPG Key ID: 2D0C9BC12F82B3A1
8 changed files with 34 additions and 9 deletions

@ -136,7 +136,7 @@ func migrateExportCommand(cmd *cobra.Command, args []string) {
}
if _, err := os.Stat(downloadPath); os.IsNotExist(err) {
q.Add(p.Name, downloadPath, p.Oid, p.Size, false)
q.Add(p.Name, downloadPath, p.Oid, p.Size, false, nil)
}
})
gs.ScanRefs(opts.Include, opts.Exclude, nil)

@ -59,7 +59,7 @@ func delayedSmudge(gf *lfs.GitFilter, s *git.FilterProcessScanner, to io.Writer,
if !skip && filter.Allows(filename) {
if _, statErr := os.Stat(path); statErr != nil {
q.Add(filename, path, ptr.Oid, ptr.Size, false)
q.Add(filename, path, ptr.Oid, ptr.Size, false, err)
return 0, true, ptr, nil
}

@ -131,9 +131,9 @@ func buildFilepathFilter(config *config.Configuration, includeArg, excludeArg *s
return filepathfilter.New(inc, exc)
}
func downloadTransfer(p *lfs.WrappedPointer) (name, path, oid string, size int64, missing bool) {
path, _ = cfg.Filesystem().ObjectPath(p.Oid)
return p.Name, path, p.Oid, p.Size, false
func downloadTransfer(p *lfs.WrappedPointer) (name, path, oid string, size int64, missing bool, err error) {
path, err = cfg.Filesystem().ObjectPath(p.Oid)
return p.Name, path, p.Oid, p.Size, false, err
}
// Get user-readable manual install steps for hooks

@ -258,7 +258,7 @@ func (c *uploadContext) UploadPointers(q *tq.TransferQueue, unfiltered ...*lfs.W
ExitWithError(err)
}
q.Add(t.Name, t.Path, t.Oid, t.Size, t.Missing)
q.Add(t.Name, t.Path, t.Oid, t.Size, t.Missing, nil)
c.SetUploaded(p.Oid)
}
}

@ -101,7 +101,7 @@ func (f *GitFilter) downloadFile(writer io.Writer, ptr *Pointer, workingfile, me
tq.WithProgressCallback(cb),
tq.RemoteRef(f.RemoteRef()),
)
q.Add(filepath.Base(workingfile), mediafile, ptr.Oid, ptr.Size, false)
q.Add(filepath.Base(workingfile), mediafile, ptr.Oid, ptr.Size, false, nil)
q.Wait()
if errs := q.Errors(); len(errs) > 0 {

@ -206,7 +206,7 @@ func buildTestData(repo *t.Repo, manifest *tq.Manifest) (oidsExist, oidsMissing
if err != nil {
return nil, nil, err
}
uploadQueue.Add(t.Name, t.Path, t.Oid, t.Size, false)
uploadQueue.Add(t.Name, t.Path, t.Oid, t.Size, false, nil)
}
uploadQueue.Wait()

@ -619,3 +619,23 @@ begin_test "fetch with invalid remote"
grep "Invalid remote name" fetch.log
)
end_test
begin_test "fetch fails when LFS directory has wrong permissions"
(
set -e
# Windows lacks POSIX permissions.
[ "$IS_WINDOWS" -eq 1 ] && exit 0
# Root is exempt from permissions.
[ "$(id -u)" -eq 0 ] && exit 0
cd shared
rm -rf .git/lfs/objects
mkdir .git/lfs/objects
chmod 400 .git/lfs/objects
git lfs fetch 2>&1 | tee fetch.log
grep "error trying to create local storage directory" fetch.log
)
end_test

@ -324,7 +324,12 @@ func NewTransferQueue(dir Direction, manifest *Manifest, remote string, options
//
// Only one file will be transferred to/from the Path element of the first
// transfer.
func (q *TransferQueue) Add(name, path, oid string, size int64, missing bool) {
func (q *TransferQueue) Add(name, path, oid string, size int64, missing bool, err error) {
if err != nil {
q.errorc <- err
return
}
t := &objectTuple{
Name: name,
Path: path,