Week 6Day 1 - "My private little stash"
Getting interrupted
We're getting close to the point where we can really start using Git as we originally intended, the team at Tamagoyaki Inc.
are also getting much more acquainted with the operations of both version control and Git in particular.
Unfortunately things don't always go as smoothly as we would like.
The following scenario demonstrates just this.
In the trenches...
"Yeh but Martha, I need you to work on this fix now! Not in five minutes."
"Klaus I'm kinda in the middle of something else yet, and I'm not ready to commit," said Martha, feeling a little concerned.
She was used to Klaus making demands on his time, but she had spent a while working on this particular fix for John and she just wasn't ready to finish up yet.
"You could always use the stash feature."
It was Rob again, it seemed as if this young user had cottoned on to Git quicker than most of the seasoned developers."
Klaus seemed unimpressed, "What the heck does that do?"
"Allows you to move your changes to somewhere else until you are ready to finish them."
"Please Rob," started Martha,
"Can you show me what you mean? Sounds exactly like what I need"
Sometimes you could be in the middle of something when another really important task comes up.
When this happens you are often required to drop everything and carry on with another task.
Often this can be quite difficult.
You may be in a development branch, but unable or unwilling to make a commit at this stage.
So how can we deal with this?
Well, one way of dealing with this situation, and this is not necessarily the best way, is to do the steps outlined below;
- Make a new branch called something like WIP
- Pull changes into this new branch
- Commit changes into WIP branch
- Switch back to the branch we need to work on
- Make our changes and commit them
- Merge in our WIP branch on top with the
--no-commit option
- Delete the WIP branch
- Continue development in our original branch
That may seem like a lot of work.
OK, the benefit is a fairly awesome one, but at the cost of considerable command line hackery to get there.
It would be nice if there was an easy way to do the above, and though someone of you may be screaming something like shell script right about now, you can rest your fingers.
We actually have another tool in the Git toolbox to help us out.
The git stash command is used for exactly these situations.
Let us make a quick example of how to use it in our test repository.
To begin with we are going to make a few changes to the master branch, before we are interrupted.
john@satsuki:~/coderepo$ git checkout master
Already on 'master'
john@satsuki:~/coderepo$ echo "Number strings rule 1234" >> another_file
john@satsuki:~/coderepo$
So now we are interrupted and we have to make some important, and urgent changes to our master branch.
The example that follows is one way that we could use the git stash command to help us out.
john@satsuki:~/coderepo$ git stash
Saved working directory and index state WIP on master: d50ffb2 Merged in zaney
HEAD is now at d50ffb2 Merged in zaney
john@satsuki:~/coderepo$ echo "Some mega important changes" >> newfile1
john@satsuki:~/coderepo$ git commit -a -m 'Important Update'
[master 9cb2af2] Important Update
1 files changed, 1 insertions(+), 0 deletions(-)
john@satsuki:~/coderepo$
So using the git stash command, we have squirrelled all of our developmental changes away into a stash.
Now we have completed the mega important change that just could not wait, we are ready to pull our changes back from the stash.
First let us see just what the stash contains.
john@satsuki:~/coderepo$ git stash list
stash@{0}: WIP on master: d50ffb2 Merged in zaney
john@satsuki:~/coderepo$ git stash show stash@{0}
another_file | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
john@satsuki:~/coderepo$ git stash show stash@{0} -p
diff --git a/another_file b/another_file
index dba885d..b3a5cc5 100644
--- a/another_file
+++ b/another_file
@@ -1 +1,2 @@
New stuff
+Number strings rule 1234
john@satsuki:~/coderepo$
As you can see, the -p option to the git stash show command shows us exactly what is contained in the stash.
We can apply this stash by running the following;
john@satsuki:~/coderepo$ git stash apply stash@{0}
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: another_file
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# my_third_committed_file
# temp_file
no changes added to commit (use "git add" and/or "git commit -a")
john@satsuki:~/coderepo$ git commit -a -m 'Continued Development'
[master 37950f8] Continued Development
1 files changed, 1 insertions(+), 0 deletions(-)
john@satsuki:~/coderepo$ git stash list
stash@{0}: WIP on master: d50ffb2 Merged in zaney
john@satsuki:~/coderepo$
Our stash has been applied to the current branch, in our case master, and we have gone ahead and committed these changes into the repository.
In this case we didn't have anything else to add to the index before we went ahead and committed it.
Interestingly though, our stash still exists.
If we had used the git stash pop command instead of the git stash apply , our stash would have been removed.
Of course we can have multiple stashes in our repository.
For completeness sake, let us learn how to manually remove a stash, and take a look at how our repository looks with our semi-graphical git log
john@satsuki:~/coderepo$ git stash drop stash@{0}
Dropped stash@{0} (193f27172fc0df278105b981815c7718204030d8)
john@satsuki:~/coderepo$ git log --graph --pretty=oneline --all --abbrev-commit --decorate
* 37950f8 (HEAD, master) Continued Development
* 9cb2af2 Important Update
* d50ffb2 Merged in zaney
|\
| * 7cc32db (zaney) Made another awesome change
| * a27d49e Made an awesome change
* | ed2301b Removed third file
* | b119573 Merge branch 'wonderful'
| \
| * | cfbecab (wonderful) Fantastic new feature
| |/
* | 4ac9201 Updated third file
|/
* 9710177 Added another file
* 55fb69f (v2.0) Added two new files
* 4a155e4 Removed a few files
* a022d4d (tag: v1.0b, v1.0a) Messed with a few files
* 9938a0c Finished adding initial files
* 163f061 (v0.9) Made a few changes to first and second files
* cfe23cb My First Ever Commit
john@satsuki:~/coderepo$
So using the git stash drop command, you can see that it is fairly simple to drop a single stash from the list.
|