Merge branch 'jc/ll-merge-expose-path'
Traditionally, external low-level 3-way merge drivers are expected to produce their results based solely on the contents of the three variants given in temporary files named by %O, %A and %B on their command line. Additionally allow them to look at the final path (given by %P). * jc/ll-merge-expose-path: ll-merge: pass the original path to external drivers
This commit is contained in:
commit
49ac7358da
@ -774,7 +774,7 @@ To define a custom merge driver `filfre`, add a section to your
|
||||
----------------------------------------------------------------
|
||||
[merge "filfre"]
|
||||
name = feel-free merge driver
|
||||
driver = filfre %O %A %B
|
||||
driver = filfre %O %A %B %L %P
|
||||
recursive = binary
|
||||
----------------------------------------------------------------
|
||||
|
||||
@ -800,6 +800,9 @@ merge between common ancestors, when there are more than one.
|
||||
When left unspecified, the driver itself is used for both
|
||||
internal merge and the final merge.
|
||||
|
||||
The merge driver can learn the pathname in which the merged result
|
||||
will be stored via placeholder `%P`.
|
||||
|
||||
|
||||
`conflict-marker-size`
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
10
ll-merge.c
10
ll-merge.c
@ -9,6 +9,7 @@
|
||||
#include "xdiff-interface.h"
|
||||
#include "run-command.h"
|
||||
#include "ll-merge.h"
|
||||
#include "quote.h"
|
||||
|
||||
struct ll_merge_driver;
|
||||
|
||||
@ -166,17 +167,20 @@ static int ll_ext_merge(const struct ll_merge_driver *fn,
|
||||
{
|
||||
char temp[4][50];
|
||||
struct strbuf cmd = STRBUF_INIT;
|
||||
struct strbuf_expand_dict_entry dict[5];
|
||||
struct strbuf_expand_dict_entry dict[6];
|
||||
struct strbuf path_sq = STRBUF_INIT;
|
||||
const char *args[] = { NULL, NULL };
|
||||
int status, fd, i;
|
||||
struct stat st;
|
||||
assert(opts);
|
||||
|
||||
sq_quote_buf(&path_sq, path);
|
||||
dict[0].placeholder = "O"; dict[0].value = temp[0];
|
||||
dict[1].placeholder = "A"; dict[1].value = temp[1];
|
||||
dict[2].placeholder = "B"; dict[2].value = temp[2];
|
||||
dict[3].placeholder = "L"; dict[3].value = temp[3];
|
||||
dict[4].placeholder = NULL; dict[4].value = NULL;
|
||||
dict[4].placeholder = "P"; dict[4].value = path_sq.buf;
|
||||
dict[5].placeholder = NULL; dict[5].value = NULL;
|
||||
|
||||
if (fn->cmdline == NULL)
|
||||
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,
|
||||
for (i = 0; i < 3; i++)
|
||||
unlink_or_warn(temp[i]);
|
||||
strbuf_release(&cmd);
|
||||
strbuf_release(&path_sq);
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -269,6 +274,7 @@ static int read_merge_config(const char *var, const char *value, void *cb)
|
||||
* %A - temporary file name for our version.
|
||||
* %B - temporary file name for the other branches' version.
|
||||
* %L - conflict marker length
|
||||
* %P - the original path (safely quoted for the shell)
|
||||
*
|
||||
* The external merge driver should write the results in the
|
||||
* file named by %A, and signal that it has done with zero exit
|
||||
|
@ -85,11 +85,12 @@ test_expect_success 'retry the merge with longer context' '
|
||||
cat >./custom-merge <<\EOF
|
||||
#!/bin/sh
|
||||
|
||||
orig="$1" ours="$2" theirs="$3" exit="$4"
|
||||
orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
|
||||
(
|
||||
echo "orig is $orig"
|
||||
echo "ours is $ours"
|
||||
echo "theirs is $theirs"
|
||||
echo "path is $path"
|
||||
echo "=== orig ==="
|
||||
cat "$orig"
|
||||
echo "=== ours ==="
|
||||
@ -110,7 +111,7 @@ test_expect_success 'custom merge backend' '
|
||||
|
||||
git reset --hard anchor &&
|
||||
git config --replace-all \
|
||||
merge.custom.driver "./custom-merge %O %A %B 0" &&
|
||||
merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
|
||||
git config --replace-all \
|
||||
merge.custom.name "custom merge driver for testing" &&
|
||||
|
||||
@ -121,7 +122,7 @@ test_expect_success 'custom merge backend' '
|
||||
o=$(git unpack-file master^:text) &&
|
||||
a=$(git unpack-file side^:text) &&
|
||||
b=$(git unpack-file master:text) &&
|
||||
sh -c "./custom-merge $o $a $b 0" &&
|
||||
sh -c "./custom-merge $o $a $b 0 'text'" &&
|
||||
sed -e 1,3d $a >check-2 &&
|
||||
cmp check-1 check-2 &&
|
||||
rm -f $o $a $b
|
||||
@ -131,7 +132,7 @@ test_expect_success 'custom merge backend' '
|
||||
|
||||
git reset --hard anchor &&
|
||||
git config --replace-all \
|
||||
merge.custom.driver "./custom-merge %O %A %B 1" &&
|
||||
merge.custom.driver "./custom-merge %O %A %B 1 %P" &&
|
||||
git config --replace-all \
|
||||
merge.custom.name "custom merge driver for testing" &&
|
||||
|
||||
@ -148,9 +149,12 @@ test_expect_success 'custom merge backend' '
|
||||
o=$(git unpack-file master^:text) &&
|
||||
a=$(git unpack-file anchor:text) &&
|
||||
b=$(git unpack-file master:text) &&
|
||||
sh -c "./custom-merge $o $a $b 0" &&
|
||||
sh -c "./custom-merge $o $a $b 0 'text'" &&
|
||||
sed -e 1,3d $a >check-2 &&
|
||||
cmp check-1 check-2 &&
|
||||
sed -e 1,3d -e 4q $a >check-3 &&
|
||||
echo "path is text" >expect &&
|
||||
cmp expect check-3 &&
|
||||
rm -f $o $a $b
|
||||
'
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user