Skip to content

Commit ccc1297

Browse files
drafnelgitster
authored andcommitted
repack: modify behavior of -A option to leave unreferenced objects unpacked
The previous behavior of the -A option was to retain any previously packed objects which had become unreferenced, and place them into the newly created pack file. Since git-gc, when run automatically with the --auto option, calls repack with the -A option, this had the effect of retaining unreferenced packed objects indefinitely. To avoid this scenario, the user was required to run git-gc with the little known --prune option or to manually run repack with the -a option. This patch changes the behavior of the -A option so that unreferenced objects that exist in any pack file being replaced, will be unpacked into the repository. The unreferenced loose objects can then be garbage collected by git-gc (i.e. git-prune) based on the gc.pruneExpire setting. Also add new tests for checking whether unreferenced objects which were previously packed are properly left in the repository unpacked after repacking. Signed-off-by: Brandon Casey <drafnel@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 1f8115b commit ccc1297

File tree

2 files changed

+60
-5
lines changed

2 files changed

+60
-5
lines changed

git-repack.sh

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ do
3030
-n) no_update_info=t ;;
3131
-a) all_into_one=t ;;
3232
-A) all_into_one=t
33-
keep_unreachable=--keep-unreachable ;;
33+
keep_unreachable=t ;;
3434
-d) remove_redundant=t ;;
3535
-q) quiet=-q ;;
3636
-f) no_reuse=--no-reuse-object ;;
@@ -78,9 +78,6 @@ case ",$all_into_one," in
7878
if test -z "$args"
7979
then
8080
args='--unpacked --incremental'
81-
elif test -n "$keep_unreachable"
82-
then
83-
args="$args $keep_unreachable"
8481
fi
8582
;;
8683
esac
@@ -130,7 +127,18 @@ then
130127
do
131128
case " $fullbases " in
132129
*" $e "*) ;;
133-
*) rm -f "$e.pack" "$e.idx" "$e.keep" ;;
130+
*)
131+
rm -f "$e.idx" "$e.keep"
132+
if test -n "$keep_unreachable" &&
133+
test -f "$e.pack"
134+
then
135+
git unpack-objects < "$e.pack" || {
136+
echo >&2 "Failed unpacking unreachable objects from redundant pack file $e.pack"
137+
exit 1
138+
}
139+
fi
140+
rm -f "$e.pack"
141+
;;
134142
esac
135143
done
136144
)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/sh
2+
3+
test_description='git-repack works correctly'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success '-A option leaves unreachable objects unpacked' '
8+
echo content > file1 &&
9+
git add . &&
10+
git commit -m initial_commit &&
11+
# create a transient branch with unique content
12+
git checkout -b transient_branch &&
13+
echo more content >> file1 &&
14+
# record the objects created in the database for file, commit, tree
15+
fsha1=$(git hash-object file1) &&
16+
git commit -a -m more_content &&
17+
csha1=$(git rev-parse HEAD^{commit}) &&
18+
tsha1=$(git rev-parse HEAD^{tree}) &&
19+
git checkout master &&
20+
echo even more content >> file1 &&
21+
git commit -a -m even_more_content &&
22+
# delete the transient branch
23+
git branch -D transient_branch &&
24+
# pack the repo
25+
git repack -A -d -l &&
26+
# verify objects are packed in repository
27+
test 3 = $(git verify-pack -v -- .git/objects/pack/*.idx |
28+
grep -e "^$fsha1 " -e "^$csha1 " -e "^$tsha1 " |
29+
sort | uniq | wc -l) &&
30+
git show $fsha1 &&
31+
git show $csha1 &&
32+
git show $tsha1 &&
33+
# now expire the reflog
34+
sleep 1 &&
35+
git reflog expire --expire-unreachable=now --all &&
36+
# and repack
37+
git repack -A -d -l &&
38+
# verify objects are retained unpacked
39+
test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
40+
grep -e "^$fsha1 " -e "^$csha1 " -e "^$tsha1 " |
41+
sort | uniq | wc -l) &&
42+
git show $fsha1 &&
43+
git show $csha1 &&
44+
git show $tsha1
45+
'
46+
47+
test_done

0 commit comments

Comments
 (0)