The above is the result of merge and rebase.
My question is that in the final state ,are C5 and C3' identical?
Or say,git rebase
is equal 开发者_开发知识库to git merge
+ remove C3?
The example isn't very good, because it only consider one commit (merged or rebased), giving you the impression that the resulting commits are similar. In general, a rebase will add multiple commits, while a merge will add at most one (fast-forward merges add none).
Moreover, as long as there is no conflict to solve, or if you solve said conflicts the same way each time, the final content of C3' and C5 will be the same but they remain different commits (since C3' and C5 have different parents, they'll also have different hashes, a fact that is more obvious in the illustrations below). Correspondingly, the recorded history for each is different. Note for the rebase, the history is linear, while for the merge it's a lattice.
Consider the same question when merging/rebasing several commits, as illustrated in "A Visual Git Reference" from Mark Lodato. You will see that the end result is quite different.
git checkout master
git merge other # update master with tip of branch 'other' changes
You take only:
- the current commit (ed489 below since you are on master),
- the latest commit of branch other (which is a snapshot representing the full content of the repo when branched in '
other
', not a delta) - their common ancestor (b325c), and performs a three-way merge.
For the meaning of the working directory and stage in this diagram, note the arrows going to the three-way merge, then to the working directory and stage. The working directory represents all the files that you see (on your hard drive), some of which are changed as a result of the three-way merge. The stage holds the files changed by the three-way merge, which is then used to create the new commit (f8bc5).
This is very different from a rebase which strives to reapply each and every commit of a branch on top of the destination branch:
git checkout topic # this time we are on topic
git rebase master # means: recreate every topic commits on top of master
at the end, we are still on (new) 'topic' branch
The above command takes all the commits that exist in '
topic
' but not inmaster
(namely169a6
and2c33a
), replays them ontomaster
, and then moves the branch head to the new tip. Note that the old commits will be [eventually] garbage collected if they are no longer referenced.
Rebasing uses the working directory and the staging area as it replays the commits (apply changes to working directory, add changes to staging area, commit the staged changes, repeat). Once all this is done, the head of the rebased branch is set to the last of the new commits (f7e63).
2 additional differences:
- Merge and rebase serve different workflows: See "git merge vs. rebase"
- "ours" and "theirs" are different between a merge and a rebase: "Why is the meaning of “ours” and “theirs” reversed"
No. C5 and C3' will have different parent commits, meaning they will themselves be different.
If you are asking whether the root treeish referenced by C5 and C3' will be identical, then yes (assuming that any conflicts were resolved the same way). In other words, the tree of files "contained in" both commits will be the same.
If you look at just the contents of the commits (i.e. not what are their parents) then both C5 and C3' contain the same thing (assuming there were no merge conflicts or other things requiring manual change). So somebody could think of it as being the same as if C3 had been removed, for some definition of "remove C3". But in Git it's not possible to remove any commits (all commits are immutable), so the operation of removing a commit from the tree is not defined for Git.
精彩评论