The git merge
command deals in commits (period, full stop, end of options ... well, there are some options, but they still apply to the commit-wide merge). It:
- starts with the current (
HEAD
) commit;
- takes something to specify the other commit, usually a branch name;
- automatically finds the merge-base commit using
git merge-base --all HEAD other-commit
;
- and (assuming a single merge base) merges all the files resulting from two diffs:
diff -M base HEAD
, and diff -M base other
.
So unless one or both of those two commit-wide git diff
commands only pick out one changed file, you cannot use git merge
to do this.
You can use git checkout -p
to do an interactive patch to one file, as compared to a second file. This is not a merge, although some people refer to this as a "two-way merge" operation.
So, the probable solution
You can also use git checkout
or git show
to extract specific versions of a single file from particular commits. If you select three such versions—a merge base, the current commit, and some other commit, for instance—you can then instruct Git to perform a three-way merge on that one file, using the git merge-file
command. For instance:
git show 1234567:foo.txt > /tmp/foo.txt.base
cp foo.txt /tmp/foo.txt.merge
git show 8888888:foo.txt > /tmp/foo.txt.other
(cd /tmp; git merge-file foo.txt.merge foo.txt.base foo.txt.other)
You now have a merged file in /tmp/foo.txt.merge, complete with any conflict markers. Note that this file is independent of a Git repository, but if you like it, you can replace any of the files in your work-tree (such as foo.txt
) with it. Or, of course, you can even just do the merge-file operation directly in your work-tree.
If you replace the first hard-coded commit hash with the other branch name, and the middle (merge base) commit hash with the hash produced by git merge-base --all HEAD otherbranch
, you probably get the kind of thing you want.
A possibly-easier alternative
You can also run git merge -n
to run a full merge (of all files, automatically finding the merge base commit) but avoid committing the resulting merge even if it all seems to Git to have worked. You can then finish only the part of the merge you care about, save the result, run git merge --abort
to terminate the in-progress merge, and copy the saved result back.