7

Say I have two branches

master -- A -   -   -   -   -  - merge
          \                    /
           \- develop -- B -- C

Now if I want to merge it will be a fast forward, but should I do

git checkout develop
git merge master

or

git checkout master
git merge develop

And what if I have possible conflicts

master -- A - D -  -  -  -  -  -merge
          \                   /
           \- develop -- B -- C

Should I now merge in to develop or into master? This is a bit confusing, so a good explanation would be really appreciated

chwi
  • 2,752
  • 2
  • 41
  • 66
  • Are you trying to do something that's based on [this branching model](http://nvie.com/posts/a-successful-git-branching-model/)? – Roman Jul 19 '12 at 14:26
  • Yes, I think so at least :P New at both git and version control you see – chwi Jul 20 '12 at 06:17
  • If you are trying to follow that model, you should never have a situation like the one you described where commit D is in *master* but not in *develop*. All of your work would go into *develop* and hot fixes would be merged into both *master* and *develop*. – Roman Jul 20 '12 at 07:44

2 Answers2

6

Missing Workflow Tasks

First of all, there are a few things missing in your workflow that make it hard to answer your question in a real-world way. For example:

  1. You should always pull from upstream before merging branches. Others may have changed develop or master in ways that you haven't accounted for.

  2. You haven't identified which is your long-lived line of development. One assumes develop, but that's just a guess because you haven't identified what happens to your branches after the merge.

General Best Practices for Rebasing Long-Lived Branches

So, assuming that you've updated your branches ahead of time, and that master and develop are both long-lived branches and that master is the "official" branch for completed code, then you should do something along these lines.

  1. Make a temporary rebasing branch based on develop.

    git checkout -b tmp develop
    
  2. Rebase your work onto master to ensure a clean fast-forward merge. I like to make this an interactive rebase, but do it any way you want. For example:

    git rebase -i master
    
  3. Merge onto master. I prefer to force the merge to be a fast-forward, but you can do whatever suits you.

    git checkout master
    git merge --ff-only tmp
    
  4. Make sure the merged branch pushes cleanly.

    git push origin
    
  5. If all went well, dispose of your temporary branch.

    git branch -d tmp
    
  6. Re-merge master with develop as a merge commit, rather than a fast-forward. This brings your development into line with the master branch for continued work.

    git checkout develop
    git merge master
    git push origin
    

Natural Consequences

Doing this ensures that the history on your master branch is relatively linear and free from merge conflicts, and still allows you to rebase when needed without screwing up published branches. This is all positive stuff.

However, this process can leave develop with a complex merge history since the re-merging from master to develop may not always be a fast-forward merge. This isn't a problem, per se, it's just a natural consequence of any workflow that includes rebasing. It's something to be aware of, but in my opinion it's a price worth paying for the flexibility it offers the team.

Todd A. Jacobs
  • 81,402
  • 15
  • 141
  • 199
3

do the second, merge while in master.

I typically rebase master to origin, the rebase dev to master, then merge. This makes the conflicts appear during the rebase; if you do this, there will be no merge conflicts.

hvgotcodes
  • 118,147
  • 33
  • 203
  • 236
  • At gitimmersion I read that rebasing was not good practice when working on public repos, because it may be confusing for other users. Do I avoid that using your routine? – chwi Jul 19 '12 at 13:25
  • http://gitimmersion.com/lab_34.html : Don’t use rebase … If the branch is public and shared with others. Rewriting publicly shared branches will tend to screw up other members of the team. When the exact history of the commit branch is important (since rebase rewrites the commit history). Given the above guidelines, I tend to use rebase for short-lived, local branches and merge for branches in the public repository. – chwi Jul 19 '12 at 13:28
  • 1
    right, its ok to rebase your dev branch, you would never rebase your master branch – hvgotcodes Jul 19 '12 at 13:36
  • For completeness, note that your first option would really be a no-op, since you would check out `dev` (commit 'C' in your diagram), then merging `master` (commit 'A') would see that 'A' is already in the history of the `dev` branch, so there's nothing to do. If there were additional commits on `master` after 'A', though, that would be different, but then your second option wouldn't be a fast-forward, either... – twalberg Jul 19 '12 at 14:15