Sync with 'maint'
[alt-git.git] / t / t2030-unresolve-info.sh
blobb3f6bc97b53d87a4442739d4d62cccd923b55bcd
1 #!/bin/sh
3 test_description='undoing resolution'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
8 TEST_PASSES_SANITIZE_LEAK=true
9 . ./test-lib.sh
11 check_resolve_undo () {
12 msg=$1
13 shift
14 while case $# in
15 0) break ;;
16 1|2|3) die "Bug in check-resolve-undo test" ;;
17 esac
19 path=$1
20 shift
21 for stage in 1 2 3
23 sha1=$1
24 shift
25 case "$sha1" in
26 '') continue ;;
27 esac
28 sha1=$(git rev-parse --verify "$sha1")
29 printf "100644 %s %s\t%s\n" $sha1 $stage $path
30 done
31 done >"$msg.expect" &&
32 git ls-files --resolve-undo >"$msg.actual" &&
33 test_cmp "$msg.expect" "$msg.actual"
36 prime_resolve_undo () {
37 git reset --hard &&
38 git checkout second^0 &&
39 test_tick &&
40 test_must_fail git merge third^0 &&
41 check_resolve_undo empty &&
43 # how should the conflict be resolved?
44 case "$1" in
45 remove)
46 rm -f file/le && git rm fi/le
48 *) # modify
49 echo different >fi/le && git add fi/le
51 esac
52 check_resolve_undo recorded fi/le initial:fi/le second:fi/le third:fi/le
55 test_expect_success setup '
56 mkdir fi &&
57 printf "a\0a" >binary &&
58 git add binary &&
59 test_commit initial fi/le first &&
60 git branch side &&
61 git branch another &&
62 printf "a\0b" >binary &&
63 git add binary &&
64 test_commit second fi/le second &&
65 git checkout side &&
66 test_commit third fi/le third &&
67 git branch add-add &&
68 git checkout another &&
69 test_commit fourth fi/le fourth &&
70 git checkout add-add &&
71 test_commit fifth add-differently &&
72 git checkout main
75 test_expect_success 'add records switch clears' '
76 prime_resolve_undo &&
77 test_tick &&
78 git commit -m merged &&
79 echo committing keeps &&
80 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
81 git checkout second^0 &&
82 echo switching clears &&
83 check_resolve_undo cleared
86 test_expect_success 'rm records reset clears' '
87 prime_resolve_undo &&
88 test_tick &&
89 git commit -m merged &&
90 echo committing keeps &&
91 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
93 echo merge clears upfront &&
94 test_must_fail git merge fourth^0 &&
95 check_resolve_undo nuked &&
97 git rm -f fi/le &&
98 echo resolving records &&
99 check_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le &&
101 git reset --hard &&
102 echo resetting discards &&
103 check_resolve_undo discarded
106 test_expect_success 'plumbing clears' '
107 prime_resolve_undo &&
108 test_tick &&
109 git commit -m merged &&
110 echo committing keeps &&
111 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
113 echo plumbing clear &&
114 git update-index --clear-resolve-undo &&
115 check_resolve_undo cleared
118 test_expect_success 'add records checkout -m undoes' '
119 prime_resolve_undo &&
120 git diff HEAD &&
121 git checkout --conflict=merge fi/le &&
122 echo checkout used the record and removed it &&
123 check_resolve_undo removed &&
124 echo the index and the work tree is unmerged again &&
125 git diff >actual &&
126 grep "^++<<<<<<<" actual
129 test_expect_success 'unmerge with plumbing' '
130 prime_resolve_undo &&
131 git update-index --unresolve fi/le &&
132 git ls-files --resolve-undo fi/le >actual &&
133 test_must_be_empty actual &&
134 git ls-files -u >actual &&
135 test_line_count = 3 actual
138 test_expect_success 'unmerge can be done even after committing' '
139 prime_resolve_undo &&
140 git commit -m "record to nuke MERGE_HEAD" &&
141 git update-index --unresolve fi/le &&
142 git ls-files --resolve-undo fi/le >actual &&
143 test_must_be_empty actual &&
144 git ls-files -u >actual &&
145 test_line_count = 3 actual
148 test_expect_success 'unmerge removal' '
149 prime_resolve_undo remove &&
150 git update-index --unresolve fi/le &&
151 git ls-files --resolve-undo fi/le >actual &&
152 test_must_be_empty actual &&
153 git ls-files -u >actual &&
154 test_line_count = 3 actual
157 test_expect_success 'unmerge removal after committing' '
158 prime_resolve_undo remove &&
159 git commit -m "record to nuke MERGE_HEAD" &&
160 git update-index --unresolve fi/le &&
161 git ls-files --resolve-undo fi/le >actual &&
162 test_must_be_empty actual &&
163 git ls-files -u >actual &&
164 test_line_count = 3 actual
167 test_expect_success 'rerere and rerere forget' '
168 mkdir .git/rr-cache &&
169 prime_resolve_undo &&
170 echo record the resolution &&
171 git rerere &&
172 rerere_id=$(cd .git/rr-cache && echo */postimage) &&
173 rerere_id=${rerere_id%/postimage} &&
174 test -f .git/rr-cache/$rerere_id/postimage &&
175 git checkout -m fi/le &&
176 echo resurrect the conflict &&
177 grep "^=======" fi/le &&
178 echo reresolve the conflict &&
179 git rerere &&
180 test "z$(cat fi/le)" = zdifferent &&
181 echo register the resolution again &&
182 git add fi/le &&
183 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
184 test -z "$(git ls-files -u)" &&
185 git rerere forget fi/le &&
186 ! test -f .git/rr-cache/$rerere_id/postimage &&
187 tr "\0" "\n" <.git/MERGE_RR >actual &&
188 echo "$rerere_id fi/le" >expect &&
189 test_cmp expect actual
192 test_expect_success 'rerere and rerere forget (subdirectory)' '
193 rm -fr .git/rr-cache &&
194 mkdir .git/rr-cache &&
195 prime_resolve_undo &&
196 echo record the resolution &&
197 (cd fi && git rerere) &&
198 rerere_id=$(cd .git/rr-cache && echo */postimage) &&
199 rerere_id=${rerere_id%/postimage} &&
200 test -f .git/rr-cache/$rerere_id/postimage &&
201 (cd fi && git checkout -m le) &&
202 echo resurrect the conflict &&
203 grep "^=======" fi/le &&
204 echo reresolve the conflict &&
205 (cd fi && git rerere) &&
206 test "z$(cat fi/le)" = zdifferent &&
207 echo register the resolution again &&
208 (cd fi && git add le) &&
209 check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
210 test -z "$(git ls-files -u)" &&
211 (cd fi && git rerere forget le) &&
212 ! test -f .git/rr-cache/$rerere_id/postimage &&
213 tr "\0" "\n" <.git/MERGE_RR >actual &&
214 echo "$rerere_id fi/le" >expect &&
215 test_cmp expect actual
218 test_expect_success 'rerere forget (binary)' '
219 git checkout -f side &&
220 test_commit --printf binary binary "a\0c" &&
221 test_must_fail git merge second &&
222 git rerere forget binary
225 test_expect_success 'rerere forget (add-add conflict)' '
226 git checkout -f main &&
227 echo main >add-differently &&
228 git add add-differently &&
229 git commit -m "add differently" &&
230 test_must_fail git merge fifth &&
231 git rerere forget add-differently 2>actual &&
232 test_grep "no remembered" actual
235 test_expect_success 'resolve-undo keeps blobs from gc' '
236 git checkout -f main &&
238 # First make sure we do not have any cruft left in the object store
239 git repack -a -d &&
240 git prune --expire=now &&
241 git prune-packed &&
242 git gc --prune=now &&
243 git fsck --unreachable >cruft &&
244 test_must_be_empty cruft &&
246 # Now add three otherwise unreferenced blob objects to the index
247 git reset --hard &&
248 B1=$(echo "resolve undo test data 1" | git hash-object -w --stdin) &&
249 B2=$(echo "resolve undo test data 2" | git hash-object -w --stdin) &&
250 B3=$(echo "resolve undo test data 3" | git hash-object -w --stdin) &&
251 git update-index --add --index-info <<-EOF &&
252 100644 $B1 1 frotz
253 100644 $B2 2 frotz
254 100644 $B3 3 frotz
257 # These three blob objects are reachable (only) from the index
258 git fsck --unreachable >cruft &&
259 test_must_be_empty cruft &&
260 # and they should be protected from GC
261 git gc --prune=now &&
262 git cat-file -e $B1 &&
263 git cat-file -e $B2 &&
264 git cat-file -e $B3 &&
266 # Now resolve the conflicted path
267 B0=$(echo "resolve undo test data 0" | git hash-object -w --stdin) &&
268 git update-index --add --cacheinfo 100644,$B0,frotz &&
270 # These three blob objects are now reachable only from the resolve-undo
271 git fsck --unreachable >cruft &&
272 test_must_be_empty cruft &&
274 # and they should survive GC
275 git gc --prune=now &&
276 git cat-file -e $B0 &&
277 git cat-file -e $B1 &&
278 git cat-file -e $B2 &&
279 git cat-file -e $B3 &&
281 # Now we switch away, which nukes resolve-undo, and
282 # blobs B0..B3 would become dangling. fsck should
283 # notice that they are now unreachable.
284 git checkout -f side &&
285 git fsck --unreachable >cruft &&
286 sort cruft >actual &&
287 sort <<-EOF >expect &&
288 unreachable blob $B0
289 unreachable blob $B1
290 unreachable blob $B2
291 unreachable blob $B3
293 test_cmp expect actual &&
295 # And they should go away when gc runs.
296 git gc --prune=now &&
297 git fsck --unreachable >cruft &&
298 test_must_be_empty cruft &&
300 test_must_fail git cat-file -e $B0 &&
301 test_must_fail git cat-file -e $B1 &&
302 test_must_fail git cat-file -e $B2 &&
303 test_must_fail git cat-file -e $B3
306 test_done