Merge branch 'nd/maint-clone-gitdir'
[git] / t / t7700-repack.sh
1 #!/bin/sh
2
3 test_description='git repack works correctly'
4
5 . ./test-lib.sh
6
7 test_expect_success 'objects in packs marked .keep are not repacked' '
8         echo content1 > file1 &&
9         echo content2 > file2 &&
10         git add . &&
11         test_tick &&
12         git commit -m initial_commit &&
13         # Create two packs
14         # The first pack will contain all of the objects except one
15         git rev-list --objects --all | grep -v file2 |
16                 git pack-objects pack > /dev/null &&
17         # The second pack will contain the excluded object
18         packsha1=$(git rev-list --objects --all | grep file2 |
19                 git pack-objects pack) &&
20         touch -r pack-$packsha1.pack pack-$packsha1.keep &&
21         objsha1=$(git verify-pack -v pack-$packsha1.idx | head -n 1 |
22                 sed -e "s/^\([0-9a-f]\{40\}\).*/\1/") &&
23         mv pack-* .git/objects/pack/ &&
24         git repack -A -d -l &&
25         git prune-packed &&
26         for p in .git/objects/pack/*.idx; do
27                 idx=$(basename $p)
28                 test "pack-$packsha1.idx" = "$idx" && continue
29                 if git verify-pack -v $p | egrep "^$objsha1"; then
30                         found_duplicate_object=1
31                         echo "DUPLICATE OBJECT FOUND"
32                         break
33                 fi
34         done &&
35         test -z "$found_duplicate_object"
36 '
37
38 test_expect_success 'loose objects in alternate ODB are not repacked' '
39         mkdir alt_objects &&
40         echo `pwd`/alt_objects > .git/objects/info/alternates &&
41         echo content3 > file3 &&
42         objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) &&
43         git add file3 &&
44         test_tick &&
45         git commit -m commit_file3 &&
46         git repack -a -d -l &&
47         git prune-packed &&
48         for p in .git/objects/pack/*.idx; do
49                 if git verify-pack -v $p | egrep "^$objsha1"; then
50                         found_duplicate_object=1
51                         echo "DUPLICATE OBJECT FOUND"
52                         break
53                 fi
54         done &&
55         test -z "$found_duplicate_object"
56 '
57
58 test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' '
59         mkdir alt_objects/pack &&
60         mv .git/objects/pack/* alt_objects/pack &&
61         git repack -a &&
62         myidx=$(ls -1 .git/objects/pack/*.idx) &&
63         test -f "$myidx" &&
64         for p in alt_objects/pack/*.idx; do
65                 git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
66         done | while read sha1 rest; do
67                 if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
68                         echo "Missing object in local pack: $sha1"
69                         return 1
70                 fi
71         done
72 '
73
74 test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' '
75         rm -f .git/objects/pack/* &&
76         echo new_content >> file1 &&
77         git add file1 &&
78         test_tick &&
79         git commit -m more_content &&
80         git repack &&
81         git repack -a -d &&
82         myidx=$(ls -1 .git/objects/pack/*.idx) &&
83         test -f "$myidx" &&
84         for p in alt_objects/pack/*.idx; do
85                 git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
86         done | while read sha1 rest; do
87                 if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
88                         echo "Missing object in local pack: $sha1"
89                         return 1
90                 fi
91         done
92 '
93
94 test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
95         # swap the .keep so the commit object is in the pack with .keep
96         for p in alt_objects/pack/*.pack
97         do
98                 base_name=$(basename $p .pack) &&
99                 if test -f alt_objects/pack/$base_name.keep
100                 then
101                         rm alt_objects/pack/$base_name.keep
102                 else
103                         touch alt_objects/pack/$base_name.keep
104                 fi
105         done &&
106         git repack -a -d &&
107         myidx=$(ls -1 .git/objects/pack/*.idx) &&
108         test -f "$myidx" &&
109         for p in alt_objects/pack/*.idx; do
110                 git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
111         done | while read sha1 rest; do
112                 if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
113                         echo "Missing object in local pack: $sha1"
114                         return 1
115                 fi
116         done
117 '
118
119 test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
120         rm -f alt_objects/pack/*.keep &&
121         mv .git/objects/pack/* alt_objects/pack/ &&
122         csha1=$(git rev-parse HEAD^{commit}) &&
123         git reset --hard HEAD^ &&
124         test_tick &&
125         git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
126         # The pack-objects call on the next line is equivalent to
127         # git repack -A -d without the call to prune-packed
128         git pack-objects --honor-pack-keep --non-empty --all --reflog \
129             --unpack-unreachable </dev/null pack &&
130         rm -f .git/objects/pack/* &&
131         mv pack-* .git/objects/pack/ &&
132         test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
133                 egrep "^$csha1 " | sort | uniq | wc -l) &&
134         echo > .git/objects/info/alternates &&
135         test_must_fail git show $csha1
136 '
137
138 test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' '
139         echo `pwd`/alt_objects > .git/objects/info/alternates &&
140         echo "$csha1" | git pack-objects --non-empty --all --reflog pack &&
141         rm -f .git/objects/pack/* &&
142         mv pack-* .git/objects/pack/ &&
143         # The pack-objects call on the next line is equivalent to
144         # git repack -A -d without the call to prune-packed
145         git pack-objects --honor-pack-keep --non-empty --all --reflog \
146             --unpack-unreachable </dev/null pack &&
147         rm -f .git/objects/pack/* &&
148         mv pack-* .git/objects/pack/ &&
149         test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
150                 egrep "^$csha1 " | sort | uniq | wc -l) &&
151         echo > .git/objects/info/alternates &&
152         test_must_fail git show $csha1
153 '
154
155 test_expect_success 'objects made unreachable by grafts only are kept' '
156         test_tick &&
157         git commit --allow-empty -m "commit 4" &&
158         H0=$(git rev-parse HEAD) &&
159         H1=$(git rev-parse HEAD^) &&
160         H2=$(git rev-parse HEAD^^) &&
161         echo "$H0 $H2" > .git/info/grafts &&
162         git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
163         git repack -a -d &&
164         git cat-file -t $H1
165         '
166
167 test_done
168