3 test_description
='undoing resolution'
5 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
=main
6 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10 check_resolve_undo
() {
15 1|
2|
3) die
"Bug in check-resolve-undo test" ;;
27 sha1
=$
(git rev-parse
--verify "$sha1")
28 printf "100644 %s %s\t%s\n" $sha1 $stage $path
30 done >"$msg.expect" &&
31 git ls-files
--resolve-undo >"$msg.actual" &&
32 test_cmp
"$msg.expect" "$msg.actual"
35 prime_resolve_undo
() {
37 git checkout second^
0 &&
39 test_must_fail git merge third^
0 &&
40 check_resolve_undo empty
&&
42 # how should the conflict be resolved?
45 rm -f file
/le
&& git
rm fi
/le
48 echo different
>fi
/le
&& git add fi
/le
51 check_resolve_undo recorded fi
/le initial
:fi
/le second
:fi
/le third
:fi
/le
54 test_expect_success setup
'
56 printf "a\0a" >binary &&
58 test_commit initial fi/le first &&
61 printf "a\0b" >binary &&
63 test_commit second fi/le second &&
65 test_commit third fi/le third &&
67 git checkout another &&
68 test_commit fourth fi/le fourth &&
69 git checkout add-add &&
70 test_commit fifth add-differently &&
74 test_expect_success
'add records switch clears' '
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' '
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 &&
97 echo resolving records &&
98 check_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le &&
101 echo resetting discards &&
102 check_resolve_undo discarded
105 test_expect_success
'plumbing clears' '
106 prime_resolve_undo &&
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 &&
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 &&
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 &&
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 &&
179 test "z$(cat fi/le)" = zdifferent &&
180 echo register the resolution again &&
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
239 git prune --expire=now &&
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
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 &&
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 &&
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