Skip to content

Commit

Permalink
commands: teach uploader how to find lockable files that aren't lfs o…
Browse files Browse the repository at this point in the history
…bjects
  • Loading branch information
technoweenie committed Feb 16, 2017
1 parent 08c5ae6 commit 9b8bed7
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 9 deletions.
39 changes: 31 additions & 8 deletions commands/uploader.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,20 +41,34 @@ type uploadContext struct {
trackedLocksMu *sync.Mutex

// ALL verifiable locks
ourLocks map[string]*locking.Lock
theirLocks map[string]*locking.Lock
ourLocks map[string]locking.Lock
theirLocks map[string]locking.Lock

// locks from ourLocks that were modified in this push
ownedLocks []*locking.Lock
ownedLocks []locking.Lock

// locks from theirLocks that were modified in this push
unownedLocks []*locking.Lock
unownedLocks []locking.Lock

// tracks errors from gitscanner callbacks
scannerErr error
errMu sync.Mutex
}

// Determines if a filename is lockable. Serves as a wrapper around theirLocks
// that implements GitScannerSet.
type gitScannerLockables struct {
m map[string]locking.Lock
}

func (l *gitScannerLockables) Contains(name string) bool {
if l == nil {
return false
}
_, ok := l.m[name]
return ok
}

func newUploadContext(remote string, dryRun bool) *uploadContext {
cfg.CurrentRemote = remote

Expand All @@ -63,8 +77,8 @@ func newUploadContext(remote string, dryRun bool) *uploadContext {
Manifest: getTransferManifest(),
DryRun: dryRun,
uploadedOids: tools.NewStringSet(),
ourLocks: make(map[string]*locking.Lock),
theirLocks: make(map[string]*locking.Lock),
ourLocks: make(map[string]locking.Lock),
theirLocks: make(map[string]locking.Lock),
trackedLocksMu: new(sync.Mutex),
}

Expand All @@ -79,10 +93,10 @@ func newUploadContext(remote string, dryRun bool) *uploadContext {
Error(" Temporarily skipping check ...")
} else {
for _, l := range theirLocks {
ctx.theirLocks[l.Path] = &l
ctx.theirLocks[l.Path] = l
}
for _, l := range ourLocks {
ctx.ourLocks[l.Path] = &l
ctx.ourLocks[l.Path] = l
}
}

Expand Down Expand Up @@ -116,6 +130,15 @@ func (c *uploadContext) buildGitScanner() (*lfs.GitScanner, error) {
}
})

gitscanner.FoundLockable = func(name string) {
if lock, ok := c.theirLocks[name]; ok {
c.trackedLocksMu.Lock()
c.unownedLocks = append(c.unownedLocks, lock)
c.trackedLocksMu.Unlock()
}
}

gitscanner.PotentialLockables = &gitScannerLockables{m: c.theirLocks}
return gitscanner, gitscanner.RemoteForPush(c.Remote)
}

Expand Down
52 changes: 51 additions & 1 deletion test/test-pre-push.sh
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ begin_test "pre-push with our lock"
)
end_test

begin_test "pre-push with their lock"
begin_test "pre-push with their lock on lfs file"
(
set -e

Expand Down Expand Up @@ -563,3 +563,53 @@ begin_test "pre-push with their lock"
popd >/dev/null
)
end_test

begin_test "pre-push with their lock on non-lfs lockable file"
(
set -e

reponame="pre_push_unowned_lock_not_lfs"
setup_remote_repo "$reponame"
clone_repo "$reponame" "$reponame"

echo "*.dat lockable" > .gitattributes
git add .gitattributes
git commit -m "initial commit"

# any lock path with "theirs" is returned as "their" lock by /locks/verify
echo "hi" > readme.txt
echo "tiny" > tiny_locked_theirs.dat
git help > large_locked_theirs.dat
git add readme.txt tiny_locked_theirs.dat large_locked_theirs.dat
git commit -m "add initial files"

git push origin master

git lfs lock "tiny_locked_theirs.dat" | tee lock.log
grep "'tiny_locked_theirs.dat' was locked" lock.log
id=$(grep -oh "\((.*)\)" lock.log | tr -d "()")
assert_server_lock $id

git lfs lock "large_locked_theirs.dat" | tee lock.log
grep "'large_locked_theirs.dat' was locked" lock.log
id=$(grep -oh "\((.*)\)" lock.log | tr -d "()")
assert_server_lock $id

pushd "$TRASHDIR" >/dev/null
clone_repo "$reponame" "$reponame-assert"

git lfs update # manually add pre-push hook, since lfs clean hook is not used
echo "other changes" >> readme.txt
echo "unauthorized changes" >> large_locked_theirs.dat
echo "unauthorized changes" >> tiny_locked_theirs.dat
# --no-verify is used to avoid the pre-commit hook which is not under test
git commit --no-verify -am "add unauthorized changes"

git push origin master 2>&1 | tee push.log

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
popd >/dev/null
)
end_test

0 comments on commit 9b8bed7

Please sign in to comment.