How to use Git Stashing and Cleaning to save and trash changes

How to use Git Stashing and Cleaning to save and trash changes

git-stashing-cleaning

Here in this article we will how we can use the Git Stashing and Cleaning utilities to save our work instead of commiting it and trash the unnecessary files in the working directory respectively.

Test Environment

Fedora 37 workstation
Git v2.40.0

What is Stashing

Stashing is a way to capture the unfinished work in your current working directory with modified tracked files and any work that you have staged but not yet committed. This work is captured and saved as a stack of unfinished work which can later be fetched and re-applied at any time even on a different branch.

What is Cleaning

Cleaning is used to remove all the untracked files from your current working directory. These are the files that you feel all not required to stashed and later used.

Procedure

Step1: Create and Stage Content

Currently i am working on the main branch. Let us try to modify some content as shown below and stage some files in the .git repository.

admin@fedser learngit]$ echo "some messy license introduced" >> license.md 
[admin@fedser learngit]$ echo "some messy readme introduced" >> readme.md 
[admin@fedser learngit]$ git add readme.md 

Now let us look at the current working directory status as shown below and it will contain some unstaged files and some files staged and ready to be commited.

[admin@fedser learngit]$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   readme.md

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:   license.md

Step2: Stash Work

Now let us try to save our modified tracked files and staged files onto stack using “git stash” as shown below.

[admin@fedser learngit]$ git stash
Saved working directory and index state WIP on main: d3eb76c Merge pull request #1 from novicejava1/edition1

Now if we look at the current status of our .git repoistory its going to be clean.

[admin@fedser learngit]$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Step3: List the Stash

We can list the Stash’s that are stored on the stack using the below command. You can see from the output that our stash is stored on stack and can be references using “stash@{0}”.

[admin@fedser learngit]$ git stash list
stash@{0}: WIP on main: d3eb76c Merge pull request #1 from novicejava1/edition1

Step4: Apply Stack in main branch

Let us now try to apply the stash. By default Git applies the latest stash that was created on the stack if the stash reference is not provided as shown below. Please note here we need to pass the “–index” option also so that staged content is also restored as shown below.

[admin@fedser learngit]$ git stash apply stash@{0} --index
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   readme.md

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:   license.md

If you look at the status our current working directory you can see the modified tracked file yet to be staged as it was in the status before we created the stash along with the staged files as it was staged in the main branch and is specific to that branch.

Please ensure to stash the current state of this branch before switching over to aother branch as shown below.

[admin@fedser learngit]$ git stash
Saved working directory and index state WIP on main: d3eb76c Merge pull request #1 from novicejava1/edition1

[admin@fedser learngit]$ git status
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Step5: Apply stash in edition1 branch

Let us now switch to edition1 branch apply the same stash that we applied in main branch.

[admin@fedser learngit]$ git switch edition1
Switched to branch 'edition1'
Your branch is up to date with 'origin/edition1'.

[admin@fedser learngit]$ git stash list
stash@{0}: WIP on main: d3eb76c Merge pull request #1 from novicejava1/edition1
stash@{1}: WIP on main: d3eb76c Merge pull request #1 from novicejava1/edition1

Now we can apply the same stash in edition1 branch without any issues.

[admin@fedser learngit]$ git stash apply stash@{0} --index
On branch edition1
Your branch is up to date with 'origin/edition1'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   readme.md

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:   license.md

Step6: Create Junk

Let us create some junk.txt files as shown below which is of no use.

[admin@fedser learngit]$ echo "This is a junky file" > junck.txt
[admin@fedser learngit]$ echo "This is a junky file" > junck1.txt
[admin@fedser learngit]$ echo "This is a junky file" > junck2.txt
[admin@fedser learngit]$ echo "This is a junky file" > junck3.txt
[admin@fedser learngit]$ git status
On branch edition1
Your branch is up to date with 'origin/edition1'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   readme.md

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:   license.md

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	junck.txt
	junck1.txt
	junck2.txt
	junck3.txt

If you have decided at some point in time that these junk*.txt files are of no use and not required to be stashed you can straight away remove all of them in one stretch using the “git clean” utility.

But before running this utility, please do a dry-run using the following command to check what all files will be removed from your working directory to ensure that its not going to remove some of your important files.

[admin@fedser learngit]$ git clean --dry-run
Would remove junck.txt
Would remove junck1.txt
Would remove junck2.txt
Would remove junck3.txt

Once you are satisfied that files in the output are not required. You can go ahead and go the actual cleanup. By default, the git clean command will only remove untracked files that are not ignored.

This is the interactive way to double ensure that the files that you are going to remove are no longer need. There is no way to retrieve these files as they are untracked.

[admin@fedser learngit]$ git clean -f -i
Would remove the following items:
  junck.txt   junck1.txt  junck2.txt  junck3.txt
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers    4: ask each             5: quit                 6: help
What now> 1
Removing junck.txt
Removing junck1.txt
Removing junck2.txt
Removing junck3.txt

If you dont pass the “-i” option its going to remove the files without any asking.

Hope you enjoyed reading this article. Thank you..