0

Ive been getting a error when attempting to merge or pull a branch.

The error (this example from a pull request) is as follows:

MacBook-Pro-2:boilerplate Gene$ git pull origin test_branch
From https://github.com/me/boilerplate
* branch            test_branch     -> FETCH_HEAD

Merge branch 'test_branch' of https://github.com/me/boilerplate into test_branch

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts 
# the commit.
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
~                                                                               
"~/Sites/boilerplate/.git/MERGE_MSG" 7L, 302C

Thing is I definitely entered a commit message.

git commit -am "saving my work"

And this error doesnt give me any option to resolve it or even ctrl+c out. I basically have to close the terminal window and re-open it.

Thing is, once I re-open the terminal, the merge or pull request always seems to succeed, but is not committed. I just commit my changes and its fine. Its mostly just annoying (and a bit nerve wracking for more important merges).

Does anyone know what this may be and how to prevent it?

yevg
  • 1,846
  • 9
  • 34
  • 70

1 Answers1

1

This is not an error message. git pull needs to do a merge and it's asking you to explain why... which is a bit disingenuous to ask of the user, but that's Git for you.

git pull origin test_branch is really git fetch origin plus a git merge origin/test_branch. Git does not talk to remote repositories unless you tell it to, so it has to get a fresh snapshot of what's changed on the remote. It does the fetch to get an update of the state of the remote repository. It stores this in remote tracking branches like origin/test_branch which is where the test_branch branch is on the origin repository.

Before the fetch, your repo might look something like this.

A - B - C - D [origin/test_branch]
             \
              E - F [test_branch]

That means the last time you fetched from origin, its test_branch was at D. Then you did a few local commits.

After the fetch, it might look like this.

A - B - C - D - G - H [origin/test_branch]
             \
              E - F [test_branch]

Somebody else pushed some changes, so your test_branch has diverged from origin's test_branch branch. This has to be merged, so git pull does git merge origin/test_branch. This results in a merge commit, and like any merge, it's asking you to explain why it happened.

A - B - C - D - G - H [origin/test_branch]
             \       \
              E - F - I [test_branch]

You can tell it something like "Synching with the remote".


Do this enough, and you get many merges that are really just bookkeeping.

A - B - C - D - G - H - J - K - L - M [origin/test_branch]
             \       \       \       \
              E - F - I - N - O - P - Q [test_branch]

I, O, and Q are all meaningless. With everybody doing this, the repository can become a big mess. I drew it neatly, but Git doesn't always do so.

There's a better way. git pull --rebase. Instead of a fetch + merge, this is a fetch + rebase. So after the fetch you have this.

A - B - C - D - G - H [origin/test_branch]
             \
              E - F [test_branch]

Instead of doing git merge origin/test_branch it does git rebase origin/test_branch. It rewrites E and F as if they were on top of H all along, giving them new commit IDs.

A - B - C - D - G - H [origin/test_branch]
             \       \
              E - F   E1 - F1 [test_branch]

E and F will eventually be garbage collected, but they'll hang around for a while so if anything goes horribly wrong you can reverse this process.

There's no bookkeeping merges to confuse things. History is nice and linear. It's as if you were working on the latest code all along.

Unlike other uses of rebase this is always safe since it only affects commits you haven't shared with anyone else. You can safely set it so git pull will always rebase in your ~/.gitconfig.

[pull]
        rebase = true

Now git pull origin test_branch will use rebase instead of merge, and you'll have a cleaner history with less bookkeeping.

Schwern
  • 153,029
  • 25
  • 195
  • 336
  • Thank you for your thorough response. I know the example was in reference to a pull request, but what would this message mean in the case of a merge? – yevg Feb 11 '17 at 02:09
  • @yevg `git pull` is not a pull request. A pull request is a Github thing, not Git. What you got *is* a message from a merge, `git pull` is a `git fetch` + `git merge`. – Schwern Feb 11 '17 at 08:06