"Fixed". Please pull master...
This scenario should be very familiar to you.
"You are coding an important feature.
Git status reveals a large number of uncommitted changes.
As you test your feature, the app reports a nasty crash/bug/assertion on a different module. As you are blocked from testing, you reach out to the owner.
The code owner informs you that he pushed a fix a few moments ago."
If you have worked in a team environment, you should at least once experienced the scenario above. I definitely have, especially working on a codebase with 1000 or more daily commits ( we use git as our version control ).
Well, what would you do? The most common step is to pull master to retrieve the fix.
So, you run back to your desk, and execute git pull --rebase
.
I am a fan of git rebase. I think that using rebase makes git history so much cleaner and easier to maintain.
Instead of getting a list of file changes or commits, your terminal reports this error:
❯ git pull
error: cannot pull with rebase: You have unstaged changes.
error: please commit or stash them.
Translation: "You still have work in progress and I don't want to mess up and overwrite your changes. Please commit or temporarily shelve your work."
Since you have uncommitted changes, you can't pull from master. You could commit your changes and move on.
Emphasizing the word: commit - I personally think every commit should
be workable, compilable and maintainable code
( else I would rename git commit
to git save
)
Back to our problem - there is an easier way.
How to pull changes while having uncommitted changes?
Use Git Stash command.
Git Stash excels in these types of scenarios (where you need to pull the latest code changes while not being ready to commit your own changes).
git stash
is a git command that allows you to temporarily shelve
or put aside uncommitted changes.
You are then free to update your local copy.
And can immediately continue where you left off by popping your stash.
Back to our scenario, I would execute git stash with:
git stash -u
The -u sign is optional but I find it very handy. It tells git stash to include new files ( git stash untracked files ).
Now you're left with a clean working tree. Hopefully, git pull --rebase
should be able
to work.
To continue where you left off, use git stash pop
.
git stash pop
This will pop the latest stash to your working directory. And that's it, you have successfully pulled master without committing your local changes with just 3 commands.
- git stash -u
- git pull --rebase
- git stash pop
Automation with "rebase.autostash"
I don't know about you but writing 3 commands every time does get tiring.
So, can "git pull" auto stash and pop pending changes? Yes.
You could create a special git alias that runs all 3 commands in order.
However, since Git version 2.7, a new global config flag ( rebase.autostash ) was introduced that automates stashing. Amazing!
By default, this flag is set to false. Enable it globally by running:
git config --global rebase.autostash true
Now, whenever you run git pull --rebase
, your local changes will automatically be stashed
and popped back. Pretty neat.
Wrap up
Git stash shines in scenarios when you're stuck between pulling master and having a dirty working copy ( especially during moments when your boss comes in and demands that you fix something immediately ).
Paired with rebase.autoStash
, my daily git experience is smooth and easy.
Finally, I highly recommend visiting git-stash documentation page, if you want to know more about the different modes of git stash.