Merge branch 'master' into streaming-log-stats

This commit is contained in:
risk danger olson 2017-04-28 09:22:23 -06:00 committed by GitHub
commit 871bcca2e9
7 changed files with 82 additions and 27 deletions

@ -91,6 +91,8 @@ func pull(remote string, filter *filepathfilter.Filter) {
processQueue := time.Now()
if err := gitscanner.ScanTree(ref.Sha); err != nil {
singleCheckout.Close()
ExitWithError(err)
}

@ -42,6 +42,8 @@ func statusCommand(cmd *cobra.Command, args []string) {
scanner, err := lfs.NewPointerScanner()
if err != nil {
scanner.Close()
ExitWithError(err)
}

@ -48,8 +48,9 @@ type uploadContext struct {
trackedLocksMu *sync.Mutex
// ALL verifiable locks
ourLocks map[string]locking.Lock
theirLocks map[string]locking.Lock
lockVerifyState verifyState
ourLocks map[string]locking.Lock
theirLocks map[string]locking.Lock
// locks from ourLocks that were modified in this push
ownedLocks []locking.Lock
@ -101,7 +102,8 @@ func newUploadContext(remote string, dryRun bool) *uploadContext {
ctx.tq = newUploadQueue(ctx.Manifest, ctx.Remote, tq.WithProgress(ctx.meter), tq.DryRun(ctx.DryRun))
ctx.committerName, ctx.committerEmail = cfg.CurrentCommitter()
ourLocks, theirLocks := verifyLocks(remote)
ourLocks, theirLocks, verifyState := verifyLocks(remote)
ctx.lockVerifyState = verifyState
for _, l := range theirLocks {
ctx.theirLocks[l.Path] = l
}
@ -112,13 +114,9 @@ func newUploadContext(remote string, dryRun bool) *uploadContext {
return ctx
}
func verifyLocks(remote string) (ours, theirs []locking.Lock) {
func verifyLocks(remote string) (ours, theirs []locking.Lock, st verifyState) {
endpoint := getAPIClient().Endpoints.Endpoint("upload", remote)
state := getVerifyStateFor(endpoint)
if state == verifyStateDisabled {
return
}
lockClient := newLockClient(remote)
@ -126,22 +124,27 @@ func verifyLocks(remote string) (ours, theirs []locking.Lock) {
if err != nil {
if errors.IsNotImplementedError(err) {
disableFor(endpoint)
} else if !errors.IsAuthError(err) {
Print("Remote %q does not support the LFS locking API. Consider disabling it with:", remote)
Print(" $ git config 'lfs.%s.locksverify' false", endpoint.Url)
if state == verifyStateEnabled {
ExitWithError(err)
} else if state == verifyStateUnknown || state == verifyStateEnabled {
if errors.IsAuthError(err) {
if state == verifyStateUnknown {
Error("WARNING: Authentication error: %s", err)
} else if state == verifyStateEnabled {
Exit("ERROR: Authentication error: %s", err)
}
} else {
Print("Remote %q does not support the LFS locking API. Consider disabling it with:", remote)
Print(" $ git config 'lfs.%s.locksverify' false", endpoint.Url)
if state == verifyStateEnabled {
ExitWithError(err)
}
}
} else {
ExitWithError(err)
}
} else if state == verifyStateUnknown {
Print("Locking support detected on remote %q. Consider enabling it with:", remote)
Print(" $ git config 'lfs.%s.locksverify' true", endpoint.Url)
}
return ours, theirs
return ours, theirs, state
}
func (c *uploadContext) scannerError() error {
@ -223,7 +226,16 @@ func (c *uploadContext) prepareUpload(unfiltered ...*lfs.WrappedPointer) (*tq.Tr
c.trackedLocksMu.Lock()
c.unownedLocks = append(c.unownedLocks, lock)
c.trackedLocksMu.Unlock()
canUpload = false
// If the verification state is enabled, this failed
// locks verification means that the push should fail.
//
// If the state is disabled, the verification error is
// silent and the user can upload.
//
// If the state is undefined, the verification error is
// sent as a warning and the user can upload.
canUpload = c.lockVerifyState != verifyStateEnabled
}
if lock, ok := c.ourLocks[p.Name]; ok {
@ -308,16 +320,18 @@ func (c *uploadContext) Await() {
os.Exit(2)
}
var avoidPush bool
c.trackedLocksMu.Lock()
if ul := len(c.unownedLocks); ul > 0 {
avoidPush = true
Print("Unable to push %d locked file(s):", ul)
for _, unowned := range c.unownedLocks {
Print("* %s - %s", unowned.Path, unowned.Owner)
}
if c.lockVerifyState == verifyStateEnabled {
Exit("ERROR: Cannot update locked files.")
} else {
Error("WARNING: The above files would have halted this push.")
}
} else if len(c.ownedLocks) > 0 {
Print("Consider unlocking your own locked file(s): (`git lfs unlock <path>`)")
for _, owned := range c.ownedLocks {
@ -325,10 +339,6 @@ func (c *uploadContext) Await() {
}
}
c.trackedLocksMu.Unlock()
if avoidPush {
Error("WARNING: The above files would have halted this push.")
}
}
var (

@ -42,6 +42,22 @@ type extCommand struct {
func pipeExtensions(request *pipeRequest) (response pipeResponse, err error) {
var extcmds []*extCommand
defer func() {
// In the case of an early return before the end of this
// function (in response to an error, etc), kill all running
// processes. Errors are ignored since the function has already
// returned.
//
// In the happy path, the commands will have already been
// `Wait()`-ed upon and e.cmd.Process.Kill() will return an
// error, but we can ignore it.
for _, e := range extcmds {
if e.cmd.Process != nil {
e.cmd.Process.Kill()
}
}
}()
for _, e := range request.extensions {
var pieces []string
switch request.action {

@ -19,6 +19,8 @@ import (
func runCatFileBatch(pointerCh chan *WrappedPointer, lockableCh chan string, lockableSet *lockableNameSet, revs *StringChannelWrapper, errCh chan error) error {
scanner, err := NewPointerScanner()
if err != nil {
scanner.Close()
return err
}

@ -48,6 +48,8 @@ func runScanTree(cb GitScannerFoundPointer, ref string, filter *filepathfilter.F
func catFileBatchTree(treeblobs *TreeBlobChannelWrapper) (*PointerChannelWrapper, error) {
scanner, err := NewPointerScanner()
if err != nil {
scanner.Close()
return nil, err
}

@ -517,6 +517,7 @@ begin_test "pre-push with their lock on lfs file"
pushd "$TRASHDIR" >/dev/null
clone_repo "$reponame" "$reponame-assert"
git config lfs.locksverify true
printf "unauthorized changes" >> locked_theirs.dat
git add locked_theirs.dat
@ -524,9 +525,17 @@ begin_test "pre-push with their lock on lfs file"
git commit --no-verify -m "add unauthorized changes"
git push origin master 2>&1 | tee push.log
res="${PIPESTATUS[0]}"
if [ "0" -eq "$res" ]; then
echo "push should fail"
exit 1
fi
grep "Unable to push 1 locked file(s)" push.log
grep "* locked_theirs.dat - Git LFS Tests" push.log
grep "ERROR: Cannot update locked files." push.log
refute_server_object "$reponame" "$(calc_oid_file locked_theirs.dat)"
popd >/dev/null
)
end_test
@ -562,6 +571,7 @@ begin_test "pre-push with their lock on non-lfs lockable file"
pushd "$TRASHDIR" >/dev/null
clone_repo "$reponame" "$reponame-assert"
git config lfs.locksverify true
git lfs update # manually add pre-push hook, since lfs clean hook is not used
echo "other changes" >> readme.txt
@ -571,10 +581,19 @@ begin_test "pre-push with their lock on non-lfs lockable file"
git commit --no-verify -am "add unauthorized changes"
git push origin master 2>&1 | tee push.log
res="${PIPESTATUS[0]}"
if [ "0" -eq "$res" ]; then
echo "push should fail"
exit 1
fi
grep "Unable to push 2 locked file(s)" push.log
grep "* large_locked_theirs.dat - Git LFS Tests" push.log
grep "* tiny_locked_theirs.dat - Git LFS Tests" push.log
grep "ERROR: Cannot update locked files." push.log
refute_server_object "$reponame" "$(calc_oid_file large_locked_theirs.dat)"
refute_server_object "$reponame" "$(calc_oid_file tiny_locked_theirs.dat)"
popd >/dev/null
)
end_test
@ -784,6 +803,7 @@ begin_test "pre-push locks verify 403 with verification enabled"
git config "lfs.$endpoint.locksverify" true
git push origin master 2>&1 | tee push.log
grep "ERROR: Authentication error" push.log
refute_server_object "$reponame" "$contents_oid"
[ "true" = "$(git config "lfs.$endpoint.locksverify")" ]
@ -836,8 +856,9 @@ begin_test "pre-push locks verify 403 with verification unset"
[ -z "$(git config "lfs.$endpoint.locksverify")" ]
git push origin master 2>&1 | tee push.log
grep "WARNING: Authentication error" push.log
refute_server_object "$reponame" "$contents_oid"
assert_server_object "$reponame" "$contents_oid"
[ -z "$(git config "lfs.$endpoint.locksverify")" ]
)
end_test