Skip to content

Commit ef45bb1

Browse files
committed
ll-merge: pass the original path to external drivers
The interface to custom low-level merge driver was modeled to be capable of driving programs like "merge" (from the RCS suite) that can produce result solely by looking at three files that hold contents of common ancestor, ours and theirs. The information we feed to the external drivers via the command line placeholders %O, %A, and %B were designed to be purely about contents by giving names of the temporary files that hold these variants without exposing the original pathname. No matter where the result goes, merging the same three variants should produce the same result, contents is the king, that is the Git way. The external driver interface, however, is meant to help people to step outside the Git worldview, and sometimes people want to know the final path that the resulting merged contents would be stored in. Expose this to the external drivers via a new placeholder %P. Requested-by: Andreas Gondek Signed-off-by: Junio C Hamano <[email protected]>
1 parent fdf96a2 commit ef45bb1

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

Documentation/gitattributes.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -774,7 +774,7 @@ To define a custom merge driver `filfre`, add a section to your
774774
----------------------------------------------------------------
775775
[merge "filfre"]
776776
name = feel-free merge driver
777-
driver = filfre %O %A %B
777+
driver = filfre %O %A %B %L %P
778778
recursive = binary
779779
----------------------------------------------------------------
780780

@@ -800,6 +800,9 @@ merge between common ancestors, when there are more than one.
800800
When left unspecified, the driver itself is used for both
801801
internal merge and the final merge.
802802

803+
The merge driver can learn the pathname in which the merged result
804+
will be stored via placeholder `%P`.
805+
803806

804807
`conflict-marker-size`
805808
^^^^^^^^^^^^^^^^^^^^^^

ll-merge.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "xdiff-interface.h"
1010
#include "run-command.h"
1111
#include "ll-merge.h"
12+
#include "quote.h"
1213

1314
struct ll_merge_driver;
1415

@@ -166,17 +167,20 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
166167
{
167168
char temp[4][50];
168169
struct strbuf cmd = STRBUF_INIT;
169-
struct strbuf_expand_dict_entry dict[5];
170+
struct strbuf_expand_dict_entry dict[6];
171+
struct strbuf path_sq = STRBUF_INIT;
170172
const char *args[] = { NULL, NULL };
171173
int status, fd, i;
172174
struct stat st;
173175
assert(opts);
174176

177+
sq_quote_buf(&path_sq, path);
175178
dict[0].placeholder = "O"; dict[0].value = temp[0];
176179
dict[1].placeholder = "A"; dict[1].value = temp[1];
177180
dict[2].placeholder = "B"; dict[2].value = temp[2];
178181
dict[3].placeholder = "L"; dict[3].value = temp[3];
179-
dict[4].placeholder = NULL; dict[4].value = NULL;
182+
dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
183+
dict[5].placeholder = NULL; dict[5].value = NULL;
180184

181185
if (fn->cmdline == NULL)
182186
die("custom merge driver %s lacks command line.", fn->name);
@@ -210,6 +214,7 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
210214
for (i = 0; i < 3; i++)
211215
unlink_or_warn(temp[i]);
212216
strbuf_release(&cmd);
217+
strbuf_release(&path_sq);
213218
return status;
214219
}
215220

@@ -269,6 +274,7 @@ static int read_merge_config(const char *var, const char *value, void *cb)
269274
* %A - temporary file name for our version.
270275
* %B - temporary file name for the other branches' version.
271276
* %L - conflict marker length
277+
* %P - the original path (safely quoted for the shell)
272278
*
273279
* The external merge driver should write the results in the
274280
* file named by %A, and signal that it has done with zero exit

t/t6026-merge-attr.sh

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,12 @@ test_expect_success 'retry the merge with longer context' '
8585
cat >./custom-merge <<\EOF
8686
#!/bin/sh
8787
88-
orig="$1" ours="$2" theirs="$3" exit="$4"
88+
orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
8989
(
9090
echo "orig is $orig"
9191
echo "ours is $ours"
9292
echo "theirs is $theirs"
93+
echo "path is $path"
9394
echo "=== orig ==="
9495
cat "$orig"
9596
echo "=== ours ==="
@@ -110,7 +111,7 @@ test_expect_success 'custom merge backend' '
110111
111112
git reset --hard anchor &&
112113
git config --replace-all \
113-
merge.custom.driver "./custom-merge %O %A %B 0" &&
114+
merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
114115
git config --replace-all \
115116
merge.custom.name "custom merge driver for testing" &&
116117
@@ -121,7 +122,7 @@ test_expect_success 'custom merge backend' '
121122
o=$(git unpack-file master^:text) &&
122123
a=$(git unpack-file side^:text) &&
123124
b=$(git unpack-file master:text) &&
124-
sh -c "./custom-merge $o $a $b 0" &&
125+
sh -c "./custom-merge $o $a $b 0 'text'" &&
125126
sed -e 1,3d $a >check-2 &&
126127
cmp check-1 check-2 &&
127128
rm -f $o $a $b
@@ -131,7 +132,7 @@ test_expect_success 'custom merge backend' '
131132
132133
git reset --hard anchor &&
133134
git config --replace-all \
134-
merge.custom.driver "./custom-merge %O %A %B 1" &&
135+
merge.custom.driver "./custom-merge %O %A %B 1 %P" &&
135136
git config --replace-all \
136137
merge.custom.name "custom merge driver for testing" &&
137138
@@ -148,9 +149,12 @@ test_expect_success 'custom merge backend' '
148149
o=$(git unpack-file master^:text) &&
149150
a=$(git unpack-file anchor:text) &&
150151
b=$(git unpack-file master:text) &&
151-
sh -c "./custom-merge $o $a $b 0" &&
152+
sh -c "./custom-merge $o $a $b 0 'text'" &&
152153
sed -e 1,3d $a >check-2 &&
153154
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 &&
154158
rm -f $o $a $b
155159
'
156160

0 commit comments

Comments
 (0)