git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] merge-one-file and GIT_WORK_TREE
@ 2011-04-28 22:38 Jeff King
  2011-04-28 22:39 ` [PATCH 1/2] add tests for merge-index / merge-one-file Jeff King
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Jeff King @ 2011-04-28 22:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Aman Gupta, git

[argh, resend, actually remembering to cc the list this time]

At GitHub, we're using read-tree, merge-index, and merge-one-file to do
trivial content-level merges from bare repositories (without having to
check out the entire repository contents each time).

However, we noticed a bug in git-merge-one-file when used with
GIT_WORK_TREE; it can silently create bogus results that ignore the
"theirs" side of files needing content-level merging.

The problem is that merge-one-file simply assumes it is in the root of
the working tree without any checking.  The only two places we use
merge-one-file in git itself are in the octopus and resolve strategies.
I think normal use is fine, because "git merge" will have changed to the
toplevel of the worktree already.

So I doubt anybody else is being affected by this. But we do expose the
commands for general use, with no disclaimer or check on the working
tree status or location. And the resulting bogus merge is a nasty
surprise.

  [1/2]: add tests for merge-index / merge-one-file
  [2/2]: merge-one-file: fix broken merges with GIT_WORK_TREE

-Peff

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/2] add tests for merge-index / merge-one-file
  2011-04-28 22:38 [PATCH 0/2] merge-one-file and GIT_WORK_TREE Jeff King
@ 2011-04-28 22:39 ` Jeff King
  2011-04-29  6:12   ` Johannes Sixt
  2011-04-28 22:41 ` [PATCH 2/2] merge-one-file: fix broken merges with GIT_WORK_TREE Jeff King
  2011-04-29 16:27 ` [PATCH 0/2] merge-one-file and GIT_WORK_TREE Junio C Hamano
  2 siblings, 1 reply; 6+ messages in thread
From: Jeff King @ 2011-04-28 22:39 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Aman Gupta, git

There were no tests for either, except a brief use in
t1200-tutorial.

These tools are not used much these days, as most people
use the merge-recursive strategy, which handles everything
internally. However, they are used by the "octopus" and
"resolve" strategies, as well as any custom strategies
or merge scripts people have built around them.

For example, together with read-tree, they are the simplest
way to do a basic content-level merge without checking out
the entire repository contents beforehand.

This script adds a basic test of the tools to perform one
content-level merge. It also shows a failure of the tools to
work properly in the face of GIT_WORK_TREE.

Signed-off-by: Jeff King <peff@peff.net>
---
We could also exercise the more exotic "both sides added" code paths of
merge-one-file. But anybody who cares about that these days is almost
certainly using "read-tree --aggressive" anyway.

 t/t6060-merge-index.sh |   70 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 70 insertions(+), 0 deletions(-)
 create mode 100755 t/t6060-merge-index.sh

diff --git a/t/t6060-merge-index.sh b/t/t6060-merge-index.sh
new file mode 100755
index 0000000..8f8ec77
--- /dev/null
+++ b/t/t6060-merge-index.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+test_description='basic git merge-index / git-merge-one-file tests'
+. ./test-lib.sh
+
+test_expect_success 'setup diverging branches' '
+	for i in 1 2 3 4 5 6 7 8 9 10; do
+		echo $i
+	done >file &&
+	git add file &&
+	git commit -m base &&
+	git tag base &&
+	sed s/2/two/ <file >tmp &&
+	mv tmp file &&
+	git commit -a -m two &&
+	git tag two &&
+	git checkout -b other HEAD^ &&
+	sed s/10/ten/ <file >tmp &&
+	mv tmp file &&
+	git commit -a -m ten &&
+	git tag ten
+'
+
+cat >expect-merged <<'EOF'
+1
+two
+3
+4
+5
+6
+7
+8
+9
+ten
+EOF
+
+test_expect_success 'read-tree does not resolve content merge' '
+	git read-tree -i -m base ten two &&
+	echo file >expect &&
+	git diff-files --name-only --diff-filter=U >unmerged &&
+	test_cmp expect unmerged
+'
+
+test_expect_success 'git merge-index git-merge-one-file resolves' '
+	git merge-index git-merge-one-file -a &&
+	git diff-files --name-only --diff-filter=U >unmerged &&
+	>expect &&
+	test_cmp expect unmerged &&
+	test_cmp expect-merged file &&
+	git cat-file blob :file >file-index &&
+	test_cmp expect-merged file-index
+'
+
+test_expect_failure 'merge-one-file respects GIT_WORK_TREE' '
+	git clone . bare.git &&
+	(cd bare.git &&
+	 mkdir work &&
+	 GIT_WORK_TREE=$PWD/work &&
+	 export GIT_WORK_TREE &&
+	 GIT_INDEX_FILE=$PWD/merge.index &&
+	 export GIT_INDEX_FILE &&
+	 git read-tree -i -m base ten two &&
+	 git merge-index git-merge-one-file -a &&
+	 git cat-file blob :file >work/file-index
+	) &&
+	test_cmp expect-merged bare.git/work/file &&
+	test_cmp expect-merged bare.git/work/file-index
+'
+
+test_done
-- 
1.7.5.rc3.17.g5e09b

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/2] merge-one-file: fix broken merges with GIT_WORK_TREE
  2011-04-28 22:38 [PATCH 0/2] merge-one-file and GIT_WORK_TREE Jeff King
  2011-04-28 22:39 ` [PATCH 1/2] add tests for merge-index / merge-one-file Jeff King
@ 2011-04-28 22:41 ` Jeff King
  2011-04-29 16:27 ` [PATCH 0/2] merge-one-file and GIT_WORK_TREE Junio C Hamano
  2 siblings, 0 replies; 6+ messages in thread
From: Jeff King @ 2011-04-28 22:41 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Aman Gupta, git

The merge-one-file tool predates the invention of
GIT_WORK_TREE. By the time GIT_WORK_TREE was invented, most
people were using the merge-recursive strategy, which
handles resolving internally. Therefore these features have
had very little testing together.

For the most part, merge-one-file just works with
GIT_WORK_TREE; most of its heavy lifting is done by plumbing
commands which do respect GIT_WORK_TREE properly. The one
exception is a shell redirection which touches the worktree
directly, writing results to the wrong place in the presence
of a GIT_WORK_TREE variable.

This means that merges won't even fail; they will silently
produce incorrect results, throwing out the entire "theirs"
side of files which need content-level merging!

This patch properly prefixes the path in the shell
redirection. An alternative strategy would be to have
merge-one-file use git-sh-setup, and cd_to_toplevel
beforehand. I opted for the minimal fix here, as changing
directories would impact where merge-one-file is unpacking
and working with files.

While we're at it, we'll also error-check the call to cat.
Merging a file in a subdirectory could in fact fail, as the
redirection relies on the "checkout-index" call just prior
to create leading directories. But we never noticed, since
we ignored the error return from running cat.

Signed-off-by: Jeff King <peff@peff.net>
---
 git-merge-one-file.sh  |    4 +++-
 t/t6060-merge-index.sh |    2 +-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh
index b86402a..0b5e3f6 100755
--- a/git-merge-one-file.sh
+++ b/git-merge-one-file.sh
@@ -132,7 +132,9 @@ case "${1:-.}${2:-.}${3:-.}" in
 
 	# Create the working tree file, using "our tree" version from the
 	# index, and then store the result of the merge.
-	git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4"
+	git checkout-index -f --stage=2 -- "$4" &&
+		cat "$src1" >"${GIT_WORK_TREE:+$GIT_WORK_TREE/}$4" ||
+		exit 1
 	rm -f -- "$orig" "$src1" "$src2"
 
 	if [ "$6" != "$7" ]; then
diff --git a/t/t6060-merge-index.sh b/t/t6060-merge-index.sh
index 8f8ec77..fd90e70 100755
--- a/t/t6060-merge-index.sh
+++ b/t/t6060-merge-index.sh
@@ -51,7 +51,7 @@ test_expect_success 'git merge-index git-merge-one-file resolves' '
 	test_cmp expect-merged file-index
 '
 
-test_expect_failure 'merge-one-file respects GIT_WORK_TREE' '
+test_expect_success 'merge-one-file respects GIT_WORK_TREE' '
 	git clone . bare.git &&
 	(cd bare.git &&
 	 mkdir work &&
-- 
1.7.5.rc3.17.g5e09b

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] add tests for merge-index / merge-one-file
  2011-04-28 22:39 ` [PATCH 1/2] add tests for merge-index / merge-one-file Jeff King
@ 2011-04-29  6:12   ` Johannes Sixt
  2011-04-29  6:25     ` Junio C Hamano
  0 siblings, 1 reply; 6+ messages in thread
From: Johannes Sixt @ 2011-04-29  6:12 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Aman Gupta, git

Am 4/29/2011 0:39, schrieb Jeff King:
> +	sed s/2/two/ <file >tmp &&

You are not using -e; will all seds out there grok this?

-- Hannes

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 1/2] add tests for merge-index / merge-one-file
  2011-04-29  6:12   ` Johannes Sixt
@ 2011-04-29  6:25     ` Junio C Hamano
  0 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2011-04-29  6:25 UTC (permalink / raw)
  To: Johannes Sixt; +Cc: Jeff King, Aman Gupta, git

Johannes Sixt <j.sixt@viscovery.net> writes:

> Am 4/29/2011 0:39, schrieb Jeff King:
>> +	sed s/2/two/ <file >tmp &&
>
> You are not using -e; will all seds out there grok this?

That should be Ok, as long as the script is not ambiguous.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/2] merge-one-file and GIT_WORK_TREE
  2011-04-28 22:38 [PATCH 0/2] merge-one-file and GIT_WORK_TREE Jeff King
  2011-04-28 22:39 ` [PATCH 1/2] add tests for merge-index / merge-one-file Jeff King
  2011-04-28 22:41 ` [PATCH 2/2] merge-one-file: fix broken merges with GIT_WORK_TREE Jeff King
@ 2011-04-29 16:27 ` Junio C Hamano
  2 siblings, 0 replies; 6+ messages in thread
From: Junio C Hamano @ 2011-04-29 16:27 UTC (permalink / raw)
  To: Jeff King; +Cc: Junio C Hamano, Aman Gupta, git

Jeff King <peff@peff.net> writes:

> The problem is that merge-one-file simply assumes it is in the root of
> the working tree without any checking.

It is kind of surprising that there was only one place that you needed to
touch ;-).

Thanks.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2011-04-29 16:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-28 22:38 [PATCH 0/2] merge-one-file and GIT_WORK_TREE Jeff King
2011-04-28 22:39 ` [PATCH 1/2] add tests for merge-index / merge-one-file Jeff King
2011-04-29  6:12   ` Johannes Sixt
2011-04-29  6:25     ` Junio C Hamano
2011-04-28 22:41 ` [PATCH 2/2] merge-one-file: fix broken merges with GIT_WORK_TREE Jeff King
2011-04-29 16:27 ` [PATCH 0/2] merge-one-file and GIT_WORK_TREE Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).