Simple tool to 'accept theirs' or 'accept mine' on a whole file using git
I don't want a visual merge tool, and I also don't want to have to vi the conflicted file and manually choose the between HEAD (mine) and the imported change (theirs). Most of the time I either want all of their changes or all of mine. Commonly this is because my change made it upsteam and is coming back to me through a pull, but may be slightly modified in various places.
Is there a command line tool which will get rid of the conflict markers and choose all one way or another based on my choice? Or a set of git commands which I can alias myself to do each one.
# accept mine
alias am="some_sequence;of;commands"
alias at="some_other_sequence;of;commands"
Doing this is rather annoying. For 'accept mine' I have tried:
randy@sabotage ~/linus $ git merge test-branch
Auto-merging Makefile
CONFLICT (content): Merge conflict in Makefile
Automatic merge failed; fix conflicts and then commit the result.
randy@sabotage ~/linus $ git checkout Makefile
error: path 'Makefile' is unmerged
andy@sabotage ~/linus $ git reset --hard HEAD Makefile
fatal: Cannot do hard reset with paths.
How am I supposed to get rid of these change markers?
I can do:
git reset HEAD Makefile; rm Makefile; git checkout Makefile
But this seems rather round about, there must be a better way. And at this point, I'm not sure if git even thinks the merge happened, so I don't think this necessarily even works.
Going the other way, doing 'accept theirs' is equally messy. The only way I can figure it out is do:
git show test-branch:Makefile > Makefile; git add Makefile;
This also gives me a messed up commit message, which has Conflicts: Makefile in it twice.
Can someone please point out how to do the above two actions in a simpler way? Thanks
The solution is very simple. git checkout <filename>
tries to check out file from the index, and therefore fails on merge.
What you need to do is (i.e. checkout a commit):
To checkout your own version you can use one of:
git checkout HEAD -- <filename>
or
git checkout --ours -- <filename>
(Warning!: If you are rebasing --ours
and --theirs
are swapped.)
or
git show :2:<filename> > <filename> # (stage 2 is ours)
To checkout the other version you can use one of:
git checkout test-branch -- <filename>
or
git checkout --theirs -- <filename>
or
git show :3:<filename> > <filename> # (stage 3 is theirs)
You would also need to run 'add' to mark it as resolved:
git add <filename>
Try this:
To accept theirs changes: git merge --strategy-option theirs
To accept yours: git merge --strategy-option ours
Based on Jakub's answer you can configure the following git aliases for convenience:
accept-ours = "!f() { git checkout --ours -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
accept-theirs = "!f() { git checkout --theirs -- \"${@:-.}\"; git add -u \"${@:-.}\"; }; f"
They optionally take one or several paths of files to resolve and default to resolving everything under the current directory if none are given.
Add them to the [alias]
section of your ~/.gitconfig
or run
git config --global alias.accept-ours '!f() { git checkout --ours -- "${@:-.}"; git add -u "${@:-.}"; }; f'
git config --global alias.accept-theirs '!f() { git checkout --theirs -- "${@:-.}"; git add -u "${@:-.}"; }; f'