[PATCH 2/2] merge-one-file: fix broken merges with GIT_WORK_TREE
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(-)
Show changes to 2 files +4 −2
git-merge-one-file.sh, t/t6060-merge-index.sh
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