Skip to content

Commit 6aaeca9

Browse files
peffgitster
authored andcommitted
merge-one-file: fix broken merges with alternate work trees
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 makes merge-one-file chdir to the toplevel of the working tree (and exit if we don't have one). This most closely matches the assumption made by the original script (before separate work trees were invented), and matches what happens when the script is called as part of a merge strategy. 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 <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cf1af1b commit 6aaeca9

File tree

2 files changed

+8
-3
lines changed

2 files changed

+8
-3
lines changed

git-merge-one-file.sh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ LONG_USAGE="Usage: git merge-one-file $USAGE
2222
2323
Blob ids and modes should be empty for missing files."
2424

25+
SUBDIRECTORY_OK=Yes
26+
. git-sh-setup
27+
cd_to_toplevel
28+
require_work_tree
29+
2530
if ! test "$#" -eq 7
2631
then
2732
echo "$LONG_USAGE"
@@ -132,7 +137,7 @@ case "${1:-.}${2:-.}${3:-.}" in
132137

133138
# Create the working tree file, using "our tree" version from the
134139
# index, and then store the result of the merge.
135-
git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4"
140+
git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1
136141
rm -f -- "$orig" "$src1" "$src2"
137142

138143
if [ "$6" != "$7" ]; then

t/t6060-merge-index.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ test_expect_success 'merge-one-file fails without a work tree' '
6868
)
6969
'
7070

71-
test_expect_failure 'merge-one-file respects GIT_WORK_TREE' '
71+
test_expect_success 'merge-one-file respects GIT_WORK_TREE' '
7272
(cd bare.git &&
7373
mkdir work &&
7474
GIT_WORK_TREE=$PWD/work &&
@@ -82,7 +82,7 @@ test_expect_failure 'merge-one-file respects GIT_WORK_TREE' '
8282
test_cmp expect-merged bare.git/work/file-index
8383
'
8484

85-
test_expect_failure 'merge-one-file respects core.worktree' '
85+
test_expect_success 'merge-one-file respects core.worktree' '
8686
mkdir subdir &&
8787
git clone . subdir/child &&
8888
(cd subdir &&

0 commit comments

Comments
 (0)