1

We generally want to use no-ff merges for feature branches but when synchronizing local repository with the upstream one, we do not want merge commits. I.e., we don't want to see merge commits after pulls.

When I configure Git this way:

git config merge.ff false

then also pulls create commits like "Merge origin/master into master". How to avoid it?

Edit: A bit more explanation:

When I have local feature branches merged into my local master and that has not been pushed yet, then when I do a pull I want to get the merge commit "Merge origin/master into master" because that's a real merge.

However, in a case where I 5 minutes ago made a push, then done nothing and then pulled 5 minutes later, I do not want to get the "Merge origin/master into master" because it's just an empty, useless commit (no real merging was done here).

With the merge.ff being false by default in our project, is there a switch to pull to do what I've described above? Or any other workaround?

Borek Bernard
  • 50,745
  • 59
  • 165
  • 240
  • If the branches are diverged, you need to create a merge commit. If it is about not creating that automatically, is [this](http://stackoverflow.com/questions/5519007/how-do-i-make-git-merges-default-be-no-ff-no-commit) of any help? – martin May 12 '15 at 08:03
  • @martin I'm having this problem: http://stackoverflow.com/a/9252042/21728 and I don't think --rebase solves that (I generally want to avoid rebasing in my flow, expect special cases which pulls are not). – Borek Bernard May 12 '15 at 11:29
  • Thank you for the clarification, I've misread you question. – martin May 12 '15 at 11:31

2 Answers2

1

The way to avoid it is to perform rebase instead of a merge. Assuming you are on master branch, you can do:

git fetch
git rebase origin/master
... solve conflicts if any and finish the rebase
git push

You can set 'git pull' to perform fetch+rebase with:

git config --global branch.autosetuprebase always
Igal S.
  • 13,146
  • 5
  • 30
  • 48
  • Rebase will, well, rebase commits which I don't want. I want this behavior: if my last commin in my local master was pushed (so 5 mins ago I was in sync with the origin) and then do pull which got me some new commits, I don't want to see "Merge origin/master into master" because it's just an empty, useless commit. When I have local commits in master (not pushed yet) and there have been other commits merged into master in the remote, I want to get "Merge origin/master into master" because it was a real merge. Does that make sense? – Borek Bernard May 12 '15 at 11:32
  • I don't think what you want is possible. I hope I will manage to explain. If you don't have local changes, than it is a fast forward and no problem here. But if you do have local changes, and you got more commits from origin, something got to connect them together, this is the "merge commit". Try to think of it in graphical view (gitk for example) - you got 2 commits (yours and from origin) with same parent. Where will the next commit go to? – Igal S. May 12 '15 at 13:16
0

It sounds like you want git pull --rebase. That will only do any rebasing in the scenario you describe, where the local user has made commits that haven't been shared yet with the upstream world.

Avoiding a merge commit and a rebase in this scenario isn't possible, because the two lineages have already diverged. But we advise all our teams to use git pull --rebase precisely because it keeps these useless local merges out of the history.

Ken Williams
  • 22,756
  • 10
  • 85
  • 147