Phuc
Phuc

Reputation: 743

Is the snapshot of the last commit of rebase and a merge are the same?

I'm a newbie learner in Git. I'm reading the book at [https://git-scm.com/book/en/v2] and now i'm on the chapter "3.6 Rebasing".

This chapter has a point:

Note that the snapshot pointed to by the final commit you end up with, whether it’s the last of the rebased commits for a rebase or the final merge commit after a merge, is the same snapshot – it’s only the history that is different.

I think it's not right in all cases. Let's look at a case below.

Assume we are at a commit C0 on 2 branches master and test. And we have an empty foo text file.

Next, we check out the master, write a text "line 1" to foo and make a commit C1. Then we check out the test, also write a text "line 1" to foo, make a commit C2. After that, we remove the text "line 1" from foo, make a commit C3.

History now:

C0---C1 master
 \
  C2---C3 test-HEAD

Now we have 2 cases to move:

  1. Use the merging by git merge master: Git take the merged result to C4. The content of foo now is "line 1". History now:

    C0---C1 master
    |      \
    C2--C3--C4 test
    
  2. Use the rebasing by git rebase master: the last commit after rebasing is C3'. The content of foo now is empty. History now:

    C0---C1 master
          \
           C2'---C3' test
    

You can see, the snapshot is pointed by C4 and by C3' are not the same, because content of foo in C4 is different with foo in C3'. So I think the quoted sentence above is not right in this case.

Am I have something wrong? Thank you.

P/s: I'm not very good in English, so please forgive me if have something not good in my writing.

Upvotes: 1

Views: 215

Answers (1)

Matthieu Moy
Matthieu Moy

Reputation: 16547

Use the rebasing by git rebase master: the last commit after rebasing is C3'. The content of foo now is empty.

No. C2' tries to add "line1" to the file, but it already contains this line so you get a conflict. Depending on how you resolve the conflict the result may be different. If you decide to keep both "line1" lines (the one in C1, and the one you're adding in C2), then C3' will remove one of these lines (again, you'll get a conflict and it depends on how you resolve it), and you'll get "line1" as the content.

I think your mistake is to think that C3 and C3' correspond to the same snapshot. They don't: they correspond to the same patch, i.e. the same difference with respect to their parents.

Bottom-line: rebase may create more conflicts that merge, especially in cases where the history goes one way and cancels it later. When you don't have conflicts, the end result of rebase and merge must be the same.

Upvotes: 1

Related Questions