git merge or rebase

7

When programming using git, I always use merge of my branch in the master to add new codes, but some graphical tools like smartgit override the merge.

Should I use the command rebase or merge to add my changes to my master branch?

    
asked by anonymous 17.02.2014 / 23:47

2 answers

13

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.

    
18.02.2014 / 18:00
5

It depends in part on your taste.

The merge brings together two separate development lines. It is easier to do and any developer can at any time merge with the "official" repository.

But many project maintainers who use Git do not like merge commits because they are kind of opaque. Each merge commit has two different "parents". The history of the project is no longer linear.

"Rebase" allows you to rewrite the "history" of the repository. Among other things this allows you to reform your commits before being sent to the "official" repository.

This allows to maintain the illusion that the development history is perfectly linear and serial, a commit having only one parent. It makes it much easier, for example, to do a regression test to find that commit has introduced a bug.

For reference, articles I wrote about: Git merge: one legitimate use and a goof and The many faces of git rebase

    
18.02.2014 / 02:10