racerX
racerX

Reputation: 1092

Why does git require me to commit or stash local changes before doing a pull

I made a change to a file in my local working copy and the same file has been modified in the remote repo. When I do a git pull, git gives the message, "error: Your local changes to the following files would be overwritten by merge: foo.txt Please commit your changes or stash them before you merge."

I know how to solve this issue, but I am not completely clear why this happens. So, if I do a git pull (which is git fetch followed by git merge), then git will first bring the remote file changes to my local (and hence I lose my local changes) and then do the merge, is this what happens?

Also, in the same scenario, instead of a git pull, I did a git fetch first. This caused no issue, but when I did a git merge, I got the same message from git about losing local changes. So, that means that git fetch does not bring the remote changes to local, only when I try to do the merge is when the local working copy is replaced by the remote changes?

Upvotes: 0

Views: 1321

Answers (1)

torek
torek

Reputation: 488203

As you mention, pull = fetch + merge, more or less.1 The problem here is that git merge works with commits. What's in your working tree are files in the host OS's file system. These files may well have come out of some commit, but they are not in and of themselves a commit. In a very real and important sense, your working tree files are not in Git at all! So git merge won't work with them.

Peculiarly, if you set the second command to be rebase, Git has an "autostash" option where it will stash, rebase, and then un-stash. Git does not have an option to do this with merge, even though it makes just as much sense here. I recommend avoiding git stash due to its many rather awful failure modes, but it actually works quite well most of the time. So if you choose rebase instead of merge, you can run git pull without committing first! Many people like this, and also like the git pull --rebase work-flow. If you find yourself in this camp, consider configuring your git pull to use rebase and your rebase to use autostash (but don't say I didn't warn you when the stash command bites you in some sensitive 😀 anatomical area).


1You get to specify the second step of git pull: it's one of merge or rebase, but you choose which one. There's also a special corner case with fetching into a totally empty repository or orphan branch, where the second step is actually just checkout/switch.

Upvotes: 1

Related Questions