1#!/bin/sh
2
3test_description='undoing resolution'
4
5GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
6export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
7
8. ./test-lib.sh
9
10check_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
35prime_resolve_undo () {
36	git reset --hard &&
37	git checkout second^0 &&
38	test_tick &&
39	test_must_fail git merge third^0 &&
40	echo merge does not leave anything &&
41	check_resolve_undo empty &&
42	echo different >fi/le &&
43	git add fi/le &&
44	echo resolving records &&
45	check_resolve_undo recorded fi/le initial:fi/le second:fi/le third:fi/le
46}
47
48test_expect_success setup '
49	mkdir fi &&
50	printf "a\0a" >binary &&
51	git add binary &&
52	test_commit initial fi/le first &&
53	git branch side &&
54	git branch another &&
55	printf "a\0b" >binary &&
56	git add binary &&
57	test_commit second fi/le second &&
58	git checkout side &&
59	test_commit third fi/le third &&
60	git branch add-add &&
61	git checkout another &&
62	test_commit fourth fi/le fourth &&
63	git checkout add-add &&
64	test_commit fifth add-differently &&
65	git checkout main
66'
67
68test_expect_success 'add records switch clears' '
69	prime_resolve_undo &&
70	test_tick &&
71	git commit -m merged &&
72	echo committing keeps &&
73	check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
74	git checkout second^0 &&
75	echo switching clears &&
76	check_resolve_undo cleared
77'
78
79test_expect_success 'rm records reset clears' '
80	prime_resolve_undo &&
81	test_tick &&
82	git commit -m merged &&
83	echo committing keeps &&
84	check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
85
86	echo merge clears upfront &&
87	test_must_fail git merge fourth^0 &&
88	check_resolve_undo nuked &&
89
90	git rm -f fi/le &&
91	echo resolving records &&
92	check_resolve_undo recorded fi/le initial:fi/le HEAD:fi/le fourth:fi/le &&
93
94	git reset --hard &&
95	echo resetting discards &&
96	check_resolve_undo discarded
97'
98
99test_expect_success 'plumbing clears' '
100	prime_resolve_undo &&
101	test_tick &&
102	git commit -m merged &&
103	echo committing keeps &&
104	check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
105
106	echo plumbing clear &&
107	git update-index --clear-resolve-undo &&
108	check_resolve_undo cleared
109'
110
111test_expect_success 'add records checkout -m undoes' '
112	prime_resolve_undo &&
113	git diff HEAD &&
114	git checkout --conflict=merge fi/le &&
115	echo checkout used the record and removed it &&
116	check_resolve_undo removed &&
117	echo the index and the work tree is unmerged again &&
118	git diff >actual &&
119	grep "^++<<<<<<<" actual
120'
121
122test_expect_success 'unmerge with plumbing' '
123	prime_resolve_undo &&
124	git update-index --unresolve fi/le &&
125	git ls-files -u >actual &&
126	test_line_count = 3 actual
127'
128
129test_expect_success 'rerere and rerere forget' '
130	mkdir .git/rr-cache &&
131	prime_resolve_undo &&
132	echo record the resolution &&
133	git rerere &&
134	rerere_id=$(cd .git/rr-cache && echo */postimage) &&
135	rerere_id=${rerere_id%/postimage} &&
136	test -f .git/rr-cache/$rerere_id/postimage &&
137	git checkout -m fi/le &&
138	echo resurrect the conflict &&
139	grep "^=======" fi/le &&
140	echo reresolve the conflict &&
141	git rerere &&
142	test "z$(cat fi/le)" = zdifferent &&
143	echo register the resolution again &&
144	git add fi/le &&
145	check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
146	test -z "$(git ls-files -u)" &&
147	git rerere forget fi/le &&
148	! test -f .git/rr-cache/$rerere_id/postimage &&
149	tr "\0" "\n" <.git/MERGE_RR >actual &&
150	echo "$rerere_id	fi/le" >expect &&
151	test_cmp expect actual
152'
153
154test_expect_success 'rerere and rerere forget (subdirectory)' '
155	rm -fr .git/rr-cache &&
156	mkdir .git/rr-cache &&
157	prime_resolve_undo &&
158	echo record the resolution &&
159	(cd fi && git rerere) &&
160	rerere_id=$(cd .git/rr-cache && echo */postimage) &&
161	rerere_id=${rerere_id%/postimage} &&
162	test -f .git/rr-cache/$rerere_id/postimage &&
163	(cd fi && git checkout -m le) &&
164	echo resurrect the conflict &&
165	grep "^=======" fi/le &&
166	echo reresolve the conflict &&
167	(cd fi && git rerere) &&
168	test "z$(cat fi/le)" = zdifferent &&
169	echo register the resolution again &&
170	(cd fi && git add le) &&
171	check_resolve_undo kept fi/le initial:fi/le second:fi/le third:fi/le &&
172	test -z "$(git ls-files -u)" &&
173	(cd fi && git rerere forget le) &&
174	! test -f .git/rr-cache/$rerere_id/postimage &&
175	tr "\0" "\n" <.git/MERGE_RR >actual &&
176	echo "$rerere_id	fi/le" >expect &&
177	test_cmp expect actual
178'
179
180test_expect_success 'rerere forget (binary)' '
181	git checkout -f side &&
182	test_commit --printf binary binary "a\0c" &&
183	test_must_fail git merge second &&
184	git rerere forget binary
185'
186
187test_expect_success 'rerere forget (add-add conflict)' '
188	git checkout -f main &&
189	echo main >add-differently &&
190	git add add-differently &&
191	git commit -m "add differently" &&
192	test_must_fail git merge fifth &&
193	git rerere forget add-differently 2>actual &&
194	test_i18ngrep "no remembered" actual
195'
196
197test_done
198