Chapter 5. Work With Branches

Stash Changes – Git Stash

Stash Changes – Git Stash
Tag:

git stash is used to separately manage work-in-progress (WIP) codes. When you want to switch the current branch in the middle of editing the Working Tree and INDEX, the edits can prevent you from switching the current branch (refer to the git checkout page). In that case, the git stash command is useful. The stashed lines of code are parked somewhere temporarily and make the Working Tree and INDEX clean (the Working Tree and INDEX statuses become the same as the HEAD status) so that you can switch branches.

Key Git Stash Commands

  • git stash: stash the Working Tree and INDEX
  • git stash save "[stash message]": stash the Working Tree and INDEX with a stash message
  • git stash list: list up stashed items
  • git stash apply [stash number]: restore a stashed item
  • git stash pop [stash number]: restore a stashed item and delete it from the stash list
  • git stash drop [stash number]: delete a stashed item
  • git stash clear: delete all the stashed items

For a better understanding, please go through the following practice section.

bloovee-round-icon.pngDeveloper A (Project Owner Role)

Practice

Objective:
Learn how to use the git stash commands

1. Prepare a practice directory and file

Create a new practice directory and file

For this practice, we create a new directory and file.

  • Practice project directory: git_branch_stash_practice
  • Practice file: git_branch_stash_practice.html

We create the practice directory under the main project directory (e.g., Dev_A_bloovee). Run the commands below to create the directory and file.

Command Line - INPUT
cd ~/Dev_A_bloovee
mkdir git_branch_stash_practice
cd git_branch_stash_practice
touch git_branch_stash_practice.html

Edit the practice HTML file (master and Branch_A)

For the master branch

Open the git_branch_stash_practice.html file with a text editor and make the following edits.

git_branch_stash_practice.html (master)
<!doctype html>
<html lang="en">
<body>
<!-- Master Branch-->
<h1>M1</h1>
<!-- /Master Branch-->

<!-- Branch A-->
N/A
<!-- /Branch A-->

<!-- Branch B-->
N/A
<!-- /Branch B-->
</body>

After saving the file, commit the file with "M1" as a commit message. Run the following command to execute.

As we haven't initiated Git in the new project directory, run the git init command first.

Command Line - INPUT
git init
git add .
git commit -m "M1"
For Branch_A

Create and checkout to Branch_A.

Command Line - INPUT
git checkout -b Branch_A
Command Line - RESPONSE
Switched to new branch 'Branch_A'

To make another version of the project file, edit the HTML file.

git_branch_stash_practice.html (Branch_A)
<!-- Branch A-->
<h1>A1</h1>
<!-- /Branch A-->

After saving the file, commit the file and check the log.

Command Line - INPUT
git commit -am "A1"
git log --oneline

You can see that a new commit has been created on Branch_A.

Command Line - RESPONSE
[Branch_A 466f3af] A1
 1 file changed, 1 insertion(+), 1 deletion(-)
466f3af (HEAD -> Branch_A) A1
9d2bd84 (master) M1

You can also clone this repository to create the above practice directory and file (Demo Code link).


2. Make WIP code

To test the git stash command, edit the file on the master branch shown below and save the file, but do not commit it. Switch to the master branch.

Command Line - INPUT
git checkout master

Edit the file by adding <h1>M2</h1>.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<!-- /Master Branch-->

<!-- Branch_A-->
N/A
<!-- /Branch_A-->

At this stage, the Working Tree is already ahead of the HEAD (the latest commit) of the master branch. As explained, you cannot switch to Branch_A. You can confirm it by running the git checkout command.

Command Line - INPUT
git checkout Branch_A

You'll get an error message like the one below.

Command Line - RESPONSE
error: Your local changes to the following files would be overwritten by checkout:
        git_branch_stash_practice.html
Please commit your changes or stash them before you switch branches.
Aborting

The command line response suggests two options before you switch branches.

  • Commit the changes
  • Stash the changes

3. Run the stash command: $ git stash

First, test the git stash command.

Command Line - INPUT
git stash

You'll see the following message.

Command Line - RESPONSE
Saved working directory and index state WIP on master: 462ee77 M1

When you run the stash command, the editing file in the Working Tree is reverted to HEAD (the latest commit).

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<!-- /Master Branch-->

Now you can switch to Branch_A like shown below.

Command Line - INPUT
git checkout Branch_A

You'll see the following message.

Command Line - RESPONSE
Switched to branch 'Branch_A'

4. Check the stash status: $ git stash list

To check the list of stashed items, run the git stash list command.

Command Line - INPUT
git stash list

You can see that one item is stashed. stash@{0} is a stash number that is used when you restore the stashed item.

Command Line - RESPONSE
stash@{0}: WIP on master: 462ee77 M1

5. Restore a stashed item: $ git stash apply or $ git stash pop

To restore a stashed item, you have two options.

Option 1: $ git stash apply

The git stash apply command simply restores the stashed item.

Option 2: $ git stash pop

When you run the git stash pop command, it restores the stashed item and deletes the stashed item from the stashed list.

In this practice, we use the git stash apply command. You can run the command with or without a stash number. If you don't put in the stash number, the latest stash is restored. Before running the command, switch back to the master branch first to see the simplest case.

Note: You can restore the stashed items to other branches, however, this may create a conflict.)

Command Line - INPUT
git checkout master
git stash apply

You can see that the file status is back to the one before you run the stash command as shown below.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<!-- /Master Branch-->

On the command line, you can see a message like the one below. This is the same response you get when you run the git status command.

Command Line - RESPONSE
On branch master
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:   git_branch_stash_practice.html

no changes added to commit (use "git add" and/or "git commit -a")

6. Delete a stashed item: $ git stash drop or $ git clear

When you don't need the stashed item anymore, you can delete it. To delete one stashed item, you can use git stash drop [stash number]. If you want to clear all the stashed items, you can use git stash clear. In this practice, we use git stash drop. If you don't specify a stash number, the command deletes the latest stash.

Command Line - INPUT
git stash drop

You'll see a message like below.

Command Line - RESPONSE
Dropped refs/stash@{0} (887b349943b8fddd3798cb7fb5e714bf4e1e1ebd))

7. Manage multiple stash items

When you create multiple stashed items, you may be confused about what each stash number means. To avoid confusion, you can add a simple stash message when you stash changes by running the git stash save "[stash message]" command.

Command Line - INPUT
git stash save "M2"

You'll see a message like below.

Command Line - RESPONSE
Saved working directory and index state On master: M2

As you stashed, the Working Tree is cleared as shown below.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<!-- /Master Branch-->

Create other stashed items

Edit the HTML file again by adding <h1>M3</h1> this time.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<h1>M3</h1>
<!-- /Master Branch-->

After saving the file, run the git stash save command with a stash message of "M3".

Command Line - INPUT
git stash save "M3"

Repeat the same process for M4 and M5. And check the stash list.

Command Line - INPUT
git stash list

You can see that the four stashed items are created as shown below.

Command Line - RESPONSE
stash@{0}: On master: M5
stash@{1}: On master: M4
stash@{2}: On master: M3
stash@{3}: On master: M2

The stash message is useful especially when you delete stashed items as stash numbers can change when you delete stashed items. Try the following commands to see the result.

Command Line - INPUT
git stash drop
git stash list

You can see that stash@{0} now refers to M4 while it was previously referred to as M5.

Command Line - RESPONSE
Dropped refs/stash@{0} (4b5d38036ccdf8a0e0284255b5de9a53882e0d63)
stash@{0}: On master: M4
stash@{1}: On master: M3
stash@{2}: On master: M2

git stash is used to separately manage work-in-progress (WIP) codes. When you want to switch the current branch in the middle of editing the Working Tree and INDEX, the edits can prevent you from switching the current branch (refer to the git checkout page). In that case, the git stash command is useful. The stashed lines of code are parked somewhere temporarily and make the Working Tree and INDEX clean (the Working Tree and INDEX statuses become the same as the HEAD status) so that you can switch branches.

Key Git Stash Commands

  • git stash: stash the Working Tree and INDEX
  • git stash save "[stash message]": stash the Working Tree and INDEX with a stash message
  • git stash list: list up stashed items
  • git stash apply [stash number]: restore a stashed item
  • git stash pop [stash number]: restore a stashed item and delete it from the stash list
  • git stash drop [stash number]: delete a stashed item
  • git stash clear: delete all the stashed items

For a better understanding, please go through the following practice section.

bloovee-round-icon.pngDeveloper A (Project Owner Role)

Practice

Objective:
Learn how to use the git stash commands

1. Prepare a practice directory and file

Create a new practice directory and file

For this practice, we create a new directory and file.

  • Practice project directory: git_branch_stash_practice
  • Practice file: git_branch_stash_practice.html

We create the practice directory under the main project directory (e.g., Dev_A_bloovee). Run the commands below to create the directory and file.

Command Line - INPUT
cd ~/Dev_A_bloovee
mkdir git_branch_stash_practice
cd git_branch_stash_practice
touch git_branch_stash_practice.html

Edit the practice HTML file (master and Branch_A)

For the master branch

Open the git_branch_stash_practice.html file with a text editor and make the following edits.

git_branch_stash_practice.html (master)
<!doctype html>
<html lang="en">
<body>
<!-- Master Branch-->
<h1>M1</h1>
<!-- /Master Branch-->

<!-- Branch A-->
N/A
<!-- /Branch A-->

<!-- Branch B-->
N/A
<!-- /Branch B-->
</body>

After saving the file, commit the file with "M1" as a commit message. Run the following command to execute.

As we haven't initiated Git in the new project directory, run the git init command first.

Command Line - INPUT
git init
git add .
git commit -m "M1"
For Branch_A

Create and checkout to Branch_A.

Command Line - INPUT
git checkout -b Branch_A
Command Line - RESPONSE
Switched to new branch 'Branch_A'

To make another version of the project file, edit the HTML file.

git_branch_stash_practice.html (Branch_A)
<!-- Branch A-->
<h1>A1</h1>
<!-- /Branch A-->

After saving the file, commit the file and check the log.

Command Line - INPUT
git commit -am "A1"
git log --oneline

You can see that a new commit has been created on Branch_A.

Command Line - RESPONSE
[Branch_A 466f3af] A1
 1 file changed, 1 insertion(+), 1 deletion(-)
466f3af (HEAD -> Branch_A) A1
9d2bd84 (master) M1

You can also clone this repository to create the above practice directory and file (Demo Code link).


2. Make WIP code

To test the git stash command, edit the file on the master branch shown below and save the file, but do not commit it. Switch to the master branch.

Command Line - INPUT
git checkout master

Edit the file by adding <h1>M2</h1>.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<!-- /Master Branch-->

<!-- Branch_A-->
N/A
<!-- /Branch_A-->

At this stage, the Working Tree is already ahead of the HEAD (the latest commit) of the master branch. As explained, you cannot switch to Branch_A. You can confirm it by running the git checkout command.

Command Line - INPUT
git checkout Branch_A

You'll get an error message like the one below.

Command Line - RESPONSE
error: Your local changes to the following files would be overwritten by checkout:
        git_branch_stash_practice.html
Please commit your changes or stash them before you switch branches.
Aborting

The command line response suggests two options before you switch branches.

  • Commit the changes
  • Stash the changes

3. Run the stash command: $ git stash

First, test the git stash command.

Command Line - INPUT
git stash

You'll see the following message.

Command Line - RESPONSE
Saved working directory and index state WIP on master: 462ee77 M1

When you run the stash command, the editing file in the Working Tree is reverted to HEAD (the latest commit).

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<!-- /Master Branch-->

Now you can switch to Branch_A like shown below.

Command Line - INPUT
git checkout Branch_A

You'll see the following message.

Command Line - RESPONSE
Switched to branch 'Branch_A'

4. Check the stash status: $ git stash list

To check the list of stashed items, run the git stash list command.

Command Line - INPUT
git stash list

You can see that one item is stashed. stash@{0} is a stash number that is used when you restore the stashed item.

Command Line - RESPONSE
stash@{0}: WIP on master: 462ee77 M1

5. Restore a stashed item: $ git stash apply or $ git stash pop

To restore a stashed item, you have two options.

Option 1: $ git stash apply

The git stash apply command simply restores the stashed item.

Option 2: $ git stash pop

When you run the git stash pop command, it restores the stashed item and deletes the stashed item from the stashed list.

In this practice, we use the git stash apply command. You can run the command with or without a stash number. If you don't put in the stash number, the latest stash is restored. Before running the command, switch back to the master branch first to see the simplest case.

Note: You can restore the stashed items to other branches, however, this may create a conflict.)

Command Line - INPUT
git checkout master
git stash apply

You can see that the file status is back to the one before you run the stash command as shown below.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<h1>M2</h1>
<!-- /Master Branch-->

On the command line, you can see a message like the one below. This is the same response you get when you run the git status command.

Command Line - RESPONSE
On branch master
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:   git_branch_stash_practice.html

no changes added to commit (use "git add" and/or "git commit -a")

6. Delete a stashed item: $ git stash drop or $ git clear

When you don't need the stashed item anymore, you can delete it. To delete one stashed item, you can use git stash drop [stash number]. If you want to clear all the stashed items, you can use git stash clear. In this practice, we use git stash drop. If you don't specify a stash number, the command deletes the latest stash.

Command Line - INPUT
git stash drop

You'll see a message like below.

Command Line - RESPONSE
Dropped refs/stash@{0} (887b349943b8fddd3798cb7fb5e714bf4e1e1ebd))

7. Manage multiple stash items

When you create multiple stashed items, you may be confused about what each stash number means. To avoid confusion, you can add a simple stash message when you stash changes by running the git stash save "[stash message]" command.

Command Line - INPUT
git stash save "M2"

You'll see a message like below.

Command Line - RESPONSE
Saved working directory and index state On master: M2

As you stashed, the Working Tree is cleared as shown below.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<!-- /Master Branch-->

Create other stashed items

Edit the HTML file again by adding <h1>M3</h1> this time.

git_branch_stash_practice.html (master)
<!-- Master Branch-->
<h1>M1</h1>
<h1>M3</h1>
<!-- /Master Branch-->

After saving the file, run the git stash save command with a stash message of "M3".

Command Line - INPUT
git stash save "M3"

Repeat the same process for M4 and M5. And check the stash list.

Command Line - INPUT
git stash list

You can see that the four stashed items are created as shown below.

Command Line - RESPONSE
stash@{0}: On master: M5
stash@{1}: On master: M4
stash@{2}: On master: M3
stash@{3}: On master: M2

The stash message is useful especially when you delete stashed items as stash numbers can change when you delete stashed items. Try the following commands to see the result.

Command Line - INPUT
git stash drop
git stash list

You can see that stash@{0} now refers to M4 while it was previously referred to as M5.

Command Line - RESPONSE
Dropped refs/stash@{0} (4b5d38036ccdf8a0e0284255b5de9a53882e0d63)
stash@{0}: On master: M4
stash@{1}: On master: M3
stash@{2}: On master: M2
Tag: