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