documentation/blog/2024-01-26-git-stash.md
This article was last updated on January 26, 2024 to add more information, diagram and commands for using git stash.
Stash is a Git command to locally store your recent changes in a separate area so you can fetch those changes later. After taking a snapshot of your local files, it resets the state of your workspace to the previous commit state. You can save multiple stashes on your local computer and you can apply back any of the stashes at a later stage.
Stash is very simple to use. You can run git stash to save your changes and then use git stash apply or git stash pop to bring back those saved changes.
Note that git stash is only applied to locally versioned files, and developers using the same git repository will not be aware of these stash changes.
In this article, we will cover Git stash in detail. We will start with why it is needed, how to use it, what are its best practices and some example commands of Git stash.
Some of the use cases where you will need Git stash are the following:
If you have two branches, let’s say branch A and branch B. A lot of work has been added to both branches, and they have diverged from each other quite a lot. Both have different heads.
If you are working on branch A and you want to make some changes to branch B, then you will have no other choice except to create a commit at that point in branch A, then commit the code and push your changes so that you can fix the bug in branch B. After fixing the bug in branch B, you will switch your active branch to branch A and then run git reset head… to get your changes back.
This is not a very flexible approach because your unfinished work will be considered a checkpoint instead of a patch that is still a work in progress. This is where Git stash comes in. With Git stash, you can save your changes locally without making a commit, switch branches, perform other operations, and then reapply the locally stashed changes when you need them.
You can transition between different tasks without needing to undo or redo the changes.
If more than one team member is working on the same code file and you want to fetch the changes made by other developers, then you will use git pull which will merge other developers' changes into the file.
However, that will only happen if their changes do not conflict with yours. If the incoming modifications are on the same lines you have changed, then using git pull will likely throw an error related to merging error. Git stash comes to the rescue here.
You can easily stash your local changes, pull the modifications made by other developers in the same file, and then you can apply your locally stashed changes to the same file. You might still have to resolve the conflicts manually, though.
Continuing the previous example of branch A and branch B, here is how you will use Git stash to switch between branches while saving your changes locally without making a commit.
git stash. It will preserve your changes locally in the stack.checkout commandgit stash pop to retrieve your stashed changes back.Your changes preserved through git stash are saved in your project’s .git directory, usually, the path is /.git/refs/stash. It is the fastest way to get your working directory clean while still keeping the changes.
Both git commit and git stash take a snapshot of changed files in the git working tree and save that snapshot for later use. However, both are very different from each other in many aspects, such as:
• Commit is a part of the public git history so others can see it. Stash is always local. • The Stash command resets the files in the working tree to a previous commit point. A new commit leaves files in the working tree unmodified. • Commit creates a new save point on your branch, whereas stash reverts to a previous save point.
The git reset command is similar to git stash in the sense that both commands revert the files in the working directory to a previous commit. However, there are many differences, such as:
• A hard reset will wipe out all the changes. A stash will save a snapshot of modified files on the local machine. • Stash does not create a new save point in the branch history because it is only to your local machine. A reset will create a new commit point in the branch history. • As the reset is based on the overall remote repository so you can use reset to jump back to any previous commit. A stash will only reset the files in your local workspace to a previous state.
The command git stage might appear to be the same as git stash because it also stages your changes; however, that is not the case. The git stage is the step prior to the commit. You add new files to the “staged files” so that the next commit contains these files. Stash will move your files back to the stack so that you can bring these files back and see the modifications.
Below illustration will help you understand how Git Stash works.
<div className="centered-image"> </div>Although it is not mandatory to name a stash, you can do that through git stash push -m "stashName" followed by git stash apply stash^{/stashName} . You can also use git stash save stashName however, the save command is deprecated. Note that a simple git stash would work perfectly fine as well.
$ git stash push -m "MyStash1"
Saved working directory and index state On BranchB: MyStash1
By default, the stash command stores uncommitted files and code while leaving any untracked or ignored files.
If you want to stash all your untracked files in the stash stack, then execute the command git stash --include-untracked or the short version git stash -u.
$ git stash --include-untracked
Saved working directory and index state WIP on BranchB: 3d49c837 modify
It is very easy to create a new branch from your latest stash. If you run git stash branch <branchName>, it will create a new branch from the latest stash. You can use the command git stash branch <branch_name> stash@{revision} to generate a new branch from a specific stash.
$ git stash branch branchfromstash
Switched to a new branch 'branchfromstash'
On branch branchfromstash
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (670a2fee6519bcb6a7bedcaf6ef64ac1be3dd9a7)
To get an overview of all your stashed changes, use the git stash list command. This command will display each stash with its corresponding identifier and description. It is a quick way to review all the stashes you have created before deciding which one to apply or remove. Keep in mind that older stashes are pushed down the stack as new ones are created.
Just execute the command git stash list to see the list of current stashes.
$ git stash list
stash@{0}: On BranchB: MyStash1
When you are ready to continue working on your stashed changes, git stash apply is the command you will use. This will reapply the last or specified stash onto your current working directory without removing it from the stash list. It is the safer option if you want to keep the stash for potential use later on another branch or if you are applying to a different context and need to ensure the changes are appropriate.
You can apply the git stash by running the command git stash apply stash^{/MyStash1}.
$ git stash apply stash@{MyStash1}
On branch BranchB
Your branch is up to date with 'origin/BranchB'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
The git stash pop command is used when you want to apply the most recent stashed changes and remove them from the stash list. This is ideal for when you are certain you no longer need the stashed state after reapplying it. This action can be irreversible, so ensure you are popping a stash you definitely won't need again, or that you are willing to resolve any conflicts that may arise on the spot.
Note that git stash pop removes the stash after applying it. git stash apply leaves it in the stash list for later use. The below example will remove the stash after applying it.
$ git stash pop
On branch branchfromstash
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: test.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (37ae3e2690ecafd8c89466fd623ba9ac965dbd35)
Below we are presenting some common pitfalls of using Git Stash and how to handle them.
git stash only stashes changes in the current working directory. If you are working in a multi-directory project, ensure you're in the correct directory when you stash or apply changes.git stash list to view all stashes. Each stash is indexed in a stack-like structure. Familiarize yourself with git stash show to preview changes before applying them.git stash apply cautiously and be prepared to resolve conflicts manually. Consider working with branches for complex changes.git stash drop and losing changes.git fsck and git reflog. However, this is not guaranteed. Always double-check the stash index before dropping a stash.git stash saves new (untracked) files.git stash does not save untracked files. Use git stash -u or git stash --include-untracked to stash untracked files. Remember to commit or stash your changes regularly to avoid losing work.git stash drop <stash@{index}> to remove specific stashes or git stash clear to remove all stashes. Be cautious with these commands, as removed stashes cannot be recovered.Here are some of the best practices you should follow when using Git stash:
Git stash is a convenient command by Git. If used in the right situations, it can be very beneficial. If you switch between your branches frequently and need to safely stage your latest work for a short time, Git stash is for you. Too much usage of the stash is also discouraged as well. If you follow the best practices mentioned above, Git stash will improve your efficiency and result in increased productivity.