-
Notifications
You must be signed in to change notification settings - Fork 25.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
receive-pack: quarantine objects until pre-receive accepts
When a client pushes objects to us, index-pack checks the objects themselves and then installs them into place. If we then reject the push due to a pre-receive hook, we cannot just delete the packfile; other processes may be depending on it. We have to do a normal reachability check at this point via `git gc`. But such objects may hang around for weeks due to the gc.pruneExpire grace period. And worse, during that time they may be exploded from the pack into inefficient loose objects. Instead, this patch teaches receive-pack to put the new objects into a "quarantine" temporary directory. We make these objects available to the connectivity check and to the pre-receive hook, and then install them into place only if it is successful (and otherwise remove them as tempfiles). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
Showing
2 changed files
with
76 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#!/bin/sh | ||
|
||
test_description='check quarantine of objects during push' | ||
. ./test-lib.sh | ||
|
||
test_expect_success 'create picky dest repo' ' | ||
git init --bare dest.git && | ||
write_script dest.git/hooks/pre-receive <<-\EOF | ||
while read old new ref; do | ||
test "$(git log -1 --format=%s $new)" = reject && exit 1 | ||
done | ||
exit 0 | ||
EOF | ||
' | ||
|
||
test_expect_success 'accepted objects work' ' | ||
test_commit ok && | ||
git push dest.git HEAD && | ||
commit=$(git rev-parse HEAD) && | ||
git --git-dir=dest.git cat-file commit $commit | ||
' | ||
|
||
test_expect_success 'rejected objects are not installed' ' | ||
test_commit reject && | ||
commit=$(git rev-parse HEAD) && | ||
test_must_fail git push dest.git reject && | ||
test_must_fail git --git-dir=dest.git cat-file commit $commit | ||
' | ||
|
||
test_expect_success 'rejected objects are removed' ' | ||
echo "incoming-*" >expect && | ||
(cd dest.git/objects && echo incoming-*) >actual && | ||
test_cmp expect actual | ||
' | ||
|
||
test_done |