Git
In this tutorial we will learn to stash changes in Git.
We use the git stash command when we want to save and not commit the changes we have made in our working directory and return back to it later.
git stash
Example: Lets say you are adding a new feature. And then an urgent need to fix a bug rises. You are not yet ready with the new feature and you have not committed it in your Git repository. So, in this case you can stash the changes and return back to the last committed state of the working directory and fix the bug. Once done you can get back the "new feature" changes from the stash and resume working on it.
When we execute the git stash command we are stashing the changes in our local repository and the stashes are never moved to the repository server.
Following is the status of the git-project we created in the Setting up Git repository tutorial.
$ git status On branch master nothing to commit, working tree clean
And following are the files in the repository.
$ ls -la total 0 drwxr-xr-x 5 yusufshakeel staff 170 Feb 12 19:46 . drwxr-xr-x 28 yusufshakeel staff 952 Feb 14 22:42 .. drwxr-xr-x 14 yusufshakeel staff 476 Feb 16 19:00 .git -rw-r--r-- 1 yusufshakeel staff 0 Feb 12 19:26 index.php drwxr-xr-x 3 yusufshakeel staff 102 Feb 12 19:46 js
Lets make some changes to the index.php file and check the status of the working directory using git status command.
git status
$ git status On branch master Changes not staged for commit: (use "git add ..." to update what will be committed) (use "git checkout -- ..." to discard changes in working directory) modified: index.php no changes added to commit (use "git add" and/or "git commit -a")
Now, lets say we want to revert back to the inital state of the working directory and we don't want to lose the changes done to the index.php file.
In this case we will stash the changes using the git stash command.
$ git stash Saved working directory and index state WIP on master: f066f07 initial commit HEAD is now at f066f07 initial commit
Now all the changes are stashed and we are back to the last commit.
In the above output we see the message ...WIP on master: f066f07 initial commit... which means the changes are stashed on master branch and from the last commit f066f07.
By default, stash are marked as WIP - "Work In Progress" on top of the branch and commit from which we created the stash.
If we now execute the git status command we will get the following.
To create a stash with a message we use the git stash save "message" command where, "message" is what we want to set for the stash.
git stash save "message"
"message"
$ git stash save "new feature"
By default, the git stash command will stash files that are being tracked i.e., already added to the Git repository or are staged i.e., ready for commit.
Files that are ignored (Git Ignore) and files that are newly created and not yet staged are not stashed by git stash command by default.
To stash untracked files we use the git stash -u command.
git stash -u
Lets say we create a new file README inside the project folder and check the status of the repository using git status command.
$ git status On branch master Untracked files: (use "git add ..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track)
If we use git stash command then the new file README will not get stashed as it is untracked and not committed in Git repository.
$ git stash No local changes to save
To stash the new file we have to use the -u option.
-u
$ git stash -u Saved working directory and index state WIP on master: f066f07 initial commit HEAD is now at f066f07 initial commit
To stash all the files (tracked, staged, new files, ignored files) we use the git stash -a command.
git stash -a
To list the stash we use the git stash list command.
git stash list
$ git stash list stash@{0}: WIP on master: f066f07 initial commit stash@{1}: WIP on master: f066f07 initial commit
In the above output we see two stashes and they are marked as stash@{0} and stash@{1}.
If we want to re-apply the most recently created stash we use the git stash pop command.
git stash pop
$ git stash pop Already up-to-date! On branch master Untracked files: (use "git add ..." to include in what will be committed) README nothing added to commit but untracked files present (use "git add" to track) Dropped refs/stash@{0} (af18d2ac781301c4f9a6cd14f21be74083dd0129)
In the above output we can see that the README file that was stashed is now re-applied to the working directory. And the last line Dropped refs/stash@{0} say that stash stash@{0} is removed from the stash list.
To re-apply a specific stash we use the git stash pop stash@{id} command.
git stash pop stash@{id}
$ git stash pop stash@{0}
To delete a specific stash we use the git stash drop stash@{id} command.
git stash drop stash@{id}
$ git stash save "new feature" Saved working directory and index state On master: new feature HEAD is now at f066f07 initial commit $ git stash list stash@{0}: On master: new feature $ git stash drop stash@{0} Dropped stash@{0} (d1b5d4fbabaf246d8436dd038fdca23cc9a90a29)
To delete all stashes we use the following command.
$ git stash clear