]>
Commit | Line | Data |
---|---|---|
9d9a2f4a JH |
1 | #!/bin/sh |
2 | ||
3 | test_description='undoing resolution' | |
4 | ||
883b98ef | 5 | GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main |
334afbc7 JS |
6 | export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME |
7 | ||
9d9a2f4a JH |
8 | . ./test-lib.sh |
9 | ||
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 | |
17 | do | |
18 | path=$1 | |
19 | shift | |
20 | for stage in 1 2 3 | |
21 | do | |
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" | |
33 | } | |
34 | ||
35 | prime_resolve_undo () { | |
36 | git reset --hard && | |
37 | git checkout second^0 && | |
38 | test_tick && | |
39 | test_must_fail git merge third^0 && | |
9d9a2f4a | 40 | check_resolve_undo empty && |
35901f1c JH |
41 | |
42 | # how should the conflict be resolved? | |
43 | case "$1" in | |
44 | remove) | |
45 | rm -f file/le && git rm fi/le | |
46 | ;; | |
47 | *) # modify | |
48 | echo different >fi/le && git add fi/le | |
49 | ;; | |
50 | esac | |
5a9f0395 | 51 | check_resolve_undo recorded fi/le initial:fi/le second:fi/le third:fi/le |
9d9a2f4a JH |
52 | } |
53 | ||
54 | test_expect_success setup ' | |
5a9f0395 | 55 | mkdir fi && |
53d8afaf JS |
56 | printf "a\0a" >binary && |
57 | git add binary && | |
5a9f0395 | 58 | test_commit initial fi/le first && |
9d9a2f4a JH |
59 | git branch side && |
60 | git branch another && | |
53d8afaf JS |
61 | printf "a\0b" >binary && |
62 | git add binary && | |
5a9f0395 | 63 | test_commit second fi/le second && |
9d9a2f4a | 64 | git checkout side && |
5a9f0395 | 65 | test_commit third fi/le third && |
b9e31f59 | 66 | git branch add-add && |
9d9a2f4a | 67 | git checkout another && |
5a9f0395 | 68 | test_commit fourth fi/le fourth && |
b9e31f59 JS |
69 | git checkout add-add && |
70 | test_commit fifth add-differently && | |
883b98ef | 71 | git checkout main |
9d9a2f4a JH |
72 | ' |
73 | ||
74 | test_expect_success 'add records switch clears' ' | |
75 | prime_resolve_undo && | |
76 | test_tick && | |
77 | git commit -m merged && | |
78 | echo committing keeps && | |
5a9f0395 | 79 | check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && |
9d9a2f4a JH |
80 | git checkout second^0 && |
81 | echo switching clears && | |
82 | check_resolve_undo cleared | |
83 | ' | |
84 | ||
85 | test_expect_success 'rm records reset clears' ' | |
86 | prime_resolve_undo && | |
87 | test_tick && | |
88 | git commit -m merged && | |
89 | echo committing keeps && | |
5a9f0395 | 90 | check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && |
9d9a2f4a JH |
91 | |
92 | echo merge clears upfront && | |
93 | test_must_fail git merge fourth^0 && | |
94 | check_resolve_undo nuked && | |
95 | ||
5a9f0395 | 96 | git rm -f fi/le && |
9d9a2f4a | 97 | echo resolving records && |
5a9f0395 | 98 | check_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le && |
9d9a2f4a JH |
99 | |
100 | git reset --hard && | |
101 | echo resetting discards && | |
102 | check_resolve_undo discarded | |
103 | ' | |
104 | ||
4a39f79d JH |
105 | test_expect_success 'plumbing clears' ' |
106 | prime_resolve_undo && | |
107 | test_tick && | |
108 | git commit -m merged && | |
109 | echo committing keeps && | |
5a9f0395 | 110 | check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && |
4a39f79d JH |
111 | |
112 | echo plumbing clear && | |
113 | git update-index --clear-resolve-undo && | |
114 | check_resolve_undo cleared | |
115 | ' | |
116 | ||
4421a823 JH |
117 | test_expect_success 'add records checkout -m undoes' ' |
118 | prime_resolve_undo && | |
119 | git diff HEAD && | |
5a9f0395 | 120 | git checkout --conflict=merge fi/le && |
4421a823 JH |
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 | |
126 | ' | |
127 | ||
8aa38563 JH |
128 | test_expect_success 'unmerge with plumbing' ' |
129 | prime_resolve_undo && | |
5a9f0395 | 130 | git update-index --unresolve fi/le && |
35901f1c JH |
131 | git ls-files --resolve-undo fi/le >actual && |
132 | test_must_be_empty actual && | |
8aa38563 | 133 | git ls-files -u >actual && |
3fb0459b | 134 | test_line_count = 3 actual |
8aa38563 JH |
135 | ' |
136 | ||
91e07058 JH |
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 && | |
35901f1c JH |
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 | |
145 | ' | |
146 | ||
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 | |
154 | ' | |
155 | ||
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 && | |
91e07058 JH |
162 | git ls-files -u >actual && |
163 | test_line_count = 3 actual | |
164 | ' | |
165 | ||
5a9f0395 | 166 | test_expect_success 'rerere and rerere forget' ' |
dea4562b JH |
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 && | |
5a9f0395 | 174 | git checkout -m fi/le && |
dea4562b | 175 | echo resurrect the conflict && |
5a9f0395 | 176 | grep "^=======" fi/le && |
dea4562b JH |
177 | echo reresolve the conflict && |
178 | git rerere && | |
5a9f0395 | 179 | test "z$(cat fi/le)" = zdifferent && |
dea4562b | 180 | echo register the resolution again && |
5a9f0395 JS |
181 | git add fi/le && |
182 | check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le && | |
dea4562b | 183 | test -z "$(git ls-files -u)" && |
5a9f0395 | 184 | git rerere forget fi/le && |
dea4562b JH |
185 | ! test -f .git/rr-cache/$rerere_id/postimage && |
186 | tr "\0" "\n" <.git/MERGE_RR >actual && | |
5a9f0395 JS |
187 | echo "$rerere_id fi/le" >expect && |
188 | test_cmp expect actual | |
189 | ' | |
190 | ||
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 && | |
dea4562b JH |
214 | test_cmp expect actual |
215 | ' | |
216 | ||
53d8afaf JS |
217 | test_expect_success 'rerere forget (binary)' ' |
218 | git checkout -f side && | |
47c88d16 | 219 | test_commit --printf binary binary "a\0c" && |
53d8afaf JS |
220 | test_must_fail git merge second && |
221 | git rerere forget binary | |
222 | ' | |
223 | ||
b9e31f59 | 224 | test_expect_success 'rerere forget (add-add conflict)' ' |
883b98ef JS |
225 | git checkout -f main && |
226 | echo main >add-differently && | |
b9e31f59 JS |
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 && | |
6789275d | 231 | test_grep "no remembered" actual |
b9e31f59 JS |
232 | ' |
233 | ||
5a5ea141 JH |
234 | test_expect_success 'resolve-undo keeps blobs from gc' ' |
235 | git checkout -f main && | |
236 | ||
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 && | |
244 | ||
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 | |
254 | EOF | |
255 | ||
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 && | |
264 | ||
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 && | |
268 | ||
269 | # These three blob objects are now reachable only from the resolve-undo | |
270 | git fsck --unreachable >cruft && | |
271 | test_must_be_empty cruft && | |
272 | ||
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 && | |
279 | ||
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 | |
291 | EOF | |
292 | test_cmp expect actual && | |
293 | ||
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 && | |
298 | ||
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 | |
303 | ' | |
304 | ||
9d9a2f4a | 305 | test_done |