Merge branch 'sh/mergetool-hideresolved'
[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-lib.sh
12
13 test_expect_success setup '
14
15         for f in text binary union
16         do
17                 echo Initial >$f && git add $f || return 1
18         done &&
19         test_tick &&
20         git commit -m Initial &&
21
22         git branch side &&
23         for f in text binary union
24         do
25                 echo Main >>$f && git add $f || return 1
26         done &&
27         test_tick &&
28         git commit -m Main &&
29
30         git checkout side &&
31         for f in text binary union
32         do
33                 echo Side >>$f && git add $f || return 1
34         done &&
35         test_tick &&
36         git commit -m Side &&
37
38         git tag anchor &&
39
40         cat >./custom-merge <<-\EOF &&
41         #!/bin/sh
42
43         orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
44         (
45                 echo "orig is $orig"
46                 echo "ours is $ours"
47                 echo "theirs is $theirs"
48                 echo "path is $path"
49                 echo "=== orig ==="
50                 cat "$orig"
51                 echo "=== ours ==="
52                 cat "$ours"
53                 echo "=== theirs ==="
54                 cat "$theirs"
55         ) >"$ours+"
56         cat "$ours+" >"$ours"
57         rm -f "$ours+"
58         exit "$exit"
59         EOF
60         chmod +x ./custom-merge
61 '
62
63 test_expect_success merge '
64
65         {
66                 echo "binary -merge"
67                 echo "union merge=union"
68         } >.gitattributes &&
69
70         if git merge main
71         then
72                 echo Gaah, should have conflicted
73                 false
74         else
75                 echo Ok, conflicted.
76         fi
77 '
78
79 test_expect_success 'check merge result in index' '
80
81         git ls-files -u | grep binary &&
82         git ls-files -u | grep text &&
83         ! (git ls-files -u | grep union)
84
85 '
86
87 test_expect_success 'check merge result in working tree' '
88
89         git cat-file -p HEAD:binary >binary-orig &&
90         grep "<<<<<<<" text &&
91         cmp binary-orig binary &&
92         ! grep "<<<<<<<" union &&
93         grep Main union &&
94         grep Side union
95
96 '
97
98 test_expect_success 'retry the merge with longer context' '
99         echo text conflict-marker-size=32 >>.gitattributes &&
100         git checkout -m text &&
101         sed -ne "/^\([<=>]\)\1\1\1*/{
102                 s/ .*$//
103                 p
104         }" >actual text &&
105         grep ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" actual &&
106         grep "================================" actual &&
107         grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual
108 '
109
110 test_expect_success 'custom merge backend' '
111
112         echo "* merge=union" >.gitattributes &&
113         echo "text merge=custom" >>.gitattributes &&
114
115         git reset --hard anchor &&
116         git config --replace-all \
117         merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
118         git config --replace-all \
119         merge.custom.name "custom merge driver for testing" &&
120
121         git merge main &&
122
123         cmp binary union &&
124         sed -e 1,3d text >check-1 &&
125         o=$(git unpack-file main^:text) &&
126         a=$(git unpack-file side^:text) &&
127         b=$(git unpack-file main:text) &&
128         sh -c "./custom-merge $o $a $b 0 text" &&
129         sed -e 1,3d $a >check-2 &&
130         cmp check-1 check-2 &&
131         rm -f $o $a $b
132 '
133
134 test_expect_success 'custom merge backend' '
135
136         git reset --hard anchor &&
137         git config --replace-all \
138         merge.custom.driver "./custom-merge %O %A %B 1 %P" &&
139         git config --replace-all \
140         merge.custom.name "custom merge driver for testing" &&
141
142         if git merge main
143         then
144                 echo "Eh? should have conflicted"
145                 false
146         else
147                 echo "Ok, conflicted"
148         fi &&
149
150         cmp binary union &&
151         sed -e 1,3d text >check-1 &&
152         o=$(git unpack-file main^:text) &&
153         a=$(git unpack-file anchor:text) &&
154         b=$(git unpack-file main:text) &&
155         sh -c "./custom-merge $o $a $b 0 text" &&
156         sed -e 1,3d $a >check-2 &&
157         cmp check-1 check-2 &&
158         sed -e 1,3d -e 4q $a >check-3 &&
159         echo "path is text" >expect &&
160         cmp expect check-3 &&
161         rm -f $o $a $b
162 '
163
164 test_expect_success 'up-to-date merge without common ancestor' '
165         test_create_repo repo1 &&
166         test_create_repo repo2 &&
167         test_tick &&
168         (
169                 cd repo1 &&
170                 >a &&
171                 git add a &&
172                 git commit -m initial
173         ) &&
174         test_tick &&
175         (
176                 cd repo2 &&
177                 git commit --allow-empty -m initial
178         ) &&
179         test_tick &&
180         (
181                 cd repo1 &&
182                 git fetch ../repo2 main &&
183                 git merge --allow-unrelated-histories FETCH_HEAD
184         )
185 '
186
187 test_expect_success 'custom merge does not lock index' '
188         git reset --hard anchor &&
189         write_script sleep-an-hour.sh <<-\EOF &&
190                 sleep 3600 &
191                 echo $! >sleep.pid
192         EOF
193
194         test_write_lines >.gitattributes \
195                 "* merge=ours" "text merge=sleep-an-hour" &&
196         test_config merge.ours.driver true &&
197         test_config merge.sleep-an-hour.driver ./sleep-an-hour.sh &&
198
199         # We are testing that the custom merge driver does not block
200         # index.lock on Windows due to an inherited file handle.
201         # To ensure that the backgrounded process ran sufficiently
202         # long (and has been started in the first place), we do not
203         # ignore the result of the kill command.
204         # By packaging the command in test_when_finished, we get both
205         # the correctness check and the clean-up.
206         test_when_finished "kill \$(cat sleep.pid)" &&
207         git merge main
208 '
209
210 test_done