I am trying to provide my own answer here.
I am new to git
. But to me, the one-line describing the command should be revised to this
git-stash - Stash away the tracked changes in a dirty working directory
(untracked changes are ignored)
In other words, git stash
(without the option -u
) would stash #1 and #2 but not #3. And if #1 and #2 are happening to the same file, then #2 will take precedence over #1.
With the option -u
, git stash -u
can include also the untracked files.
See this SO article (link) for more details.
Experiment
The following experiment shows how git stash
(with -u
) handles
the three cases (a based case, file t1.txt
in history) is also included.
Set up four different states
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ echo "Hello" > t1.txt ; git add t1.txt ; git commit -m "Add t1.txt"
[f2 7367b85] Add t1.txt
1 file changed, 1 insertion(+)
create mode 100644 tmp/t1.txt
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ echo "Hello in Index" > t1.txt ; git add t1.txt
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ echo "Hello in Working Directory (tracked)" > t1.txt
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ echo "Bonjour in Working Directory (untracked)" > t2.txt
Examine the four states
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git status
On branch f2
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: t1.txt
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: t1.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
t2.txt
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git diff --cached t1.txt
diff --git a/tmp/t1.txt b/tmp/t1.txt
index e965047..a863c48 100644
--- a/tmp/t1.txt
+++ b/tmp/t1.txt
@@ -1 +1 @@
-Hello
+Hello in Index
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git diff t1.txt
diff --git a/tmp/t1.txt b/tmp/t1.txt
index a863c48..a0c6962 100644
--- a/tmp/t1.txt
+++ b/tmp/t1.txt
@@ -1 +1 @@
-Hello in Index
+Hello in Working Directory (tracked)
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ cat t2.txt
Bonjour in Working Directory (untracked)
Now perform the stash
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git stash
Saved working directory and index state WIP on f2: 7367b85 Add t1.txt
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git status
On branch f2
Untracked files:
(use "git add <file>..." to include in what will be committed)
t2.txt
nothing added to commit but untracked files present (use "git add" to track)
Note that t2.txt was not handled by git stash
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git stash show
tmp/t1.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
If you lost t2.txt; git stash won't be able to restore it for you
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ rm t2.txt
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git stash pop
On branch f2
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: t1.txt
no changes added to commit (use "git add" and/or "git commit -a")
Dropped refs/stash@{0} (6a004ffe723ae18d9d5a314c0f5460622b27e300)
Index vs Tracked (Changes not staged for commit)
By the way, note also that what happened to the state of
#1 "Hello in Index" (of t1.txt in index before `git stash`)
#2 "Hello in Working Directory (tracked)" (of t1.txt in worktree before `git stash`)
#1
was also lost after a pair of git stash
and git stash pop
operations.
What was retained was #2
. In other words, the working directory state has taken precedence in the stash operation.
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ cat t1.txt
Hello in Working Directory (tracked)