115

We're ending up with a lot of commits like this in our repo:

Merge branch 'master' of bitbucket.org:user/repo

This happens every time a developer syncs his/hers local fork to the top-level repo.

Is there anyway to avoid this merge-commit hell from cluttering all the repo log? Can one avoid them when initiating the pull-requests in some way?

I know I can do git rebase if this is done in my local VM only, is there any equivalence in the GitHub/BitBucket UI?

How do you guys do it?

Niklas9
  • 8,008
  • 8
  • 34
  • 55

2 Answers2

163

Rebase Feature Branches Before Merging

If you want to avoid merge commits, you need to ensure all commits are fast-forwards. You do this by making sure your feature branch rebases cleanly onto your line of development before a merge like so:

git checkout master
git checkout -b feature/foo

# make some commits

git rebase master
git checkout master
git merge --ff-only feature/foo

Rebase also has a lot of flags, including interactive rebasing with the -i flag, but you may not need that if you're keeping things as simple as possible and want to preserve all of your branch history on a merge.

Use the --ff-only Flag

Aside from rebasing, the use of the --ff-only flag will ensure that only fast-forward commits are allowed. A commit will not be made if it would be a merge commit instead. The git-merge(1) manual page says:

--ff-only

Refuse to merge and exit with a non-zero status unless the current HEAD is already up-to-date or the merge can be resolved as a fast-forward.

Todd A. Jacobs
  • 76,463
  • 14
  • 137
  • 188
  • 1
    This is a great answer. I use rebase as often as possible. I didn't know about the --ff-only flag though. Pretty cool! – Leo Correa May 03 '13 at 12:24
  • 4
    Thanks for the rebase and --ff-only advices. However, as said in my question, how can I do this within the UI of GitHub/BitBucket? – Niklas9 May 03 '13 at 21:54
  • 3
    @Niklas I'm pretty sure you will need to resort to the CLI to do what you want. GitHub doesn't expose the full power of Git; just a subset of its features plus some graphical and social-networking value-adds. Good luck! – Todd A. Jacobs May 03 '13 at 22:02
  • 3
    One thing to note with this process is that, before merging the topic branch (feature/foo) back into master, you'd better git pull origin master (if using a remote), to ensure the master branch is up-to-date. If updates were found, be sure to once again rebase master onto the topic branch before merging it back into master. – chikamichi Nov 08 '13 at 13:40
  • 24
    @CodeGnome don't call it "resorting" to the CLI...in reality you should be warning about "resorting" to the UI! – yurisich Jan 07 '14 at 15:57
  • Also an interesting on the same topic article: https://www.derekgourlay.com/blog/git-when-to-merge-vs-when-to-rebase/ – phw Jun 28 '17 at 14:12
17

"Todd A. Jacobs" already mentioned "rebase" is the concept here. This is just a more detailed way of doing things.

Let's say you're on the master branch

$ git branch
  * master

You want to make a fix, so create a “fixbranch” which is branched from the master

$ git checkout -b fixbranch

Maybe you would have worked for a couple of days on this branch and had a couple of commits.

The day you wanted to push your commits to central master repo! Checkout master and get the latest changes from the central master repo

$ git checkout master
$ git pull origin master

Rebase your fixbranch with the master to have a clean history and resolve the conflicts if any in the local repo itself.

$ git checkout fixbranch
$ git rebase master

Now fixbranch is uptodate to with the central master, let me merge fixbranch into the master branch

 $ git checkout master
 $ git merge fixbranch

I’m done! let me push local master to the central master

$ git push origin master

https://git-scm.com/book/en/v2/Git-Branching-Rebasing

Kondal Kolipaka
  • 3,281
  • 20
  • 26