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