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