30

I am collaboratively working on a project with someone, so we decided to use git. Unfortunately, we frequently code in locations with no internet, so we end up with something like this:

origin/master: A---B---C
                        \
mylocalmaster:           D---E---F
                        \
hismaster:               G---H---I

Now, say he pushes his commits and gets this:

origin/master: A---B---C---G---H---I
                        \
master (local):          D---E---F

All I want to do is push my commits to get this in both my local repo and the online one:

A---B---C---D---E---F---G---H---I

It seems to work when I do git push, but the trouble arises when I do git fetch and then git merge. All I'm trying to do is get his commits into my local repo, but I end up with a merge commit saying something like Merge remote-tracking branch 'origin/master' as its message.

I don't want to have this pointless commit, since there is no conflicting code in our commits. We are working on completely different files, so there's no reason to have this commit. How can I prevent git from creating this merge commit?

AlexMA
  • 9,842
  • 7
  • 42
  • 64
Alexis King
  • 43,109
  • 15
  • 131
  • 205
  • 1
    When you do a git push in that situation you should be getting an error. It should not seem to work fine. – bames53 Apr 14 '12 at 22:08
  • Since I arrived at this page trying to learn how to *force* git to create a merge commit without any file changes, I'll mention here that the answer to that is the `git commit-tree` command. See `man git-commit-tree`. – Wildcard Sep 09 '16 at 23:32
  • @Wildcard Out of curiosity, in what situation would you want to create a merge commit that `git merge --no-ff` wouldn’t solve? – Alexis King Sep 10 '16 at 00:19
  • @AlexisKing, a feature branch the history of which you don't want to lose, but the "meat" of which has already been rebased and merged in the past. You can keep the feature branch around forever, or you can "merge" it again—while ensuring it doesn't change the working code you already have, which *includes* the feature. – Wildcard Sep 10 '16 at 02:05

2 Answers2

32

You can omit creating merge commits, by using rebase instead of merge.

As @Dougal said, if you do git fetch, you can execute git rebase afterwards to change the base of your changes to the fetched HEAD.

Usually you create those unwanted merge commits, by pulling from remote repository. In that case you can add --rebase option:

git pull --rebase

or add the proper option to Git config file (locally):

git config branch.<branch-name-here>.rebase true

or for all the new repositories and branches:

git config branch.autosetuprebase always --global

However, rebasing creates cleaner, more linear history it is good to create merge commits, where there are massive changes in both branches (use git merge to do so).

Rafał Rawicki
  • 22,324
  • 5
  • 59
  • 79
  • 1
    And the answer for your first question - why? Merge commits are created by default to avoid confusion for Git newcomers, because this is the conceptually simpler situation and people expect to have merge commits when they merge. – Rafał Rawicki Apr 14 '12 at 22:13
  • 3
    I don't want to create these commits because I'm not merging anything. If I let git create a million of these commits which do nothing, it'll just clog up my commit history for no reason. – Alexis King Apr 14 '12 at 22:19
  • 6
    Well, actually merge commits are required in this case because of git's data model. A commit hash includes knowledge about all its parent commits. This, once you change one commit in the row of commits, all following commits get a new hash -- they become different from what they originally were. The merge commit takes the unchanged commits and references both lines (hence it has two parents). If you rebase, you change your commits to directly reference the remote commits as their parents. This has nothing to do with the actual diffs, but only with history tracking. – Holger Just Apr 14 '12 at 22:20
  • @JakeKing you can skip creating these commits, by following solutions from my answer. Is there something I can clarify? – Rafał Rawicki Apr 14 '12 at 22:24
  • No, no, I agree with you. I was just clarifying why I want to do this in the first place. – Alexis King Apr 14 '12 at 22:49
  • There is an addition benefit to rebasing over merging that often isn't mentioned, and that is that bisecting works out better. If you merge, then bisect will walk both merged branches, which is not something that you often want to do since one (your development branch) often contains intermediate states of the code (and I even check in code that doesn't compile, just so that I have backed it up to the server before going home). – David Neiss Aug 15 '16 at 19:59
9

Use git rebase (after a git fetch) to make your commits apply against his rather than against the previous master. That is, to go to ABCGHIDEF in your example. (You can't do ABCDEFGHI without having to do a push -f, because ABCGHI is already in origin/master and you'd have to override that.)

Danica
  • 28,423
  • 6
  • 90
  • 122