Let's consider the scenario below to better understand what happens and which option to use:
--- A --- B --- C --- D --- remotes/origin/master
\
--- E --- F --- master
Let's say you based your work on commit B, and created commits E and F, and in the meantime commits C and D were added to the remote branch. merge
can work in two ways: fast forward and merge commit . Fast forward only works if you did not commit any, which is not the case. In cases where fast forward is possible, there is no difference between using it and rebase.
Merge commit looks like this:
--- A --- B --- C --- D --- remotes/origin/master
\ \
--- E --- F --- M --- master
That is, it creates the M commit, which has two parents: the last commits of your branch and the branch you are doing merge.
The rebase is as follows:
--- A --- B --- C --- D --- remotes/origin/master
\
--- E' --- F' --- master
The main advantage of rebase is that its history remains linear: every commit has a single parent. But note that commits E and F no longer exist in your branch: there are commits E 'and F', which are equivalent to the original and different E's and F's. The main disadvantage is this: let's say you have published your branch in the "meurepo" repository:
--- A --- B --- C --- D --- remotes/origin/master
\
--- E --- F --- master, remotes/meurepo/master
And someone else forked your repository and did something on it:
--- A --- B --- C --- D --- remotes/origin/master
\
--- E --- F --- master, remotes/meurepo/master
\
--- G --- remotes/outrorepo/master
You have now rebase, and added a commit:
--- A --- B --- C --- D --- remotes/origin/master
\ \
\ --- E' --- F' --- H -- master
\
- E --- F --- G --- remotes/outrorepo/master
Now the other person has serious problems. Commits E and F and commits E 'and F' are different, which can cause serious problems for the other person if they attempt to merge. Also, the other person can not rebase as easily as you (it is possible, but it requires you to know exactly where you did the override - trivial above, but not so much in practice). >
Let's see how the merge option is, and I'll include the other person's branch:
--- A --- B --- C --- D --- remotes/origin/master
\ \
--- E --- F --- M -- H -- master, remotes/meurepo/master
\
--- G --- remotes/outrorepo/master
Notice that a commit has now been created. This commit has two parents: D and F. The main disadvantage of this type of operation is precisely this lack of linearity. It's harder to find the exact moment when some problem was introduced in the code (in the example above it looks easy, but think how it gets if everyone does this regularly.)
There are two advantages. The first is that merge is simpler: since the history has been preserved, git already knows that commits E and F are common between remotes / meurepo / master and remotes / outrorepo / master, and can be ignored when checking conflicts.
The other advantage is that it's easier to understand what the people working on the code were thinking. Let's say someone else a bug in H, caused by the interaction of C with E. In the case of merge, it knows that C and E have been developed independently, and so the interaction is unexpected. In the case of rebase, she will think you already knew about the interaction when creating E ', because the story is linear, and will be in doubt whether it was intentional or not.
The rule that seems to me the most recommended is this: as long as you do not publish your branch, you can rebase. Once published, merge. However, rebases are widely used in the Linux community, which is the creator of git, which serves as a counterpoint.