70

Suppose I am rebasing experiment branch on master and there are conflicts in files. And of course there are files deleted in both branches. So when I am resolving the conflicts, in git status I see deleted by us and deleted by them. Its very confusing. Is there any way of understanding what they mean? Who is them and who is us?

Or while rebasing is there another way to know which file was deleted by which branch? Like printing the branch name?

Urist McDev
  • 498
  • 3
  • 14
Milind Dumbare
  • 3,104
  • 2
  • 19
  • 32

2 Answers2

64

Reference documentation

Note that a rebase merge works by replaying each commit from the working branch on top of the <upstream> branch. Because of this, when a merge conflict happens, the side reported as ours is the so-far rebased series, starting with <upstream>, and theirs is the working branch. In other words, the sides are swapped.

https://git-scm.com/docs/git-rebase/2.17.0 (latest: https://git-scm.com/docs/git-rebase)

Hence, files "deleted by us" are those that were deleted on the branch you are rebasing onto (the final branch), and files "deleted by them" are files that were deleted in the branch you are rebasing (the one that will be dropped).

Demonstration

$ ls
a
$ git log --oneline --graph --decorate --all
* d055cdd (HEAD -> y) Write baz in a-file
| * 487dc8c (x) Write bar in a-file
|/  
* 3fa0da5 (master) Write foo in a-file
$ git rebase x
First, rewinding head to replay your work on top of it...
Applying: Write baz in a-file
Using index info to reconstruct a base tree...
M   a
Falling back to patching base and 3-way merge...
Auto-merging a
CONFLICT (content): Merge conflict in a
error: Failed to merge in the changes.
Patch failed at 0001 Write baz in a-file
The copy of the patch that failed is found in: .git/rebase-apply/patch

When you have resolved this problem, run "git rebase --continue".
If you prefer to skip this patch, run "git rebase --skip" instead.
To check out the original branch and stop rebasing, run "git rebase --abort".
$ cat a
<<<<<<< HEAD
bar
=======
baz
>>>>>>> Write baz in a-file
$ git checkout --ours a
$ cat a
bar
$ git checkout --theirs a
$ cat a
baz

AFAIK there is no switch to display the specific names of the branches explicitly with the official tools. Unless I'm wrong this is just one of those things you need to learn to get through the initial confusion.

To their credit, it does make a lot of sense if you think about it.

More pedantic analysis

The text of the manual page is a little ambiguous as it could be interpreted to be relevant only when using the --merge option. This is exacerbated by a second mention of the behavior in --strategy: "Note the reversal of ours and theirs as noted above for the -m option.".

However, I believe this is not contrasting the behavior of git-rebase when --merge is used with when it isn't; rather I believe it is contrasting the behavior of git-rebase with git-merge. The MERGE STRATEGIES section is clearly ripped from the git-merge manual page, so it's somewhat easy to imagine that the author felt the need to emphasize the swap when using rebase since it's not mentioned in that section. The following sentence, to me, confirms this interpretation: "[...] git rebase replays each commit from the working branch on top of the branch using the given strategy [...]".

Although we now understand that the merge strategy should have no impact on the sides (only the choice of git-merge vs git-rebase should), I'll note --merge is implied by the default strategy regardless (making the default behavior completely non-ambiguous).

tne
  • 7,071
  • 2
  • 45
  • 68
  • 77
    "To their credit, it does make a lot of sense" - shouldn't that be "To *our* credit..." :-) – Jon Burgess Aug 06 '15 at 01:49
  • 13
    "To our credit, it does make a lot of sense if they think about it." – kkm inactive - support strike Jan 24 '16 at 00:39
  • 13
    `it does make a lot of sense if you think about it.` Nope, it sure doesn't. Especially when rebasing a branch authored by yourstruly. Them = me. – Cheeso Jul 27 '16 at 03:06
  • 4
    @Cheeso The key insight is that a rebase is like checking out the upstream branch, then cherry-picking each commit from the current branch onto it. When you look at it this way, the working branch (ours) is the upstream branch, and the other one (which we cherry-pick from) is the "foreign" one (theirs). Once the rebase is complete, git resets the head on the new branch and checks it out. This is a very mechanical/procedural understanding, but I stand by the claim that "to our credit, it does make a lot of sense if they think about it" ;). – tne Jul 27 '16 at 18:35
  • The portion of the man page quoted in this answer refers specifically to the `-m, --merge` option. It does **not** explicitly answer the question of what those terms mean when the `-m` or `--merge` option has not been used. –  May 13 '18 at 21:52
  • 1
    @sampablokuper The wording in the quote is definitely not as clear as it could be, but I couldn't find another quote in the reference documentation. I've made an attempt at a more pedantic interpretation of the text to hopefully more convincingly confirm that the quote is in fact relevant regardless of whether `--merge` is used or not. `--merge` is implied by default, but feel free to test rebase conflict resolution using non-default strategies that don't imply it if you want to be more adequately convinced. You'd have my vote for a little patch to the refdocs if you can find better wording. – tne May 14 '18 at 19:14
  • @tne, thanks and upvoted. I agree that Git's docs need improvement in this regard:.The OP's question is likely to arise in the mind of any Git user encountering such a message as the OP reported (especially for the first time), yet the `git rebase` man page fails to answer it clearly and explicitly. I greatly appreciate your effort to post the steps by which, despite the manual's circumlocutions, an apparently unambiguous conclusion can be deduced. I got there the same way. If better wording for the man page ever strikes me, I will of course aim to file a patch :) Thanks again. –  May 15 '18 at 00:22
27

Below is a copy of SzG's answer on a similar question:

When you merge, us refers to the branch you're merging into, as opposed to them, the branch to be merged.

When you rebase, us refers the upstream branch, and them is the branch you're moving about. It's a bit counter-intuitive in case of a rebase.

The reason is that git uses the same merge-engine for rebase, and it's actually cherry-picking your stuff into the upstream branch. us = into, them = from.

anothernode
  • 5,100
  • 13
  • 43
  • 62
Maxim Suslov
  • 4,335
  • 1
  • 35
  • 29