I have 2 git branches branch1 and branch2 and I want to merge file.py in branch2 into file.py in branch1 and only that file.
In essence I just want to work on the fi
You can stash
and stash pop
the file:
git checkout branch1
git checkout branch2 file.py
git stash
git checkout branch1
git stash pop
When content is in file.py
from branch2 that is no longer applies to branch1, it requires picking some changes and leaving others. For full control do an interactive merge using the --patch
switch:
$ git checkout --patch branch2 file.py
The interactive mode section in the man page for git-add(1)
explains the keys that are to be used:
y - stage this hunk
n - do not stage this hunk
q - quit; do not stage this hunk nor any of the remaining ones
a - stage this hunk and all later hunks in the file
d - do not stage this hunk nor any of the later hunks in the file
g - select a hunk to go to
/ - search for a hunk matching the given regex
j - leave this hunk undecided, see next undecided hunk
J - leave this hunk undecided, see next hunk
k - leave this hunk undecided, see previous undecided hunk
K - leave this hunk undecided, see previous hunk
s - split the current hunk into smaller hunks
e - manually edit the current hunk
? - print help
The split command is particularly useful.
What I've done is a bit manual, but I:
revert
;HEAD~1
, that is, their state in the
merge commit;Ugly? Yes. Easy to remember? Also yes.
If you only care about the conflict resolution and not about keeping the commit history, the following method should work. Say you want to merge a.py b.py
from BRANCHA
into BRANCHB
. First, make sure any changes in BRANCHB
are either committed or stashed away, and that there are no untracked files. Then:
git checkout BRANCHB
git merge BRANCHA
# 'Accept' all changes
git add .
# Clear staging area
git reset HEAD -- .
# Stash only the files you want to keep
git stash push a.py b.py
# Remove all other changes
git add .
git reset --hard
# Now, pull the changes
git stash pop
git
won't recognize that there are conflicts in a.py b.py
, but the merge conflict markers are there if there were in fact conflicts. Using a third-party merge tool, such as VSCode, one will be able to resolve conflicts more comfortably.
To merge only the changes from branch2's file.py
, make the other changes go away.
git checkout -B wip branch2
git read-tree branch1
git checkout branch2 file.py
git commit -m'merging only file.py history from branch2 into branch1'
git checkout branch1
git merge wip
Merge will never even look at any other file. You might need to '-f' the checkouts if the trees are different enough.
Note that this will leave branch1 looking as if everything in branch2's history to that point has been merged, which may not be what you want. A better version of the first checkout above is probably
git checkout -B wip `git merge-base branch1 branch2`
in which case the commit message should probably also be
git commit -m"merging only $(git rev-parse branch2):file.py into branch1"