Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'git pull' brings others' commits into my staging area during merge conflict

Tags:

git

So, I have faced this nasty problem quite often, and tried looking for any solutions online, but I am not sure if this is git's expected behavior or not.

Whenever I have a few local commits and I do a git pull, git brings all the other peoples' commits into my staging area in case, I have a merge conflict. Now, although the conflict is on a single file, I do not understand why git brings other peoples' non-conflicting commits into my staging area, asking me to commit them as if they were changes/ commits made by me.

Recently, I had this same behavior on a colleague's laptop, and we unstaged all the files not added by the colleague before committing, and then committed the only file that was conflicting. And what happened, was quite unexpected. Git apparently deleted all those files, undid all the changes, as if our commit reversed them.

However, the strangest thing of all was, we looked in Stash (we use Stash for managing the central repo), and I did not see those files being undone by our commit in Stash.

I am at a loss as how did this happen. Any plausible explanation? Also, I have seen Stash act very weirdly at times. It seems unreliable. It will not show any changes between two commits, and yet there are at times, changes. I have no idea how this happens, but has anyone else experienced these issues?

Update : I realized this later that Stash wasn't weird just a little unintuitive. When doing a merge, it showed changes based on two different parents. And there was a small dropdown that would let you change the parent to see changes corresponding to it. I thought it would be good to update it here so people do not have misleading ideas.

like image 494
Setafire Avatar asked Apr 05 '15 22:04

Setafire


2 Answers

The staged files you are seeing are the results of all the changes between the last time you synchronised your local branch with the remote branch (I guess master as you do not mention it).

Git pull has 'fetched' the changes since you last pulled, then it tries to merge this local copy of the remote branch into your local branch. It then hit a conflict in one of the changed files.

So it has to stop in the middle of the merge to ask you how to resolve the conflict to the one file.

So the other files are ready to merge, have been staged and would have been merged automatically if there hadn't been any other conflicts.

To complete the automatic merge, you need to a) resolve the conflict then b) hit commit to finish merging the other people's changes into your local branch. (Some GUIs automate the commit completion step after you click a "I've finished resolving" button)

You will also notice in the commit window of your GUI, there is a pre-fabricated merge message for the pending commit? It will say something like "merging origin/x into x... Conflicts: y". Once all the changed files can be added to the stage you are ready to complete this automatic commit which was paused.

So this sounds like expected behaviour to me, but you are just seeing "inside" one of git's internal processes.

Stashing shouldn't be necessary or involved here. Although some GUIs do auto-stash, git itself doesn't use stashing during a pull.

Note: you shouldn't have any changed files locally when you do a pull. (i.e. commit everything clean before doing any branch operations, is a good best practice) Having a GUI clean up your changed files is when auto-stash is useful, but it still has its complications when there are conflicts. i.e. you need to resolve the conflicts then remember to pop the stash afterwards. If you rely on the automation too much, it gets confusing when you have to complete the automated process you don't know about! So I'd recommend always keeping your working directory clean.

like image 108
scipilot Avatar answered Oct 21 '22 07:10

scipilot


The default behaviour of git pull is to perform a fetch and then a merge. A merge is an actual, new, commit; normally this is resolved automatically so you see no staged changes. However, in the case of a conflict, the commit cannot be performed automatically, hence the visible staged changes.

like image 3
Oliver Charlesworth Avatar answered Oct 21 '22 07:10

Oliver Charlesworth