Conflicts in git can be a pain to deal with especially that you have to go into each code block which generated a conflict and check which version you want to keep and sometimes it can be hard to be sure. However, in some scenarios, the choice is easy. You want to keep whatever already existed on the server, or the opposite, you want to override it all with what you have. In this case, instead of going through the conflicts manually, git has extremely helpful flags which are
--ours
and
--theirs
.
Let's assume that the conflict looks like this:
this is some content
=======
this is a totally different content
>>>>>>> new_branch
When you have a merge conflict and you know exactly which version you want to keep, entirely or on a file basis, you can use these flags like this:
git checkout --ours .
But when you use which? Is it "ours" or "theirs"? well, this can be a bit confusing... In the conflict above for example, it's hard to tell. You might say "HEAD is whatever already on the branch we're merging into and the other part is what's on the new branch" but it's actually more complicated than that.
If you looked into the help for the git checkout command, you'll see the following:
-2, --ours checkout our version for unmerged files
-3, --theirs checkout their version for unmerged files
That doesn't sound very helpful. Let's go to the actual documentation. For version 2.23.0 it says:
--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 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.
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 as ours (i.e. "our shared canonical history"), while what you did on your side branch as theirs (i.e. "one contributor’s work on top of it").
This one feels more intuitive as your guess is probably right:
To keep the changes that are on master:
git checkout --ours .
This one feels a bit counter-intuitive as ours is not the branch we're on:
To keep the changes that are on master:
git checkout --ours .
A pull command fetches data from a remote source and incorporate the changes into the local branch. The incorporation part can be done either with a merge operation (which is the default mode), or with a rebase operation.
The fetch + merge scenario looks as follows:
git checkout master
git pull origin new_branch
So exactly the same as a merge operation.
The fetch + rebase scenario happens in the following way:
However, you don't have to memorize it like this: merge makes sense and rebase doesn't 😅. It is actually much simpler than that and it can be summerized in one sentence:
"ours represents the history and theirs is the new applied commits".
In a merge, git takes the current branch and apply the additional commits to it's HEAD. The current branch is the history ours and the additional commits are new theirs. In a rebase, git rewrites the history of the current branch. Making it compatible with the other branch. Then, applies any additional commits from the current branch. The other branch becomes the history thus ours and the current branch might have new additions theirs.
Now let's get back to our conflict example if the operations was a merge, the final code would be:
this is some content
Once unpublished, all posts by tariqabughofa will become hidden and only accessible to themselves.
If tariqabughofa is not suspended, they can still re-publish their posts from their dashboard.