Git: How to save your changes temporarily

August 29, 2020

"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.

  1. git stash -u
  2. git pull --rebase
  3. 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.

On a side note, I extensive use git in the command line. If you are uncomfortable using terminal, there are some git application tools with GUI to help you out. Most likely, they will come with a 'git stash' button on the interface.

Some of the tools I have tried in the past are:

  • (Tower)[https://www.git-tower.com/mac]
  • (SourceTree)[https://www.sourcetreeapp.com/]

Finally, I highly recommend visiting git-stash documentation page, if you want to know more about the different modes of git stash.


Webmentions

Want to respond? Reply, like, reply or bookmark on Twitter :)

0 Likes