Git: Handling Merge Conflicts Using “Ours” and “Theirs”
Share
Interests
Posted in these interests:
If you’ve arrived on this page, you’re probably in the middle of a merge conflict as we speak. To fix conflicts, we often have to open the file and manually sort out each conflicts, but sometimes we’re lucky and we can keep one version and throw out the other entirely. To do this, we can use git checkout
with one of two flags: --ours
or --theirs
.
Convenient, right? Maybe not.
The usage of --ours
and --their
might be a little confusing at first, so lets dive in and learn by example.
tl;dr
With feature
branch checked out.
git merge master | git rebase master | |
---|---|---|
Keep changes from master | --theirs | --ours |
Keep changes from feature | --ours | --theirs |
Continue reading for an explanation.
1 – Using –ours/–theirs during a merge
Technically speaking, use of git checkout --ours/--theirs
is only applicable during a merge. You might be wondering about rebases, and I’ll explain that in the next step.
For simplicity, let’s start with a basic merge conflict. Imagine our git history looks like this:
A---B---C feature
/
D---E---F---G master
The letters signify a commit, and each commit includes changes to our file: myscript.py.
So changes were made to myscript.py
in both master
and feature
branches. A common strategy is to routinely merge changes from master into your feature branch during development to keep the feature branch from getting too far out of date. But when we go to merge master
into feature
, we’re going to run into trouble:
(feature) $ git merge master
Auto-merging myscript.py
CONFLICT (content): Merge conflict in myscript.py
Automatic merge failed; fix conflicts and then commit the result.
In most cases, you’d want to open myscript.py
and sort out the merge conflicts. But in some cases, you’ll want to completely disregard one version and keep the other. This is where git checkout --ours/--theirs
comes into play.
Use --ours
keep the version in the current branch
Since we have our feature
branch checked out, we can use --ours
to keep the version of myscript.py
that resides in the feature
branch, and disregard the version from master
.
git checkout --ours myscript.py
Use --theirs
to keep the version from the branch being merged in
And --theirs
accomplishes the opposite. If we want to discard the version of myscript.py
that resides in our current branch and keep the version from master
, we can use --theirs
.
git checkout --theirs myscript.py
2 – Using –ours/–theirs during a rebase
When we run into merge conflicts during a rebase, we are effectively in the middle of a merge, so the rules for git checkout --ours/--theirs
from above still apply. But, the tricky part is identifying the “current” branch. Let me explain what happens during a rebase.
What happens during a rebase?
Again, let’s assume the following history:
A---B---C feature
/
D---E---F---G master
When we rebase master
“into” feature
, what we are really doing is this:
“Roll back” to the common ancestor and save the diff
In our case, we roll back to commit E, and save the diff of each commit introduce by the feature
branch.
A---B---C (saved in temporary files)
feature
/
D---E---F---G master
Reset the feature
branch to the current commit from master
The feature
branch now has the same history as master
.
A---B---C (saved in temporary files)
feature
/
D---E---F---G master
Apply the saved changes from the feature
branch
Now each change from the feature
branch (A
, B
, and C
) will be applied to the new feature
branch once again. It’s important to note, for the sake of this guide, that this is accomplished through a merge.
The new history looks like this:
A---B---C feature
/
D---E---F---G master
Ok, so how do I use git checkout --ours/--theirs
during a rebase?
The point of that long winded explanation was to show that when you are fixing merge conflicts in the middle of a rebase, your “current” branch is not longer your original feature
branch but rather a new branch that is up to date with master
. And the commits being merge into the current branch are the commits from your original feature branch. So --ours
and --theirs
will appear to be flipped around.
Use --ours
to keep changes from the branch being rebased onto (master
)
At the beginning of the rebase, we had feature
branch checked out, so it may seem backward, but we will use --ours
to keep changes from master.
git checkout --ours myscript.py
Use --theirs
to keep the changes from the “current” branch (feature
)
And naturally, the opposite is true. Use --theirs
to keep changes from the feature
branch.
git checkout --theirs myscript.py
3 – Conclusion
I know this can be confusing, so please let me know in the comments below if you thought this guide was helpful or if you could use further clarification!