[PATCH 2/2] merge-one-file: fix broken merges with GIT_WORK_TREE
- From
Jeff King <peff@peff.net>
- Date
- Apr 28, 2011, 22:41 UTC
- Message-ID
- <20110428224125.GB16027@sigill.intra.peff.net>
- In-Reply-To
- <20110428223822.GA16004@sigill.intra.peff.net>
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