This might sound like too basic of a question, but I have searched for answers and I am more confused now than before.
What does "ours" and "theirs" mean in git when merging my branch into my other branch? Both branches are "ours".
In a merge conflict is "ours" always the upper of the two versions displayed?
Does "ours" always refer to the branch that HEAD was pointing to when the merge began? If so then why not use a clear possessive reference like "current branch's" instead of using a possessive pronoun like "ours" that is referentially ambiguous (since both branches are technically ours)?
Or just use the branch name (instead of saying "ours" just say "local master's" or such)?
The most confusing part to me is if I specify in a specific branch's .gitattributes file. Lets say in test branch I have the following .gitattributes file:
config.xml merge=ours
Now I checkout and point HEAD to master then merge in test. Since master is ours, and test's .gitattributes is not checked out, will it even have an effect? If it does have an effect, since master is now "ours", then what will happen?
There is no precise meaning, precisely because these terms mean the opposite things depending on whether you are merging or rebasing. THE natural way of thinking about two branches is "my work" and "someone else's work". The choice of terminology that obscures this classification is absolutely THE worst design choice in git. It must have been inspired by accounting's "credit" and "debit" or "assets" and "liabilities" - same headache.
I'll post my memo here, because I have to come back here again and again.
SCENARIO 1. Normal developer: You are developer who can't merge to master
and have to play with feature
branches only.
Case 1: master is a king. You want to refresh your feature
branch (= rebase to master
), because master
contains new updates of dependencies and you want to overwrite your modest changes.
git checkout master
git pull
git checkout feature
git rebase -X ours master
Case 2: you are a king. You want to rebase your feature
branch to master
changes. But you did more than your colleagues had and want to use your own changes in a priority.
git checkout master
git pull
git checkout feature
git rebase -X theirs master
IMPORTANT: As you can see normal developers should prefer rebase
and repeat it every morning like exercises/coffee.
SCENARIO 2. Merging-sensei: You are a team-lead and want to merge other branches and push a merged result directly to a master. master
is a branch you will change.
Case 1: master is a king You want to merge third-party branch, but master
is a priority. feature
is a branch that your senior did.
git checkout feature
git pull
git checkout master
git merge -X ours feature
Case 2: new changes is a king When your senior developer released a cool feature
and you want to overwrite the old s**t in the master
branch.
git checkout feature
git pull
git checkout master
git merge -X theirs feature
REMEMBER: To remember in a midnight which one to choose: master
is ours
ALWAYS. And theirs
is a feature
that theirs have done.
Just to clarify -- as noted above when rebasing the sense is reversed, so if you see
<<<<<<< HEAD
foo = 12;
=======
foo = 22;
>>>>>>> [your commit message]
Resolve using 'mine' -> foo = 12
Resolve using 'theirs' -> foo = 22
I know it doesn't explain the meaning but I've made myself a little image, as reference to remind which one to use:
Hope it helps!
PS - Give a check also to the link in Nitay's answer
I know this has been answered, but this issue confused me so many times I've put up a small reference website to help me remember: https://nitaym.github.io/ourstheirs/
Here are the basics:
$ git checkout master
$ git merge feature
If you want to select the version in master
:
$ git checkout --ours codefile.js
If you want to select the version in feature
:
$ git checkout --theirs codefile.js
$ git checkout feature
$ git rebase master
If you want to select the version in master
:
$ git checkout --ours codefile.js
If you want to select the version in feature
:
$ git checkout --theirs codefile.js
(This is for complete files, of course)
So if you are on branch release/2.5 and you merge branch feature/new-buttons into it, then the content as found in release/2.5 is what ours refers to and the content as found on feature/new-buttons is what theirs refers to. During a merge action this is pretty straight forward.
The only problem most people fall for is the rebase case. If you do a re-base instead of a normal merge, the roles are swapped. How's that? Well, that's caused solely by the way rebasing works. Think of rebase to work like that:
Of course, that's not really what is going on but it's a nice mind model for me. And if you look at 2 and 3, you will understand why the roles are swapped now. As of 2, your current branch is now the branch from the server without any of your changes, so this is ours (the branch you are on). The changes you made are now on a different branch that is not your current one (BranchX) and thus these changes (despite being the changes you made) are theirs (the other branch used in your action).
That means if you merge and you want your changes to always win, you'd tell git to always choose "ours" but if you rebase and you want all your changes to always win, you tell git to always choose "theirs".
The 'ours' in Git is referring to the original working branch which has authoritative/canonical part of git history.
The 'theirs' refers to the version that holds the work in order to be rebased (changes to be replayed onto the current branch).
This may appear to be swapped to people who are not aware that doing rebasing (e.g. git rebase
) is actually taking your work on hold (which is theirs) in order to replay onto the canonical/main history which is ours, because we're rebasing our changes as third-party work.
The documentation for git-checkout
was further clarified in Git >=2.5.1 as per f303016
commit:
--ours
--theirs
When checking out paths from the index, check out stage #2 ('ours') or #3 ('theirs') for unmerged paths.
Note that during
git rebase
andgit 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.This is because
rebase
is used in a workflow that treats the history at the remote as the shared canonical one, and treats the work done on the branch you are rebasing as the third-party work to be integrated, and you are temporarily assuming the role of the keeper of the canonical history during the rebase. As the keeper of the canonical history, you need to view the history from the remote asours
(i.e. "our shared canonical history"), while what you did on your side branch astheirs
(i.e. "one contributor's work on top of it").
For git-merge
it's explain in the following way:
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. For a binary file, the entire contents are taken from our side.
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 the opposite of ours.
Further more, here is explained how to use them:
The merge mechanism (
git merge
andgit pull
commands) allows the backend merge strategies to be chosen with-s
option. Some strategies can also take their own options, which can be passed by giving-X<option>
arguments togit merge
and/orgit pull
.
So sometimes it can be confusing, for example:
git pull origin master
where -Xours
is our local, -Xtheirs
is theirs (remote) branchgit pull origin master -r
where -Xours
is theirs (remote), -Xtheirs
is oursSo the 2nd example is opposite to the 1st one, because we're rebasing our branch on top of the remote one, so our starting point is remote one, and our changes are treated as external.
Similar for git merge
strategies (-X ours
and -X theirs
).
From git checkout
's usage:
-2, --ours checkout our version for unmerged files
-3, --theirs checkout their version for unmerged files
-m, --merge perform a 3-way merge with the new branch
When resolving merge conflicts, you can do git checkout --theirs some_file
, and git checkout --ours some_file
to reset the file to the current version and the incoming versions respectively.
If you've done git checkout --ours some_file
or git checkout --theirs some_file
and would like to reset the file to the 3-way merge version of the file, you can do git checkout --merge some_file
.
Source: Stackoverflow.com