8

I'm working with someone on the same branch.

I'm pulling each time after I've made changes to my working directory before I add or commit or push and only sometimes I get the below message. When does it do this and why?

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.

j08691
  • 204,283
  • 31
  • 260
  • 272
akantoword
  • 2,824
  • 8
  • 26
  • 43
  • 2
    Because pull is shorthand for fetch and merge. Unless your merge is fast forward, then you'll need a new commit – Jeff Puckett Jun 13 '16 at 18:50
  • Because the default behavior for `pull` is **terrible** (that's what the **t** stands for in _"git"_). The default behavior really should have been `git pull --ff-only` which safely fast forwards your branch to get it up to date and aborts with a message if a merge commit would be required. See: https://git-scm.com/docs/git-pull#Documentation/git-pull.txt---ff-only – Dem Pilafian Jun 15 '19 at 01:23

5 Answers5

8

Simple answer: git pull is, essentially, a combination of git fetch and then a git merge.

As any merge, if Git finds out fast-forwarding is not possible, a traditional merge is necessary (one more commit with two parents), therefore this process asks for a commit message.

Reference: Git docs for branching and merging

everton
  • 7,579
  • 2
  • 29
  • 42
  • does fast-forwarding just mean that git will place my changes over my colleague's changes as long as there's no conflict? fastforwarding is not possible when there's conflict right? so at that point I have to use rebase AND i have to reconcile the code manually? but what does it mean if i rebase and wasn't require to reconcile anything? – akantoword Jun 13 '16 at 19:49
  • 1
    Yes, fast-forwarding means your branch marker cannot just be moved forward to another branch marker, as they have parallel commits. Merging is not exclusively related to conflicts resolution, in git it basically means one commit has 2+ parent commits. – everton Jun 13 '16 at 19:53
  • As stated by other answers, `git pull --rebase` usually makes things cleaner, avoiding unecessary merges. – everton Jun 13 '16 at 19:54
  • It depends: some ppl like to create a merge commit when integrating a feature branch so it is clearer where the code was integrated – Ricardo Amores Jun 13 '16 at 19:56
  • Yep, it depends on the team workflow. A structured process like gitflow workflow almost forbids fast forwarding and rebases. – everton Jun 13 '16 at 19:57
  • I think listing out the conditions on which git does what will help me, please correct me if I'm wrong - if there is conflict between my colleague and my code, git cannot ff, which means I must make a commit to the merge conflict and resolve the conflict manually. however, I don't see a conflict between my colleague and my code, yet git cannot ff so I've had to make a commit to the merge, but I did NOT have to resolve any conflicts manually. what does this situation mean? – akantoword Jun 13 '16 at 20:04
  • my logic is = if I didn't have to resolve any conflicts manually, then why did I need to make a merge commit? because merge commit should only be forced on me when there is a conflict, right? – akantoword Jun 13 '16 at 20:11
  • 1
    No, merge commit will always come up when you have branches with different commits merging together. Conflicts resolution will come up if these commits have conflicting changes. Merging happens either way. – everton Jun 13 '16 at 20:13
  • One simple rule is: As soon as you commit a change to your local repo and someone else has pushed his/her commit to the origin, you'll be forced to pull and to merge before pushing your own changes. – paiego Aug 22 '18 at 22:50
4

Please use git pull --rebase.

Gaurav Agarwal
  • 14,664
  • 4
  • 29
  • 41
4

Well, as usually with git, that behaviour depends on a couple of things, in this case you are seeing that message because you got some conflicts between your colleague code and yours and it tries to make a merge commit, instead of doing a fast-forward merge.

Lets clear up the previous phrase, and for that we must start from the beginning:

When you are pulling, what you really are doing are two operations in one:

  • get the remote data to your local machine (git fetch)
  • "join" the data you just retrieved to your local branch (git merge origin/master)

To "join" the code you have two possible operations: merge or rebase

When doing a merge, git creates a new special commit. It contains two parents, one for your last local commit and another for the last code of the merged branch. That's why you see a bifurcation in the history line when you create a merge, if you use a GUI client or git log --graph No matter how special it is, it is still a commit, and this it requires a message for it. This is the case you are describing.

However there is another operation you can do to bring the remote data to your local machine: rebase. In that case you'll get the remote data, and then your local commits (the ones that are not yet in the remote location) will be applied in the same order on top of the last commit your fetched. In that case you are not really creating a merge commit, so no message is needed, because the history will be kept linear.

Well, here's the trick: git pull can actually do a rebase if the operation can be completed without any conflict. That's called a fast-forward pull.

You can configure git to use whatever default you want (rebase or merge) or supply the parameters when doing the merge:

git pull --ff, pulls the data and tries to rebase. This operation will abort if there are conflicts

git pull --no-ffalways create a merge, even if there are no conflicts

Here's an SO answer on how to configure git to use fast-forward by default

But take into consideration that even if you have ff by default, the pull operation will fallback to a normal merge if there are conflicts. If you want to force the pull to make a rebase you'll need to do

git pull --rebase

But note that doing this won't make the conflicts disappear, you'll need to fix them anyway ;)

Community
  • 1
  • 1
Ricardo Amores
  • 4,597
  • 1
  • 31
  • 45
  • I'm confused by what a conflict actually is, because I've never had to fix anything manually. I did git pull--rebase and it worked but I didn't have to fix anything – akantoword Jun 13 '16 at 19:47
  • If you got pull --rebase and no error happened then you had no conflicts. when doing git pull if you get the merge msg can depend of your current configuration. Can you edit the answer with the result of git confit --list? Be sure to remove your email from for that listing, for your privacy. – Ricardo Amores Jun 13 '16 at 20:01
0

Git most likely wants you to provide a message for the merge. When the origin has changed from your copy, Git will try and merge it. It wants to provide a commit message, because the act of merging is a commit in of itself.

Ryan
  • 14,392
  • 8
  • 62
  • 102
0

One simple rule is: As soon as you commit a change to your local repo, if someone else has pushed his/her commit to the origin since you last pulled, you'll be forced to pull (fetch/merge) which will require a merge message before pushing your own changes.

paiego
  • 3,619
  • 34
  • 43