When I am using Git, should I rebase before I merge?

16,367

Solution 1

OK, this is too long for a comment now.

To paraphrase the manual (git help rebase)

   Assume the following history exists and the current branch is "new_feature":

                 A---B---C new_feature
                /
           D---E---F---G develop


   From this point, the result of either of the following commands:

       git rebase develop
       git rebase develop new_feature

   would be:

                         A'--B'--C' <new_feature
                        /
           D---E---F---G <develop

Now, if you had conflicts, the actual state after first running rebase will be

              A'--B'--C'--[local state]
             /        ^
D---E---F---G          new_feature
            ^ develop

where [local state] is the conflicted merge you have yet to fix. Once you've resolved the merge conflicts and added the resolved files to the index, you run git rebase --continue: now your state will be

              A'--B'--C'--H <new_feature
             /
D---E---F---G <develop

Obviously at this point merging new_feature back onto develop can be fast-forwarded like so:

              A'--B'--C'--H <new_feature  <develop
             /
D---E---F---G

but if it isn't you'll get this instead

              A'--B'--C'--H <new_feature
             /             \
D---E---F---G---------------I <develop

Now whichever of these you prefer from a timeline perspective, it isn't obvious why either would have a problem ... unless you never completed the rebase and resolved the conflicts with H, but I would think git would complain about that.

Solution 2

Sounds to me like you are using rebase backwards but it might be just a confusing phrasing.

I'd rebase the feature branch onto develop and then (on develop) do a git merge --ff-only feature.

Share:
16,367

Related videos on Youtube

Code Junkie
Author by

Code Junkie

Updated on June 25, 2022

Comments

  • Code Junkie
    Code Junkie almost 2 years

    I am working on a large scale Rails project, and the team I am working with is using Github to manage the project. While many changes are worked on locally and then pushed directly to our development branch, we create a branch when we are going to work on a very large change. When the time comes to merge that branch back into develop, I often try to rebase develop back into my feature branch before I merge my feature branch into develop (to prevent overwriting of other people's work). I find that when I do this, I seem to run into the same merge conflicts twice. I run into a whole list of conflicts while rebasing, then run into the same list of conflicts again while merging. Should I rebase develop into my feature branch before I merge my feature into develop, or should I just merge my feature into develop?

    Let's say my feature branch is called "new_feature". My process for merging it with the "develop" branch goes like this:

    git checkout develop 
    
    git pull (this is set up on our rig to always pull rebase)
    
    git checkout new_feature 
    
    git rebase develop 
    
    (lots of merge conflicts ensue) 
    
    git checkout develop  
    
    git merge -no-ff new_feature 
    
    (same set of merge conflicts again)
    

    It's as if the timeline changes from my rebase cause my new feature branch to kind of mirror develop all the way back, and then develop conflicts with a psudo-copy of itself.

    • Useless
      Useless about 12 years
      why git merge -no-ff? If you just rebased new_feature onto develop, it should be a fast-forward.
    • Useless
      Useless about 12 years
      I can see it might make the timeline confusing ... hmm. The rebase is replacing all the commits on new_feature with equivalent changes applied to develop instead of the original branch point, which means you'll get (copies of) old commits, whose parents (between the original branch point and develop/HEAD) are older than them.
    • Andrew Marshall
      Andrew Marshall about 12 years
      The reasoning behind using --no-ff even when the merge would be a fast-forward is that it logically groups the commits, maintaining the fact that they were in a branch at one point in the history. It is particularly useful when the branch has many commits on them and it makes sense to see that they were all part of the same feature branch as added context.
  • Code Junkie
    Code Junkie about 12 years
    I'm working on editing my post to show the process, to see if I'm getting it wrong.
  • madth3
    madth3 about 12 years
    As @Useless commented, the merge should be a fast-forward (I prefer to force it by using the --ff-only). All the rest seems ok although your way of putting it in words is not the standard. I'd recommend reading progit.org/book
  • Umagon
    Umagon over 6 years
    "but if it isn't you'll get this instead"? "isn't" what? I don't understand how to cause either of these scenarios. What was the difference?
  • Useless
    Useless over 6 years
    "... can be fast-forwarded ... but if it isn't ...". If you choose not to fast-forward the merge, with --no-ff, you get a merge commit instead of just moving the branch pointer, as the diagram shows. If you don't understand either scenario in the first place though, you probably need to ask your own question or otherwise learn more about git, because I can't really guess where this answer lost you.
  • Greg Rynkowski
    Greg Rynkowski over 2 years
    Claiming that "large-scale" and "rebase" are mutually inappropriate is incorrect. No matter how big the project is, when working with feature branches, rebasing them before merging is actually a best practice. What is wrong, are these attempts to rebase develop used by a team, what is a bad practice no matter the size of the project (in the vast majority of cases).