Merge branch 'kb/perf-trace'
[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         >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 'writing bitmaps via command-line can duplicate .keep objects' '
39         # build on $objsha1, $packsha1, and .keep state from previous
40         git repack -Adbl &&
41         test_when_finished "found_duplicate_object=" &&
42         for p in .git/objects/pack/*.idx; do
43                 idx=$(basename $p)
44                 test "pack-$packsha1.idx" = "$idx" && continue
45                 if git verify-pack -v $p | egrep "^$objsha1"; then
46                         found_duplicate_object=1
47                         echo "DUPLICATE OBJECT FOUND"
48                         break
49                 fi
50         done &&
51         test "$found_duplicate_object" = 1
52 '
53
54 test_expect_success 'writing bitmaps via config can duplicate .keep objects' '
55         # build on $objsha1, $packsha1, and .keep state from previous
56         git -c repack.writebitmaps=true repack -Adl &&
57         test_when_finished "found_duplicate_object=" &&
58         for p in .git/objects/pack/*.idx; do
59                 idx=$(basename $p)
60                 test "pack-$packsha1.idx" = "$idx" && continue
61                 if git verify-pack -v $p | egrep "^$objsha1"; then
62                         found_duplicate_object=1
63                         echo "DUPLICATE OBJECT FOUND"
64                         break
65                 fi
66         done &&
67         test "$found_duplicate_object" = 1
68 '
69
70 test_expect_success 'loose objects in alternate ODB are not repacked' '
71         mkdir alt_objects &&
72         echo `pwd`/alt_objects > .git/objects/info/alternates &&
73         echo content3 > file3 &&
74         objsha1=$(GIT_OBJECT_DIRECTORY=alt_objects git hash-object -w file3) &&
75         git add file3 &&
76         test_tick &&
77         git commit -m commit_file3 &&
78         git repack -a -d -l &&
79         git prune-packed &&
80         for p in .git/objects/pack/*.idx; do
81                 if git verify-pack -v $p | egrep "^$objsha1"; then
82                         found_duplicate_object=1
83                         echo "DUPLICATE OBJECT FOUND"
84                         break
85                 fi
86         done &&
87         test -z "$found_duplicate_object"
88 '
89
90 test_expect_success 'packed obs in alt ODB are repacked even when local repo is packless' '
91         mkdir alt_objects/pack &&
92         mv .git/objects/pack/* alt_objects/pack &&
93         git repack -a &&
94         myidx=$(ls -1 .git/objects/pack/*.idx) &&
95         test -f "$myidx" &&
96         for p in alt_objects/pack/*.idx; do
97                 git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
98         done | while read sha1 rest; do
99                 if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
100                         echo "Missing object in local pack: $sha1"
101                         return 1
102                 fi
103         done
104 '
105
106 test_expect_success 'packed obs in alt ODB are repacked when local repo has packs' '
107         rm -f .git/objects/pack/* &&
108         echo new_content >> file1 &&
109         git add file1 &&
110         test_tick &&
111         git commit -m more_content &&
112         git repack &&
113         git repack -a -d &&
114         myidx=$(ls -1 .git/objects/pack/*.idx) &&
115         test -f "$myidx" &&
116         for p in alt_objects/pack/*.idx; do
117                 git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
118         done | while read sha1 rest; do
119                 if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
120                         echo "Missing object in local pack: $sha1"
121                         return 1
122                 fi
123         done
124 '
125
126 test_expect_success 'packed obs in alternate ODB kept pack are repacked' '
127         # swap the .keep so the commit object is in the pack with .keep
128         for p in alt_objects/pack/*.pack
129         do
130                 base_name=$(basename $p .pack) &&
131                 if test -f alt_objects/pack/$base_name.keep
132                 then
133                         rm alt_objects/pack/$base_name.keep
134                 else
135                         touch alt_objects/pack/$base_name.keep
136                 fi
137         done &&
138         git repack -a -d &&
139         myidx=$(ls -1 .git/objects/pack/*.idx) &&
140         test -f "$myidx" &&
141         for p in alt_objects/pack/*.idx; do
142                 git verify-pack -v $p | sed -n -e "/^[0-9a-f]\{40\}/p"
143         done | while read sha1 rest; do
144                 if ! ( git verify-pack -v $myidx | grep "^$sha1" ); then
145                         echo "Missing object in local pack: $sha1"
146                         return 1
147                 fi
148         done
149 '
150
151 test_expect_success 'packed unreachable obs in alternate ODB are not loosened' '
152         rm -f alt_objects/pack/*.keep &&
153         mv .git/objects/pack/* alt_objects/pack/ &&
154         csha1=$(git rev-parse HEAD^{commit}) &&
155         git reset --hard HEAD^ &&
156         test_tick &&
157         git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
158         # The pack-objects call on the next line is equivalent to
159         # git repack -A -d without the call to prune-packed
160         git pack-objects --honor-pack-keep --non-empty --all --reflog \
161             --unpack-unreachable </dev/null pack &&
162         rm -f .git/objects/pack/* &&
163         mv pack-* .git/objects/pack/ &&
164         test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
165                 egrep "^$csha1 " | sort | uniq | wc -l) &&
166         echo > .git/objects/info/alternates &&
167         test_must_fail git show $csha1
168 '
169
170 test_expect_success 'local packed unreachable obs that exist in alternate ODB are not loosened' '
171         echo `pwd`/alt_objects > .git/objects/info/alternates &&
172         echo "$csha1" | git pack-objects --non-empty --all --reflog pack &&
173         rm -f .git/objects/pack/* &&
174         mv pack-* .git/objects/pack/ &&
175         # The pack-objects call on the next line is equivalent to
176         # git repack -A -d without the call to prune-packed
177         git pack-objects --honor-pack-keep --non-empty --all --reflog \
178             --unpack-unreachable </dev/null pack &&
179         rm -f .git/objects/pack/* &&
180         mv pack-* .git/objects/pack/ &&
181         test 0 = $(git verify-pack -v -- .git/objects/pack/*.idx |
182                 egrep "^$csha1 " | sort | uniq | wc -l) &&
183         echo > .git/objects/info/alternates &&
184         test_must_fail git show $csha1
185 '
186
187 test_expect_success 'objects made unreachable by grafts only are kept' '
188         test_tick &&
189         git commit --allow-empty -m "commit 4" &&
190         H0=$(git rev-parse HEAD) &&
191         H1=$(git rev-parse HEAD^) &&
192         H2=$(git rev-parse HEAD^^) &&
193         echo "$H0 $H2" > .git/info/grafts &&
194         git reflog expire --expire=$test_tick --expire-unreachable=$test_tick --all &&
195         git repack -a -d &&
196         git cat-file -t $H1
197         '
198
199 test_done
200