334

I am in the middle of rebasing after a git pull --rebase. I have a few files that have merge conflicts. How can I accept "their" changes or "my" changes for specific files?

$ git status
# Not currently on any branch.
# You are currently rebasing.
#   (fix conflicts and then run "git rebase --continue")
#   (use "git rebase --skip" to skip this patch)
#   (use "git rebase --abort" to check out the original branch)
#
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       modified:  CorrectlyMergedFile
#
# Unmerged paths:
#   (use "git reset HEAD <file>..." to unstage)
#   (use "git add <file>..." to mark resolution)
#
#       both modified: FileWhereIWantToAcceptTheirChanges
#       both modified: FileWhereIWantToAcceptMyChanges

Normally I just open the file or a merge tool and manually accept all "their" or "my" changes. However, I suspect I'm missing a convenient git command.

Also, note that I will only be able to choose a merge strategy for each file when I see what files hit conflicts an possibly what the conflicts are.

Steven Wexler
  • 16,589
  • 8
  • 53
  • 80
  • @AbeVoelker I don't think that solves my problem. I want to select a merge strategy for specific files. Also, note that I will only know what merge stragegy to use when I'm in my rebase and see which files have hit conflicts and what the conflicts are. – Steven Wexler May 30 '13 at 00:08
  • I edited this question to be more generic: http://stackoverflow.com/questions/278081/resolving-a-git-conflict-with-binary-files. Maybe we can close this question as a duplicate of that? Is that appropriate? –  May 30 '13 at 00:39
  • @TheShadow That seems reasonable to me. – Steven Wexler May 30 '13 at 00:41
  • I wasn't sure if it was appropriate to change the title of [the other question](http://stackoverflow.com/questions/278081/resolving-a-git-conflict-for-specific-file-ours-mine-or-theirs) to what I did, because I took out the part about resolving binary files. I restored the other question to what it was previously, so this current question still adds value. –  May 30 '13 at 12:55
  • Possible duplicate of [Simple tool to 'accept theirs' or 'accept mine' on a whole file using git](http://stackoverflow.com/questions/914939/simple-tool-to-accept-theirs-or-accept-mine-on-a-whole-file-using-git). –  Apr 12 '14 at 02:49
  • FWIW: I came here trying to somehow undo a poor rebase of MR/PR branch with main. While `git checkout --ours origin/mr-pr-branch` worked it resulted in hundreds of commits to push. In the end checked out to main, deleted local mr-pr-branch, and pulled/checked-out again. – s3c Jun 01 '22 at 04:47

4 Answers4

393

For each conflicted file you get, you can specify

git checkout --ours -- <paths>
# or
git checkout --theirs -- <paths>

From the git checkout docs

git checkout [-f|--ours|--theirs|-m|--conflict=<style>] [<tree-ish>] [--] <paths>...

--ours
--theirs
When checking out paths from the index, check out stage #2 (ours) or #3 (theirs) for unmerged paths.

The index may contain unmerged entries because of a previous failed merge. By default, if you try to check out such an entry from the index, the checkout operation will fail and nothing will be checked out. Using -f will ignore these unmerged entries. The contents from a specific side of the merge can be checked out of the index by using --ours or --theirs. With -m, changes made to the working tree file can be discarded to re-create the original conflicted merge result.

  • 11
    Is it possible to accept theires for all files that are left umerged? – aslakjo Dec 20 '13 at 09:57
  • 64
    @aslakjo `git rebase -s recursive -X ` or `git merge -s recursive -X `. Keep in mind that for a rebase, "ours" and "theirs" are reversed from what they are during a merge. You could probably just use a file/shell glob too, like `git checkout --theirs -- *.txt`. –  Apr 12 '14 at 02:52
  • This command does not work when is a submodule it seems. – user239558 Jan 12 '15 at 10:48
  • 3
    Many thanks, @Cupcake, the unexpected reversal of `ours/theirs` with rebase was driving me crazy!! (It makes sense now that I think about how a rebase actually works, but not at all intuitive.) – Dan Lenski Feb 19 '16 at 01:39
  • 2
    @DanLenski rebase in general is just a really tricky tool for people to understand at first, but once you do understand how it works, you can do all kinds of really powerful things with it. –  Feb 23 '16 at 07:40
  • Yeah, I like to think of myself as somewhat of an expert user of `rebase`, but I'm embarrassed to say I had never figured out the reversal of `ours`/`theirs` and would always do these "the hard way" (commit by commit) until I read this. – Dan Lenski Feb 23 '16 at 17:35
  • On Windows using Git Bash, I needed to use /\ (forward slash, backward slash) as path separator, e.g. `git checkout --ours -- **/\*.csproj`. I have no idea why and can't find an answer on Google. Can anyone point me to an explanation? Using anything else fails; I tried. `*.csproj`, `**/*.csproj`, `**\/*.csproj`. – Vincent Sels May 16 '17 at 09:56
  • I do this, then git add, then rebase --continue, and I find myself in the same situation again, can't get out of the loop. – Mehdi Jul 12 '17 at 09:27
  • somehow, git checkout has no effect on the staged files for me – Tin Man Apr 21 '18 at 23:10
  • 1
    @VincentSels actually, you need to mask the * character, else, the shell will try to expand it. so in your case `git checkout --outs -- "**/*.csproj"` will do what you mean. The same is true e.g. for `git lfs track "*.jpg"`. If you have some jpg-files in your CWD, without the quotes, only these would be tracked. – eFloh Apr 26 '18 at 12:14
  • @TinMan git is very quiet when using `git checkout --ours/--theirs -- `. Make sure you do a `git add ` afterwards, then you'll see the results you're looking for – 2Toad Dec 11 '18 at 20:12
  • **BEWARE**, using `checkout [--ours|--theirs] -- file` will *completely overwrite* the `file` with either: the one from our branch, or the one from the branch being merged. This is somehow dangerous as you may have correctly merged chunks on the `file` that you will discard! What you want is applying the `ours` or `theirs` strategy *only on the conflicting chunks* within the file! See [this answer](https://stackoverflow.com/questions/39126509/how-to-resolve-git-merge-conflict-from-command-line-using-a-given-strategy-fo) or *jakub.g*'s for a solution considering this point. – Totor Nov 29 '20 at 22:42
216

Even though this question is answered, providing an example as to what "theirs" and "ours" means in the case of git rebase vs merge. See this link

Git Rebase
theirs is actually the current branch in the case of rebase. So the below set of commands are actually accepting your current branch changes over the remote branch.

# see current branch
$ git branch
... 
* branch-a
# rebase preferring current branch changes during conflicts
$ git rebase -X theirs branch-b

Git Merge
For merge, the meaning of theirs and ours is reversed. So, to get the same effect during a merge, i.e., keep your current branch changes (ours) over the remote branch being merged (theirs).

# assuming branch-a is our current version
$ git merge -X ours branch-b  # <- ours: branch-a, theirs: branch-b
Gingi
  • 2,149
  • 1
  • 18
  • 34
Abe
  • 8,623
  • 10
  • 50
  • 74
  • What about a git pull --rebase ? – Will Farley Jul 28 '21 at 10:37
  • 3
    I *think* this was really helpful since `ours` is 100% opposite what one would think. Ours is the branch we're rebasing onto... right? Bizarre as expected. – Dan Rosenstark Nov 10 '21 at 16:52
  • 1
    @DanRosenstark think of rebasing as: 1. switching to `branch-b` (this becomes ours) 2. running `git commit` the first (and subsequently the next) commit from `branch-a` (this becomes theirs) 3. repeat step 2 for every other commit 4. point `branch-a` to the last commit from step 3. This is how "theirs" and "ours" is interpreted – Highmastdon Aug 24 '22 at 07:31
41

Note that git checkout --ours|--theirs will overwrite the files entirely, by choosing either theirs or ours version, which might be or might not be what you want to do (if you have any non-conflicted changes coming from the other side, they will be lost).

If instead you want to perform a three-way merge on the file, and only resolve the conflicted hunks using --ours|--theirs, while keeping non-conflicted hunks from both sides in place, you may want to resort to git merge-file; see details in this answer.

Community
  • 1
  • 1
jakub.g
  • 38,512
  • 12
  • 92
  • 130
  • 1
    Regarding "non-conflicting changes" that will be lost - this refers to only the files where there are non-conflicting changes in specific lines else where in the same file, or all changes from all files in aligned histories? – ktamlyn Mar 07 '18 at 22:07
  • 2
    @ktamlyn by "non-conflicting changes" I meant changes in the same file. For example, there are two changed hunks (parts) in `example.txt` in `ours` version, one is conflicted (also changed in the `theirs` revision), other is non-conflicted. If you do `git checkout --theirs example.txt`, it will just blindly read the whole file at `theirs` revision, and the non-conflicted part of the diff will be lost. – jakub.g Mar 14 '18 at 08:50
  • 1
    Thanks! This was a necessary clarification for me, even though "changes in the same file" makes the most sense in this context. – ktamlyn Mar 21 '18 at 16:51
  • This should be the accepted answer, well, although it doesn't really give an answer, but points out an important issue in the other proposed solution. – tomasyany Nov 07 '18 at 16:44
  • 1
    If you want to go back to the original conflicted file you can run `git checkout --merge `. – Andrew Keeton Oct 17 '19 at 18:31
15

quoting @user456814 from comment above:

git rebase -s recursive -X <ours/theirs>
or
git merge -s recursive -X <ours/theirs>

Keep in mind that for a rebase, "ours" and "theirs" are reversed from what they are during a merge

@user456814 gave this useful answer in comments on the accepted answer way back in 2014. I'm surfacing it here as a community wiki to make it easier to find, evaluate, update, etc, since comments are limited in that respect.

Kay V
  • 3,738
  • 2
  • 20
  • 20