2007-04-17 15:05:00 +08:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2007 Junio C Hamano
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='per path merge controlled by merge attribute'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
|
|
|
|
for f in text binary union
|
|
|
|
do
|
2015-03-25 13:29:52 +08:00
|
|
|
echo Initial >$f && git add $f || return 1
|
2007-04-17 15:05:00 +08:00
|
|
|
done &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m Initial &&
|
|
|
|
|
|
|
|
git branch side &&
|
|
|
|
for f in text binary union
|
|
|
|
do
|
2015-03-25 13:29:52 +08:00
|
|
|
echo Master >>$f && git add $f || return 1
|
2007-04-17 15:05:00 +08:00
|
|
|
done &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m Master &&
|
|
|
|
|
|
|
|
git checkout side &&
|
|
|
|
for f in text binary union
|
|
|
|
do
|
2015-03-25 13:29:52 +08:00
|
|
|
echo Side >>$f && git add $f || return 1
|
2007-04-17 15:05:00 +08:00
|
|
|
done &&
|
|
|
|
test_tick &&
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
git commit -m Side &&
|
2007-04-17 15:05:00 +08:00
|
|
|
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
git tag anchor
|
2007-04-17 15:05:00 +08:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success merge '
|
|
|
|
|
|
|
|
{
|
|
|
|
echo "binary -merge"
|
|
|
|
echo "union merge=union"
|
|
|
|
} >.gitattributes &&
|
|
|
|
|
|
|
|
if git merge master
|
|
|
|
then
|
|
|
|
echo Gaah, should have conflicted
|
|
|
|
false
|
|
|
|
else
|
|
|
|
echo Ok, conflicted.
|
|
|
|
fi
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check merge result in index' '
|
|
|
|
|
|
|
|
git ls-files -u | grep binary &&
|
|
|
|
git ls-files -u | grep text &&
|
|
|
|
! (git ls-files -u | grep union)
|
|
|
|
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'check merge result in working tree' '
|
|
|
|
|
|
|
|
git cat-file -p HEAD:binary >binary-orig &&
|
|
|
|
grep "<<<<<<<" text &&
|
|
|
|
cmp binary-orig binary &&
|
|
|
|
! grep "<<<<<<<" union &&
|
|
|
|
grep Master union &&
|
|
|
|
grep Side union
|
|
|
|
|
|
|
|
'
|
|
|
|
|
2010-01-21 15:49:27 +08:00
|
|
|
test_expect_success 'retry the merge with longer context' '
|
|
|
|
echo text conflict-marker-size=32 >>.gitattributes &&
|
|
|
|
git checkout -m text &&
|
|
|
|
sed -ne "/^\([<=>]\)\1\1\1*/{
|
|
|
|
s/ .*$//
|
|
|
|
p
|
|
|
|
}" >actual text &&
|
|
|
|
grep ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" actual &&
|
|
|
|
grep "================================" actual &&
|
|
|
|
grep "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" actual
|
|
|
|
'
|
|
|
|
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
cat >./custom-merge <<\EOF
|
|
|
|
#!/bin/sh
|
|
|
|
|
2015-06-05 06:10:29 +08:00
|
|
|
orig="$1" ours="$2" theirs="$3" exit="$4" path=$5
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
(
|
|
|
|
echo "orig is $orig"
|
|
|
|
echo "ours is $ours"
|
|
|
|
echo "theirs is $theirs"
|
2015-06-05 06:10:29 +08:00
|
|
|
echo "path is $path"
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
echo "=== orig ==="
|
|
|
|
cat "$orig"
|
|
|
|
echo "=== ours ==="
|
|
|
|
cat "$ours"
|
|
|
|
echo "=== theirs ==="
|
|
|
|
cat "$theirs"
|
|
|
|
) >"$ours+"
|
|
|
|
cat "$ours+" >"$ours"
|
|
|
|
rm -f "$ours+"
|
|
|
|
exit "$exit"
|
|
|
|
EOF
|
|
|
|
chmod +x ./custom-merge
|
|
|
|
|
|
|
|
test_expect_success 'custom merge backend' '
|
|
|
|
|
|
|
|
echo "* merge=union" >.gitattributes &&
|
|
|
|
echo "text merge=custom" >>.gitattributes &&
|
|
|
|
|
|
|
|
git reset --hard anchor &&
|
|
|
|
git config --replace-all \
|
2015-06-05 06:10:29 +08:00
|
|
|
merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
|
2007-04-19 02:27:32 +08:00
|
|
|
git config --replace-all \
|
|
|
|
merge.custom.name "custom merge driver for testing" &&
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
|
|
|
|
git merge master &&
|
|
|
|
|
|
|
|
cmp binary union &&
|
|
|
|
sed -e 1,3d text >check-1 &&
|
2008-09-03 16:59:29 +08:00
|
|
|
o=$(git unpack-file master^:text) &&
|
|
|
|
a=$(git unpack-file side^:text) &&
|
|
|
|
b=$(git unpack-file master:text) &&
|
2015-06-05 06:10:29 +08:00
|
|
|
sh -c "./custom-merge $o $a $b 0 'text'" &&
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
sed -e 1,3d $a >check-2 &&
|
|
|
|
cmp check-1 check-2 &&
|
|
|
|
rm -f $o $a $b
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'custom merge backend' '
|
|
|
|
|
|
|
|
git reset --hard anchor &&
|
|
|
|
git config --replace-all \
|
2015-06-05 06:10:29 +08:00
|
|
|
merge.custom.driver "./custom-merge %O %A %B 1 %P" &&
|
2007-04-19 02:27:32 +08:00
|
|
|
git config --replace-all \
|
|
|
|
merge.custom.name "custom merge driver for testing" &&
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
|
|
|
|
if git merge master
|
|
|
|
then
|
|
|
|
echo "Eh? should have conflicted"
|
|
|
|
false
|
|
|
|
else
|
|
|
|
echo "Ok, conflicted"
|
|
|
|
fi &&
|
|
|
|
|
|
|
|
cmp binary union &&
|
|
|
|
sed -e 1,3d text >check-1 &&
|
2008-09-03 16:59:29 +08:00
|
|
|
o=$(git unpack-file master^:text) &&
|
|
|
|
a=$(git unpack-file anchor:text) &&
|
|
|
|
b=$(git unpack-file master:text) &&
|
2015-06-05 06:10:29 +08:00
|
|
|
sh -c "./custom-merge $o $a $b 0 'text'" &&
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
sed -e 1,3d $a >check-2 &&
|
|
|
|
cmp check-1 check-2 &&
|
2015-06-05 06:10:29 +08:00
|
|
|
sed -e 1,3d -e 4q $a >check-3 &&
|
|
|
|
echo "path is text" >expect &&
|
|
|
|
cmp expect check-3 &&
|
Custom low-level merge driver support.
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
2007-04-18 13:51:45 +08:00
|
|
|
rm -f $o $a $b
|
|
|
|
'
|
|
|
|
|
2008-09-07 00:29:49 +08:00
|
|
|
test_expect_success 'up-to-date merge without common ancestor' '
|
|
|
|
test_create_repo repo1 &&
|
|
|
|
test_create_repo repo2 &&
|
|
|
|
test_tick &&
|
|
|
|
(
|
|
|
|
cd repo1 &&
|
|
|
|
>a &&
|
|
|
|
git add a &&
|
|
|
|
git commit -m initial
|
|
|
|
) &&
|
|
|
|
test_tick &&
|
|
|
|
(
|
|
|
|
cd repo2 &&
|
|
|
|
git commit --allow-empty -m initial
|
|
|
|
) &&
|
|
|
|
test_tick &&
|
|
|
|
(
|
|
|
|
cd repo1 &&
|
merge: refuse to create too cool a merge by default
While it makes sense to allow merging unrelated histories of two
projects that started independently into one, in the way "gitk" was
merged to "git" itself aka "the coolest merge ever", such a merge is
still an unusual event. Worse, if somebody creates an independent
history by starting from a tarball of an established project and
sends a pull request to the original project, "git merge" however
happily creates such a merge without any sign of something unusual
is happening.
Teach "git merge" to refuse to create such a merge by default,
unless the user passes a new "--allow-unrelated-histories" option to
tell it that the user is aware that two unrelated projects are
merged.
Because such a "two project merge" is a rare event, a configuration
option to always allow such a merge is not added.
We could add the same option to "git pull" and have it passed
through to underlying "git merge". I do not have a fundamental
opposition against such a feature, but this commit does not do so
and instead leaves it as low-hanging fruit for others, because such
a "two project merge" would be done after fetching the other project
into some location in the working tree of an existing project and
making sure how well they fit together, it is sufficient to allow a
local merge without such an option pass-through from "git pull" to
"git merge". Many tests that are updated by this patch does the
pass-through manually by turning:
git pull something
into its equivalent:
git fetch something &&
git merge --allow-unrelated-histories FETCH_HEAD
If somebody is inclined to add such an option, updated tests in this
change need to be adjusted back to:
git pull --allow-unrelated-histories something
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2016-03-19 04:21:09 +08:00
|
|
|
git fetch ../repo2 master &&
|
|
|
|
git merge --allow-unrelated-histories FETCH_HEAD
|
2008-09-07 00:29:49 +08:00
|
|
|
)
|
|
|
|
'
|
|
|
|
|
2016-08-22 20:47:55 +08:00
|
|
|
test_expect_success 'custom merge does not lock index' '
|
2016-08-18 22:51:12 +08:00
|
|
|
git reset --hard anchor &&
|
2016-11-09 21:51:22 +08:00
|
|
|
write_script sleep-an-hour.sh <<-\EOF &&
|
|
|
|
sleep 3600 &
|
2016-09-07 14:10:41 +08:00
|
|
|
echo $! >sleep.pid
|
2016-08-18 22:51:12 +08:00
|
|
|
EOF
|
|
|
|
|
|
|
|
test_write_lines >.gitattributes \
|
2016-11-09 21:51:22 +08:00
|
|
|
"* merge=ours" "text merge=sleep-an-hour" &&
|
2016-08-18 22:51:12 +08:00
|
|
|
test_config merge.ours.driver true &&
|
2016-11-09 21:51:22 +08:00
|
|
|
test_config merge.sleep-an-hour.driver ./sleep-an-hour.sh &&
|
2016-11-12 04:24:44 +08:00
|
|
|
|
|
|
|
# We are testing that the custom merge driver does not block
|
|
|
|
# index.lock on Windows due to an inherited file handle.
|
|
|
|
# To ensure that the backgrounded process ran sufficiently
|
|
|
|
# long (and has been started in the first place), we do not
|
|
|
|
# ignore the result of the kill command.
|
|
|
|
# By packaging the command in test_when_finished, we get both
|
|
|
|
# the correctness check and the clean-up.
|
|
|
|
test_when_finished "kill \$(cat sleep.pid)" &&
|
2016-11-11 07:54:12 +08:00
|
|
|
git merge master
|
2016-08-18 22:51:12 +08:00
|
|
|
'
|
|
|
|
|
2007-04-17 15:05:00 +08:00
|
|
|
test_done
|