[ git ] merge v.s. rebase

overview

* integrate changes from one branch into another branch—they just do it in very different ways.

scenario

     [ feature ]
          |
          v
     -F-F-F
    /
-x-x--M-M
        ^
        |
    [ master ]

o = changes
To incorporate new commits to feature branch, we have 2 options : merging or rebasing.

1) Merging option

Command :

git checkout feature
git merge master

or

git merge master feature

This creates a new “merge commit” in the feature branch that ties together the histories of both branches, giving you a branch structure like this

        [ feature ]
            |
            v

     -F-F-F-*(merge commit)
    /
-x-x--M-M
        ^
        |
    [ master ]

Pro :
Merge = “non-destructive operation”.
The existing branches are not changed in any way. This avoids all of the potential pitfalls of rebasing

Con :
Feature branch will have an extraneous merge commit every time you need to incorporate upstream changes.
If master is very active, this can pollute your feature branch’s history quite a bit.
While it’s possible to mitigate this issue with advanced “git log” options, it can make it hard for other developers to understand the history of the project.

2) Rebase option

Rebase the feature branch onto master branch using the following command

git checkout feature
git rebase master

This moves the entire feature branch to begin on the tip of the master branch, effectively incorporating all of the new commits in master.
But, instead of using a merge commit, rebasing re-writes the project history by creating brand new commits for each commit in the original branch.

           [ feature ]
                |
                v
-x-x--M-M-F*-F*-F*
        ^
        |
    [ master ]

* = brand new commit

Pro :
Get a much cleaner project history.
First, it eliminates the unnecessary merge commits required by git merge.
Second, as you can see in the above diagram, rebasing also results in a perfectly linear project history—you can follow the tip of feature all the way to the beginning of the project without any forks.
This makes it easier to navigate your project with commands like “git log”, “git bisect”, and “gitk”.

Con :
There are two trade-offs for this pristine commit history: safety and traceability.
If you don’t follow the “Golden Rule of Rebasing”, re-writing project history can be potentially catastrophic for your collaboration workflow.
And, less importantly, rebasing loses the context provided by a merge commit—you can’t see when upstream changes were incorporated into the feature.

Golden Rule of Rebasing
***** never use it on “public” branches.
For example, think about what would happen if you rebased master onto your feature branch:

     [ feature ]
          |
          v
-x-x--F-F-F-M*-M*
               ^
               |
           [ master ]

* = brand new commit

The rebase moves all of the commits in master onto the tip of feature.
The problem is that this only happened in your repository.
All of the other developers are still working with the original master.
Since rebasing results in brand new commits, Git will think that your master branch’s history has diverged from everybody else’s.

The only way to synchronize the two “master” branches is to merge them back together, resulting in an extra merge commit and two sets of commits that contain the same changes (the original ones, and the ones from your rebased branch).
Needless to say, this is a very confusing situation.

So, before you run “git rebase”, always ask yourself, “Is anyone else looking at this branch?”
If the answer is yes, take your hands off the keyboard and start thinking about a “non-destructive” way to make your changes (e.g., the “git revert” command).
Otherwise, you’re safe to re-write history as much as you like.

More information including “Force-Pushing”, “Workflow Walkthrough” at

https://www.atlassian.com/git/tutorials/merging-vs-rebasing

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s