Git pull: what happens when and why?
What happens when you git pull?
Git pull does a fetch and then a merge. git fetch updates your repo bringing in new git repo objects, updates origin/master. git fetch does not change your working directory or local branches at all. git merge merges the shared-repo origin/master into your local master branch, possibly with conflicts. git can fast-forward your master branch if nobody has changed the same files or if you use stash.
Cases:
- All of your changes are in files other people have not changed.
- Result: you can usually just pull with no concern or interference.
- No stash, no commit, no asking for merge-commit messages. simple fast-forward.
- Some of your changes are in files other changed, but not at the same places. [NO merge-conflict]
- (A separation of a few lines between your changes and others changes is usually enough.)
- Result: you must stash or commit.
- If you stash, then it fast-forwards -- NOT asking for a merge commit message.
- If you commit, it will ask for a merge commit message even though there are no conflicts.
- (This is the case which changed a few years ago when Linus Torvalds decided that users should at be nagged for an explanation of why they are merging other branches into their current development branch.)
- Some of your changes are in files at the same places other changed. [merge-conflict]
- Result: You must stash or commit. You will have merge-conflicts.
- If you stash, then fast-forwards without asking for a merge commit message.
- When you git stash pop, it will have conflicts in files that must be resolved with your editor. No commit is required.
- If you commit, it will have conflicts in files that must be resolved with your editor.
- You must follow it up with git add for each resolved file, and then finish with a final merge commit with a message.
So, git stash works great when you have a small number of changes and will hopefully be committing them before long anyways. You should try to do your git stash pop immediately after doing the git pull so that the changes are fresh in your mind, you can fix any conflicts, and so you will not forget they are on the stash and start working on other stuff.
If something is ready, go ahead and commit and push it.
If something is going to take a while, put it on a development branch. git makes this fairly easy.
The place where git stash can go wrong is when you have more than one stash building up. Either you forgot you had stuff on your stash stack, now you have even more uncommitted stuff. You might get away with stashing multiple times, but it seems like bad practice and you run the risk of losing or messing up your changes. If you start to have multiple stashes AND multiple development branches, it can be complicated and confusing.
So a little git stash followed immediately by pull and pop is just fine. But don't try to get elaborate with your git stashing. Needing multiple stashes is a clear sign that you should be using local dev branches.
git pull --rebase
Another way to handle merges that may or may not have conflicts is to commit your changes as usual, and then run "git pull --rebase" instead of just "git pull".
git pull --rebase does the following:
- temporarily "rewinds" your tree, i.e. undoes your recent commits so that your tree is in the same state as the last time you did a git pull
- fast-forwards your tree with everybody else's changes since that time
- re-applies your recent commits
When git re-applies your commits on the updated tree, there may be merge conflicts that you then resolve as usual -- but the conflicts arise one commit at a time (one of your commits) instead of for all of your commits at once. This process also gets rid of the "Merge branch 'master' of hgwdev.cse.ucsc.edu:/data/git/kent" commits in the git history.
git stash is still useful for setting aside changes-in-progress for a short time.