How do I resolve a git merge conflict in favor of pulled changes?
I want to remove all conflicting changes from a working tree without having to go through all of the conflicts with git mergetool
, while keeping all conflict-free changes. Preferably, I want to do this while pulling, not afterwards.
git pull -s recursive -X theirs <remoterepo or other repo>
Or, simply, for the default repository:
git pull -X theirs
If you're already in conflicted state...
git checkout --theirs path/to/file
Answered 2023-09-21 08:07:08
-s recursive
here is redundant, since that's the default merge strategy. So you could simplify it to git pull -X theirs
, which is basically equivalent to git pull --strategy-option theirs
. - anyone MERGING
state. I can then git merge --abort
and try again, but each time I end up with a merge occurring. … I know that a rebase was pushed to my upstream though, so perhaps that's causing this? - anyone git checkout --theirs path/to/file
. Used it during rebase and got unexpected results. Found explanation in doc: Note that during git rebase and git pull --rebase, ours and theirs may appear swapped; --ours gives the version from the branch the changes are rebased onto, while --theirs gives the version from the branch that holds your work that is being rebased. - anyone git checkout --theirs/--ours path
man page states that it works for unmerged paths. So if there were no conflict in path, it is already merged this command will do nothing. This might case issues when you want for example 'theirs' version of a whole sub-folder. So in such case it would be safer to do git checkout MERGE_HEAD path
or use commit hash. - anyone git pull -X theirs
creates a merge commit if there are conflicts (e.g. if another committer ran git push -f
to the remote). If you don't want merge commits, run instead git fetch && git reset --hard origin/master
. - anyone You can use the recursive "theirs" strategy option:
git merge --strategy-option theirs
From the man:
ours
This option forces conflicting hunks to be auto-resolved cleanly by
favoring our version. Changes from the other tree that do not
conflict with our side are reflected to the merge result.
This should not be confused with the ours merge strategy, which does
not even look at what the other tree contains at all. It discards
everything the other tree did, declaring our history contains all that
happened in it.
theirs
This is opposite of ours.
Note: as the man page says, the "ours" merge strategy-option is very different from the "ours" merge strategy.
Answered 2023-09-21 08:07:08
git checkout --theirs
to operate on a single conflicting file - anyone git checkout <ref to theirs> -- the/conflicted.file
; and then git add
their changes. - anyone If you're already in conflicted state, and you want to just accept all of theirs:
git checkout --theirs .
git add .
If you want to do the opposite:
git checkout --ours .
git add .
This is pretty drastic, so make sure you really want to wipe everything out like this before doing it.
Answered 2023-09-21 08:07:08
.
and specify the file(s) in place of the dot that you want to checkout. less "drastic" & exactly what you want to do, presumably. - anyone git add -u
instead to skip files that are not under version control. - anyone git checkout --ours
takes all ours changes including non conflicting. Be careful with that. - anyone OK so, picture the scenario I was just in:
You attempt a merge
, or maybe a cherry-pick
, and you're stopped with
$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
Now, you view the conflicted file and you really don't want to keep your changes. In my case above, the file was conflicted on just a newline my IDE had auto-added. To undo your changes and accept their's, the easiest way is:
git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
The converse of this (to overwrite the incoming version with your version) is
git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php
Surprisingly, I couldn't find this answer very easily on the Net.
Answered 2023-09-21 08:07:08
git status
between checkout
and add
, the file still shows as "both modified". - anyone git reset --hard
and then git pull [remote server name] [branch name] -Xtheirs
(undoes the merge then pulls the new stuff on top of my stuff) - not sure if this what you want. - anyone If you're already in conflicted state, and do not want to checkout path one by one. You may try
git merge --abort
git pull -X theirs
Answered 2023-09-21 08:07:08
git merge <your-branches> -X theirs
- anyone git pull -r origin main -X theirs
- anyone git pull origin <my-branch-name>
I do git pull origin <my-branch-name> -X theirs
to get everything from upstream and overwrite any tracked files I have with their version. You can also do a git pull
and then settle the merge conflicts, but when there are many conflicts, the -X theirs
is what you want. - anyone git checkout --theirs <file>
for such requirement. - anyone The git pull -X theirs
answers may create an ugly merge commit, or issue an
error: Your local changes to the following files would be overwritten by merge:
If you want to simply ignore any local modifications to files from the repo, for example on a client that should always be a mirror of an origin, run this (replace master
with the branch you want):
git fetch && git reset --hard origin/master
How does it work? git fetch
does git pull
but without merge. Then git reset --hard
makes your working tree match the last commit. All of your local changes to files in the repo will be discarded, but new local files will be left alone.
Answered 2023-09-21 08:07:08
git fetch && git reset --hard {remote}/{branch}
was what solved my problem. I needed to completely ditch my own changes in favour of "theirs" state of a branch, but the git pull -X theirs
choked on some moved/renamed files. Thanks! - anyone git pull
afterwards I go back to conflicting state, may be I shouldn't have git pulled, but why not? - anyone Please not that sometimes this will not work:
git checkout --ours path/to/file
or
git checkout --theirs path/to/file
I did this instead, assuming HEAD is ours and MERGE_HEAD is theirs
git checkout HEAD -- path/to/file
or:
git checkout MERGE_HEAD -- path/to/file
After we do this and we are good:
git add .
If you want to understand more, see wonderful post of torek here : git checkout --ours does not remove files from unmerged files list
Answered 2023-09-21 08:07:08
VS Code (integrated Git) IDE Users:
If you want to accept all the incoming changes in the conflict file then do the following steps.
1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming
Similarly you can do for other options like Accept All Both, Accept All Current etc.,
Answered 2023-09-21 08:07:08
To resolve all conflicts with the version in a particular branch:
git diff --name-only --diff-filter=U | xargs git checkout ${branchName}
So, if you are already in the merging state, and you want to keep the master version of the conflicting files:
git diff --name-only --diff-filter=U | xargs git checkout master
Answered 2023-09-21 08:07:08
git cherry-pick --continue
or a git commit --allow-empty
command to commit these changes, and there seems to be no system behind which command is required, which makes automating this a pain. I’m currently solving this by testing for the existence of a .git/COMMIT_EDITMSG
file but that seems hacky and brittle, and I’m not yet convinced that it always works. - anyone git add
) then you can bulk resolve the rest via this. git checkout --ours
/ git checkout --theirs
is useful too. - anyone git checkout --ours/theirs
doesn't exclusively resolve conflicts. It checks out (takes the entire file) from either ours/theirs
.
Suppose we have a file foo
with changes in two commits/branches/trees/whatever. If there was a conflict introduced by theirs, as well as a modification, and we want to resolve the conflict using ours
-- then using checkout --ours foo
will discard the changes introducing conflicts, but also the modifications.
sed -i -e '/^<<<<<<</,/^=======/d' -e '/^>>>>>>>/d' foo
-i
Modify the file in place,/^<<<<<<</,/^=======/d
delete everything between and including <<<<<<<
and =======
(ours)/^>>>>>>>/d
delete the remaining conflict marker-e
specify multiple patterns to SEDfoo
the filesed -i -e '/^<<<<<<</d' -e '/^=======/,/^>>>>>>>/d' foo
I made a script that you can call git resolve -o/-t/-b
.
You can create custom merge tools. Building on the above sed
scripts you can put something like this in your git-config
:
[mergetool "ours"]
cmd = "sed -i -e '/^<<<<<<</d' -e '/^=======/,/^>>>>>>>/d' -- $MERGED"
and call it git mergetool --tool=ours
Note that there are other non-standard merge styles, like diff3
and zdiff3
as pointed out by @Stavros in the comments. The number of conflict markers is also not hard coded to 7 in git. I believe it's mainly just a default and as I recall, it can be configured.
The basic sed
script can be tweaked to work with all configurations.
Answered 2023-09-21 08:07:08
git merge --theirs|--ours
do, i.e pick the whole file from theirs or ours branch. Currently there is no built-in command line option in git to resolve ONLY the conflict part, picking theirs or ours. This can only be done by manual editing. Some merge tools (e.g Tortoise, P4, kdf3 etc) help. The sed
option in this answer is handy and the one closest to a command line option. - anyone git resolve -t/--theirs -o/--ours -b/--both -a/--add
. Bug reports and PRs are welcomed and appreciated - anyone -a
, but it adds the files after resolving conflict (which is good). - anyone Update 2023!
If you want to accept all current changes and ignore any incoming changes, you could accomplish this:
git merge [branch] --strategy-option ours
[branch]
should be replaced with the name of the branch you are merging into your current branch.
If, instead, you know you want to overwrite any current changes and accept all conflicts from incoming changes, you can use the theirs
strategy instead:
git merge [branch] --strategy-option theirs
Answered 2023-09-21 08:07:08
[branch]
could be origin/yourbranchname
- anyone from https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging
This will basically do a fake merge. It will record a new merge commit with both branches as parents, but it will not even look at the branch you’re merging in. It will simply record as the result of the merge the exact code in your current branch.
$ git merge -s ours mundo
Merge made by the 'ours' strategy.
$ git diff HEAD HEAD~
You can see that there is no difference between the branch we were on and the result of the merge.
This can often be useful to basically trick Git into thinking that a branch is already merged when doing a merge later on. For example, say you branched off a release branch and have done some work on it that you will want to merge back into your master branch at some point. In the meantime some bugfix on master needs to be backported into your release branch. You can merge the bugfix branch into the release branch and also merge -s ours the same branch into your master branch (even though the fix is already there) so when you later merge the release branch again, there are no conflicts from the bugfix.
A situation I've found to be useful if I want master to reflect the changes of a new topic branch. I've noticed that -Xtheirs doesn't merge without conflicts in some circumstances... e.g.
$ git merge -Xtheirs topicFoo
CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.
In this case the solution I found was
$ git checkout topicFoo
from topicFoo, first merge in master using the -s ours strategy, this will create the fake commit that is just the state of topicFoo. $ git merge -s ours master
check the created merge commit
$ git log
now checkout the master branch
$ git checkout master
merge the topic branch back but this time use the -Xtheirs recursive strategy, this will now present you with a master branch with the state of topicFoo.
$ git merge -X theirs topicFoo
Answered 2023-09-21 08:07:08
I had a long-running next-version
branch with tons of deletions to files that had changed on develop
, files that had been added in different places on both branches, etc.
I wanted to take the entire contents of the next-version
branch into develop
, all in one whopping merge commit.
The combination of the above commands that worked for me was:
git merge -X theirs next-version
# lots of files left that were modified on develop but deleted on next-version
git checkout next-version .
# files removed, now add the deletions to the commit
git add .
# still have files that were added on develop; in my case they are all in web/
git rm -r web
Not a new answer, just combining bits from many answers, partly to reassure that you might need all of these answers.
Answered 2023-09-21 08:07:08
Accept remote changes (theirs
) and in case there are conflicts you get the following error:
fatal: Not possible to fast-forward, aborting.
so you may want to pull and accept their changes with fast-forward:
$ git pull -X theirs --ff
Answered 2023-09-21 08:07:08
In Emacs using smerge-mode, to resolve all conflict markers using either mine or theirs, we can define:
(defun aj/smerge-keep-mine-all ()
""
(interactive)
(save-excursion
(beginning-of-buffer)
(while (ignore-errors 'user-error (progn (smerge-next) t))
(smerge-keep-mine))))
(defun aj/smerge-keep-other-all ()
""
(interactive)
(save-excursion
(beginning-of-buffer)
(while (ignore-errors 'user-error (progn (smerge-next) t))
(smerge-keep-other))))
Answered 2023-09-21 08:07:08
I found that I needed to specify origin main as the branch I was merging into.
git merge **origin main** --strategy-option theirs
Answered 2023-09-21 08:07:08
Even though there are already great answers here, I wanted to post this answer to document how to resolve all merge conflicts in Visual Studio (in favor of our changes as an example).
If instead, you want to accept incoming changes (their changes) as asked in this question, just replace ours
in Step 6 below with theirs
. It's as simple as that.
Summary of what I'm doing here:
Merge dev into my branch and while doing that if there are any merge conflicts, take changes from my branch.
(After this is done, I'll create a PR to finally push the changes from my branch to dev).
Checkout the branch where you want to merge dev
into by going to 'Manage Branches' and double clicking your branch name. In my case, it's feature\InterimBranchToDev2-AshK
.
Right click dev
and click Merge 'dev' into 'feature/InterimBranchToDev2-AshK'
You'll see a ton of merge conflicts! 😲
Now it's very tedious to right click each of those files and click Keep Current (feature/InterimBranchToDev2-AshK)
, so let's Abort
this and take care of this using command line.
Hit Abort
Open cmd
Type git merge --strategy-option ours --no-commit dev
and hit enter
What this basically means: "Merge dev into current branch and if there are any merge conflicts, take version from current branch, and also don't commit the merge yet".
This will be the output:
Automatic merge went well; stopped before committing as requested
Now go to Visual Studio, conflicts are nicely taken care of and you can enter your message and commit:
Answered 2023-09-21 08:07:08
Starting with an example,
We have a main
branch and a dev
branch having some conflicts
Pull updates before checkout, so the main branch is up to date:
git checkout main
git pull
git checkout dev
Then merge:
git merge --strategy-option theirs main
git merge --strategy-option ours main
ours
and theirs
here are special words, they have meaning and are not custom, but main
or dev
could be any other two branches you want to merge together.
Answered 2023-09-21 08:07:08