diff --git a/commands/command_pre_push.go b/commands/command_pre_push.go index e878b148..cb800b0e 100644 --- a/commands/command_pre_push.go +++ b/commands/command_pre_push.go @@ -81,7 +81,10 @@ func prePushCommand(cmd *cobra.Command, args []string) { u, wErr := lfs.NewUploadable(pointer.Oid, pointer.Name, i+1, len(pointers)) if wErr != nil { - if Debugging || wErr.Panic { + if cleanPointerErr, ok := wErr.Err.(*lfs.CleanedPointerError); ok { + Exit("%s is an LFS pointer to %s, which does not exist in .git/lfs/objects.\n\nRun 'git lfs fsck' to verify Git LFS objects.", + pointer.Name, cleanPointerErr.Pointer.Oid) + } else if Debugging || wErr.Panic { Panic(wErr.Err, wErr.Error()) } else { Exit(wErr.Error()) diff --git a/lfs/pointer_clean.go b/lfs/pointer_clean.go index 2d998bee..0d7c7c8e 100644 --- a/lfs/pointer_clean.go +++ b/lfs/pointer_clean.go @@ -14,7 +14,8 @@ type cleanedAsset struct { } type CleanedPointerError struct { - Bytes []byte + Pointer *Pointer + Bytes []byte } func (e *CleanedPointerError) Error() string { @@ -36,9 +37,9 @@ func PointerClean(reader io.Reader, size int64, cb CopyCallback) (*cleanedAsset, cb = nil } - by, _, err := DecodeFrom(reader) + by, ptr, err := DecodeFrom(reader) if err == nil && len(by) < 512 { - return nil, &CleanedPointerError{by} + return nil, &CleanedPointerError{ptr, by} } multi := io.MultiReader(bytes.NewReader(by), reader) diff --git a/lfs/upload_queue.go b/lfs/upload_queue.go index 40cd344b..cbd075ad 100644 --- a/lfs/upload_queue.go +++ b/lfs/upload_queue.go @@ -18,6 +18,7 @@ type Uploadable struct { // NewUploadable builds the Uploadable from the given information. func NewUploadable(oid, filename string, index, totalFiles int) (*Uploadable, *WrappedError) { path, err := LocalMediaPath(oid) + if err != nil { return nil, Errorf(err, "Error uploading file %s (%s)", filename, oid) } diff --git a/test/test-pre-push.sh b/test/test-pre-push.sh index ad7888a7..cbe9f6f4 100755 --- a/test/test-pre-push.sh +++ b/test/test-pre-push.sh @@ -106,7 +106,7 @@ begin_test "pre-push with existing file" reponame="$(basename "$0" ".sh")-existing-file" setup_remote_repo "$reponame" - clone_repo "$reponame" dry-run2 + clone_repo "$reponame" existing-file echo "existing" > existing.dat git add existing.dat git commit -m "add existing dat" @@ -137,3 +137,47 @@ begin_test "pre-push with existing file" } ) end_test + +begin_test "pre-push with existing pointer" +( + set -e + + reponame="$(basename "$0" ".sh")-existing-pointer" + setup_remote_repo "$reponame" + clone_repo "$reponame" existing-pointer + + echo "$(pointer "7aa7a5359173d05b63cfd682e3c38487f3cb4f7f1d60659fe59fab1505977d4c" 4)" > new.dat + git add new.dat + git commit -m "add new pointer" + mkdir -p .git/lfs/objects/7a/a7 + echo "new" > .git/lfs/objects/7a/a7/7aa7a5359173d05b63cfd682e3c38487f3cb4f7f1d60659fe59fab1505977d4c + + # push file to the git lfs server + echo "refs/heads/master master refs/heads/master 0000000000000000000000000000000000000000" | + git lfs pre-push origin "$GITSERVER/$reponame" 2>&1 | + tee push.log + grep "(1 of 1 files)" push.log +) +end_test + +begin_test "pre-push with missing pointer" +( + set -e + + reponame="$(basename "$0" ".sh")-missing-pointer" + setup_remote_repo "$reponame" + clone_repo "$reponame" missing-pointer + + echo "$(pointer "7aa7a5359173d05b63cfd682e3c38487f3cb4f7f1d60659fe59fab1505977d4c" 4)" > new.dat + git add new.dat + git commit -m "add new pointer" + + # assert that push fails + set +e + echo "refs/heads/master master refs/heads/master 0000000000000000000000000000000000000000" | + git lfs pre-push origin "$GITSERVER/$reponame" 2>&1 | + tee push.log + set -e + grep "new.dat is an LFS pointer to 7aa7a5359173d05b63cfd682e3c38487f3cb4f7f1d60659fe59fab1505977d4c, which does not exist in .git/lfs/objects" push.log +) +end_test