]> git.ipfire.org Git - thirdparty/git.git/blob - t/t6406-merge-attr.sh
use xstrncmpz()
[thirdparty/git.git] / t / t6406-merge-attr.sh
1 #!/bin/sh
2 #
3 # Copyright (c) 2007 Junio C Hamano
4 #
5
6 test_description='per path merge controlled by merge attribute'
7
8 GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
9 export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
10
11 TEST_PASSES_SANITIZE_LEAK=true
12 . ./test-lib.sh
13
14 test_expect_success setup '
15
16 for f in text binary union
17 do
18 echo Initial >$f && git add $f || return 1
19 done &&
20 test_tick &&
21 git commit -m Initial &&
22
23 git branch side &&
24 for f in text binary union
25 do
26 echo Main >>$f && git add $f || return 1
27 done &&
28 test_tick &&
29 git commit -m Main &&
30
31 git checkout side &&
32 for f in text binary union
33 do
34 echo Side >>$f && git add $f || return 1
35 done &&
36 test_tick &&
37 git commit -m Side &&
38
39 git tag anchor &&
40
41 cat >./custom-merge <<-\EOF &&
42 #!/bin/sh
43
44 orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
45 (
46 echo "orig is $orig"
47 echo "ours is $ours"
48 echo "theirs is $theirs"
49 echo "path is $path"
50 echo "=== orig ==="
51 cat "$orig"
52 echo "=== ours ==="
53 cat "$ours"
54 echo "=== theirs ==="
55 cat "$theirs"
56 ) >"$ours+"
57 cat "$ours+" >"$ours"
58 rm -f "$ours+"
59
60 if test -f ./please-abort
61 then
62 echo >>./please-abort killing myself
63 kill -9 $$
64 fi
65 exit "$exit"
66 EOF
67 chmod +x ./custom-merge
68 '
69
70 test_expect_success merge '
71
72 cat >.gitattributes <<-\EOF &&
73 binary -merge
74 union merge=union
75 EOF
76
77 if git merge main
78 then
79 echo Gaah, should have conflicted
80 false
81 else
82 echo Ok, conflicted.
83 fi
84 '
85
86 test_expect_success 'check merge result in index' '
87
88 git ls-files -u | grep binary &&
89 git ls-files -u | grep text &&
90 ! (git ls-files -u | grep union)
91
92 '
93
94 test_expect_success 'check merge result in working tree' '
95
96 git cat-file -p HEAD:binary >binary-orig &&
97 grep "<<<<<<<" text &&
98 cmp binary-orig binary &&
99 ! grep "<<<<<<<" union &&
100 grep Main union &&
101 grep Side union
102
103 '
104
105 test_expect_success 'retry the merge with longer context' '
106 echo text conflict-marker-size=32 >>.gitattributes &&
107 git checkout -m text &&
108 sed -ne "/^\([<=>]\)\1\1\1*/{
109 s/ .*$//
110 p
111 }" >actual text &&
112 grep ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" actual &&
113 grep "================================" actual &&
114 grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual
115 '
116
117 test_expect_success 'custom merge backend' '
118
119 echo "* merge=union" >.gitattributes &&
120 echo "text merge=custom" >>.gitattributes &&
121
122 git reset --hard anchor &&
123 git config --replace-all \
124 merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
125 git config --replace-all \
126 merge.custom.name "custom merge driver for testing" &&
127
128 git merge main &&
129
130 cmp binary union &&
131 sed -e 1,3d text >check-1 &&
132 o=$(git unpack-file main^:text) &&
133 a=$(git unpack-file side^:text) &&
134 b=$(git unpack-file main:text) &&
135 sh -c "./custom-merge $o $a $b 0 text" &&
136 sed -e 1,3d $a >check-2 &&
137 cmp check-1 check-2 &&
138 rm -f $o $a $b
139 '
140
141 test_expect_success 'custom merge backend' '
142
143 git reset --hard anchor &&
144 git config --replace-all \
145 merge.custom.driver "./custom-merge %O %A %B 1 %P" &&
146 git config --replace-all \
147 merge.custom.name "custom merge driver for testing" &&
148
149 if git merge main
150 then
151 echo "Eh? should have conflicted"
152 false
153 else
154 echo "Ok, conflicted"
155 fi &&
156
157 cmp binary union &&
158 sed -e 1,3d text >check-1 &&
159 o=$(git unpack-file main^:text) &&
160 a=$(git unpack-file anchor:text) &&
161 b=$(git unpack-file main:text) &&
162 sh -c "./custom-merge $o $a $b 0 text" &&
163 sed -e 1,3d $a >check-2 &&
164 cmp check-1 check-2 &&
165 sed -e 1,3d -e 4q $a >check-3 &&
166 echo "path is text" >expect &&
167 cmp expect check-3 &&
168 rm -f $o $a $b
169 '
170
171 test_expect_success !WINDOWS 'custom merge driver that is killed with a signal' '
172 test_when_finished "rm -f output please-abort" &&
173
174 git reset --hard anchor &&
175 git config --replace-all \
176 merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
177 git config --replace-all \
178 merge.custom.name "custom merge driver for testing" &&
179
180 >./please-abort &&
181 echo "* merge=custom" >.gitattributes &&
182 test_must_fail git merge main 2>err &&
183 grep "^error: failed to execute internal merge" err &&
184 git ls-files -u >output &&
185 git diff --name-only HEAD >>output &&
186 test_must_be_empty output
187 '
188
189 test_expect_success 'up-to-date merge without common ancestor' '
190 git init repo1 &&
191 git init repo2 &&
192 test_tick &&
193 (
194 cd repo1 &&
195 >a &&
196 git add a &&
197 git commit -m initial
198 ) &&
199 test_tick &&
200 (
201 cd repo2 &&
202 git commit --allow-empty -m initial
203 ) &&
204 test_tick &&
205 (
206 cd repo1 &&
207 git fetch ../repo2 main &&
208 git merge --allow-unrelated-histories FETCH_HEAD
209 )
210 '
211
212 test_expect_success 'custom merge does not lock index' '
213 git reset --hard anchor &&
214 write_script sleep-an-hour.sh <<-\EOF &&
215 sleep 3600 &
216 echo $! >sleep.pid
217 EOF
218
219 test_write_lines >.gitattributes \
220 "* merge=ours" "text merge=sleep-an-hour" &&
221 test_config merge.ours.driver true &&
222 test_config merge.sleep-an-hour.driver ./sleep-an-hour.sh &&
223
224 # We are testing that the custom merge driver does not block
225 # index.lock on Windows due to an inherited file handle.
226 # To ensure that the backgrounded process ran sufficiently
227 # long (and has been started in the first place), we do not
228 # ignore the result of the kill command.
229 # By packaging the command in test_when_finished, we get both
230 # the correctness check and the clean-up.
231 test_when_finished "kill \$(cat sleep.pid)" &&
232 git merge main
233 '
234
235 test_expect_success 'binary files with union attribute' '
236 git checkout -b bin-main &&
237 printf "base\0" >bin.txt &&
238 echo "bin.txt merge=union" >.gitattributes &&
239 git add bin.txt .gitattributes &&
240 git commit -m base &&
241
242 printf "one\0" >bin.txt &&
243 git commit -am one &&
244
245 git checkout -b bin-side HEAD^ &&
246 printf "two\0" >bin.txt &&
247 git commit -am two &&
248
249 if test "$GIT_TEST_MERGE_ALGORITHM" = ort
250 then
251 test_must_fail git merge bin-main >output
252 else
253 test_must_fail git merge bin-main 2>output
254 fi &&
255 grep -i "warning.*cannot merge.*HEAD vs. bin-main" output
256 '
257
258 test_done