Currently, I am curious to find out what Git will do for us behind the scene if we run the 'git stash' commands. Below are the logs coming from my experiment.
Reference: Git Book
Preparation
Create a brand new folder and run the 'git init' command.
Step 1:
Create a first commit.
$ echo 'first commit' > first_commit.py
$ git add .
$ git commit -m 'first commit'
[master (root-commit) 540b81b] first commit
1 file changed, 1 insertion(+)
create mode 100644 first_commit.py
Check the git status.
On branch master
nothing to commit, working tree clean
Check the .git tree structure.
$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── branches
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 54
│ │ └── 0b81b6fb3e8a6c8e8de363acf856ba77e6666f (git commit object for the first commit)
│ ├── 5e
│ │ └── c586d228b5ff1e8c845c4ed8c2d01f3a159b24 (git blob object for the first commit)
│ ├── 75
│ │ └── 79acf4e2845113349b344d98e366357bc6d125 (git tree object for the first commit)
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
15 directories, 25 files
Check more info.
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
540b81b6fb3e8a6c8e8de363acf856ba77e6666f
$ git ls-files -s
100644 5ec586d228b5ff1e8c845c4ed8c2d01f3a159b24 0 first_commit.py
$ git log --oneline --decorate --graph --all
* 540b81b (HEAD -> master) first commit
Step 2:
Edit the tracked file.
$ echo 'modify first commit' > first_commit.py
Add a new files and add it to the staging area.
$ echo 'staged data' > staged_data.py
$ git add staged_data.py
Add a new files and keep it untracked.
$ echo 'untracked' > untracked_data.py
Check the git status.
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: staged_data.py
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: first_commit.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked_data.py
Check the .git tree structure.
$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── branches
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ └── master
├── objects
│ ├── 54
│ │ └── 0b81b6fb3e8a6c8e8de363acf856ba77e6666f (git commit object for the first commit)
│ ├── 5e
│ │ └── c586d228b5ff1e8c845c4ed8c2d01f3a159b24 (git blob object for the first commit)
│ ├── 75
│ │ └── 79acf4e2845113349b344d98e366357bc6d125 (git tree object for the first commit)
│ ├── bb
│ │ └── 2310c44ce2dda23a59d6e3397c30947cc14f3f (new file for a git blob object)
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
16 directories, 26 files
Check more info.
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
540b81b6fb3e8a6c8e8de363acf856ba77e6666f
$ git ls-files -s
100644 5ec586d228b5ff1e8c845c4ed8c2d01f3a159b24 0 first_commit.py
100644 bb2310c44ce2dda23a59d6e3397c30947cc14f3f 0 staged_data.py
$ git log --oneline --decorate --graph --all
* 540b81b (HEAD -> master) first commit
Step 3:
Stash the changes. (-u will include the untracked files)
Saved working directory and index state WIP on master: 540b81b first commit
Check the git status.
On branch master
nothing to commit, working tree clean
Check the .git tree structure.
$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── ORIG_HEAD (a new file)
├── branches
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ │ └── master
│ └── stash (a new file)
├── objects
│ ├── 18
│ │ └── 383cf89b3be950d6fa7d3671301f2505f7e7c9 (git commit object for 'index on master')
│ ├── 21
│ │ └── d07d848ea2d2f9493971bf15fffac2543e0e12 (git tree object for 'untracked')
│ ├── 33
│ │ └── 0e45055490c45a14f8676e02dfb737e9e083aa (git blob object for 'WIP on master')
│ ├── 54
│ │ └── 0b81b6fb3e8a6c8e8de363acf856ba77e6666f (git commit object for the first commit)
│ ├── 5a
│ │ └── 72eb2edc5d0da32ff615d210d6fa90c31ed940 (git blob object for 'untracked')
│ ├── 5e
│ │ └── c586d228b5ff1e8c845c4ed8c2d01f3a159b24 (git blob object for the first commit)
│ ├── 63
│ │ └── 7e1b1afb4f209162d8ef7c5836b2d04fc5012f (git commit object for 'WIP on master')
│ ├── 75
│ │ └── 79acf4e2845113349b344d98e366357bc6d125 (git tree object for the first commit)
│ ├── 8b
│ │ └── a9c13efffa57668e0c285b370f6d344a7dd66d (git commit object for 'untracked')
│ ├── 91
│ │ └── 60192d673a0371f335e821d6e4a78bb2bd0f60 (git tree object for 'WIP on master')
│ ├── 9a
│ │ └── eb573ff2d1786e30fee3fc5837d3d7a713c565 (git tree object for 'index on master')
│ ├── bb
│ │ └── 2310c44ce2dda23a59d6e3397c30947cc14f3f (new file for a git blob object)
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
├── stash (a new file)
└── tags
24 directories, 37 files
Check the HEAD pointer and branch pointers info.
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
540b81b6fb3e8a6c8e8de363acf856ba77e6666f
$ git ls-files -s
100644 5ec586d228b5ff1e8c845c4ed8c2d01f3a159b24 0 first_commit.py
$ git log --oneline --decorate --graph --all
*-. 637e1b1 (refs/stash) WIP on master: 540b81b first commit
|\ \
| | * 8ba9c13 untracked files on master: 540b81b first commit
| * 18383cf index on master: 540b81b first commit
|/
* 540b81b (HEAD -> master) first commit
$ cat .git/ORIG_HEAD
540b81b6fb3e8a6c8e8de363acf856ba77e6666f
$ cat .git/refs/stash
637e1b1afb4f209162d8ef7c5836b2d04fc5012f
Check the content of the git commit object '18383cf' (index on master)
This commit will track the staged changes. (the index file from step 2).
Also, its parent is the last commit when running the 'git stash' command.
$ git cat-file -p 18383cf
tree 9aeb573ff2d1786e30fee3fc5837d3d7a713c565
parent 540b81b6fb3e8a6c8e8de363acf856ba77e6666f
author Frank <frank@demo.com> date
committer Frank <frank@demo.com> date
index on master: 540b81b first commit
Check the content of the git tree object '9aeb573'
$ git cat-file -p 9aeb573
100644 blob 5ec586d228b5ff1e8c845c4ed8c2d01f3a159b24 first_commit.py
100644 blob bb2310c44ce2dda23a59d6e3397c30947cc14f3f staged_data.py
Check the content of the git blob objects.
$ git cat-file -p 5ec586d
first commit
$ git cat-file -p bb2310c
staged data
Check the content of the git commit object '8ba9c13' (untracked files on master)
The 'git stash' command will create a git commit object, a git tree object, and git blob objects to record the untracked files in step 2.
There is no parent in this special commit object.
$ git cat-file -p 8ba9c13
tree 21d07d848ea2d2f9493971bf15fffac2543e0e12
author Frank <frank@demo.com> date
committer Frank <frank@demo.com> date
untracked files on master: 540b81b first commit
Check the content of the git tree object '21d07d8'
$ git cat-file -p 21d07d8
100644 blob 5a72eb2edc5d0da32ff615d210d6fa90c31ed940 untracked_data.py
Check the content of the git blob object '5a72eb2'
$ git cat-file -p 5a72eb2
untracked
Check the content of the git commit object '637e1b1' (WIP, working in progress, on master)
This commit will refer to three commits:
#1 The last commit when running the 'git stash' command
#2 The 'index on master' commit
#3 The 'untracked files on master' commit
$ git cat-file -p 637e1b1
tree 9160192d673a0371f335e821d6e4a78bb2bd0f60
parent 540b81b6fb3e8a6c8e8de363acf856ba77e6666f
parent 18383cf89b3be950d6fa7d3671301f2505f7e7c9
parent 8ba9c13efffa57668e0c285b370f6d344a7dd66d
author Frank <frank@demo.com> date
committer Frank <frank@demo.com> date
WIP on master: 540b81b first commit
Check the content of the git tree object '9160192'
$ git cat-file -p 9160192
100644 blob 330e45055490c45a14f8676e02dfb737e9e083aa first_commit.py
100644 blob bb2310c44ce2dda23a59d6e3397c30947cc14f3f staged_data.py
Check the content of the git blob objects.
$ git cat-file -p 330e450
modify first commit
$ git cat-file -p bb2310c
staged data
Step 4:
Apply the stashed changes.
(Using 'pop' will drop the last stashed data)
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: staged_data.py
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: first_commit.py
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked_data.py
Dropped refs/stash@{0} (637e1b1afb4f209162d8ef7c5836b2d04fc5012f)
Check the .git tree structure.
$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── ORIG_HEAD
├── branches
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ │ └── master
│ └── stash (removed)
├── objects
│ ├── 18
│ │ └── 383cf89b3be950d6fa7d3671301f2505f7e7c9 (git commit object for 'index on master')
│ ├── 21
│ │ └── d07d848ea2d2f9493971bf15fffac2543e0e12 (git tree object for 'untracked')
│ ├── 33
│ │ └── 0e45055490c45a14f8676e02dfb737e9e083aa (git blob object for 'WIP on master')
│ ├── 54
│ │ └── 0b81b6fb3e8a6c8e8de363acf856ba77e6666f (git commit object for the first commit)
│ ├── 5a
│ │ └── 72eb2edc5d0da32ff615d210d6fa90c31ed940 (git blob object for 'untracked')
│ ├── 5e
│ │ └── c586d228b5ff1e8c845c4ed8c2d01f3a159b24 (git blob object for the first commit)
│ ├── 63
│ │ └── 7e1b1afb4f209162d8ef7c5836b2d04fc5012f (git commit object for 'WIP on master')
│ ├── 75
│ │ └── 79acf4e2845113349b344d98e366357bc6d125 (git tree object for the first commit)
│ ├── 8b
│ │ └── a9c13efffa57668e0c285b370f6d344a7dd66d (git commit object for 'untracked')
│ ├── 91
│ │ └── 60192d673a0371f335e821d6e4a78bb2bd0f60 (git tree object for 'WIP on master')
│ ├── 9a
│ │ └── eb573ff2d1786e30fee3fc5837d3d7a713c565 (git tree object for 'index on master')
│ ├── bb
│ │ └── 2310c44ce2dda23a59d6e3397c30947cc14f3f (new file for a git blob object)
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
├── stash (removed)
└── tags
24 directories, 35 files
.git/refs/stash is removed.
Check more info.
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
540b81b6fb3e8a6c8e8de363acf856ba77e6666f
$ git ls-files -s
100644 5ec586d228b5ff1e8c845c4ed8c2d01f3a159b24 0 first_commit.py
100644 bb2310c44ce2dda23a59d6e3397c30947cc14f3f 0 staged_data.py
$ git log --oneline --decorate --graph --all
* 540b81b (HEAD -> master) first commit
$ cat .git/ORIG_HEAD
540b81b6fb3e8a6c8e8de363acf856ba77e6666f
Step 5:
Create a commit.
$ git commit -m 'second commit'
[master 2c5cadd] second commit
3 files changed, 3 insertions(+), 1 deletion(-)
create mode 100644 staged_data.py
create mode 100644 untracked_data.py
Check the git status.
On branch master
nothing to commit, working tree clean
Check the .git tree structure.
$ tree .git/
.git/
├── COMMIT_EDITMSG
├── HEAD
├── ORIG_HEAD
├── branches
├── config
├── description
├── hooks
│ ├── applypatch-msg.sample
│ ├── commit-msg.sample
│ ├── fsmonitor-watchman.sample
│ ├── post-update.sample
│ ├── pre-applypatch.sample
│ ├── pre-commit.sample
│ ├── pre-merge-commit.sample
│ ├── pre-push.sample
│ ├── pre-rebase.sample
│ ├── pre-receive.sample
│ ├── prepare-commit-msg.sample
│ ├── push-to-checkout.sample
│ └── update.sample
├── index
├── info
│ └── exclude
├── logs
│ ├── HEAD
│ └── refs
│ └── heads
│ │ └── master
├── objects
│ ├── 18
│ │ └── 383cf89b3be950d6fa7d3671301f2505f7e7c9 (git commit object for 'index on master')
│ ├── 21
│ │ └── d07d848ea2d2f9493971bf15fffac2543e0e12 (git tree object for 'untracked')
│ ├── 2c
│ │ └── 5caddc1a5e04f08bbedea8f87e1973fffa4304 (git commit object for the second commit)
│ ├── 33
│ │ └── 0e45055490c45a14f8676e02dfb737e9e083aa (git blob object for 'WIP on master')
│ ├── 54
│ │ └── 0b81b6fb3e8a6c8e8de363acf856ba77e6666f (git commit object for the first commit)
│ ├── 5a
│ │ └── 72eb2edc5d0da32ff615d210d6fa90c31ed940 (git blob object for 'untracked')
│ ├── 5e
│ │ └── c586d228b5ff1e8c845c4ed8c2d01f3a159b24 (git blob object for the first commit)
│ ├── 63
│ │ └── 7e1b1afb4f209162d8ef7c5836b2d04fc5012f (git commit object for 'WIP on master')
│ ├── 75
│ │ └── 79acf4e2845113349b344d98e366357bc6d125 (git tree object for the first commit)
│ ├── 85
│ │ └── 22a84af8b611023a4d6ba70ee1f591aca9437f (git tree object for the second commit)
│ ├── 8b
│ │ └── a9c13efffa57668e0c285b370f6d344a7dd66d (git commit object for 'untracked')
│ ├── 91
│ │ └── 60192d673a0371f335e821d6e4a78bb2bd0f60 (git tree object for 'WIP on master')
│ ├── 9a
│ │ └── eb573ff2d1786e30fee3fc5837d3d7a713c565 (git tree object for 'index on master')
│ ├── bb
│ │ └── 2310c44ce2dda23a59d6e3397c30947cc14f3f (new file for a git blob object)
│ ├── info
│ └── pack
└── refs
├── heads
│ └── master
└── tags
26 directories, 37 files
Check more info.
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
2c5caddc1a5e04f08bbedea8f87e1973fffa4304
$ git ls-files -s
100644 330e45055490c45a14f8676e02dfb737e9e083aa 0 first_commit.py
100644 bb2310c44ce2dda23a59d6e3397c30947cc14f3f 0 staged_data.py
100644 5a72eb2edc5d0da32ff615d210d6fa90c31ed940 0 untracked_data.py
$ git log --oneline --decorate --graph --all
* 2c5cadd (HEAD -> master) second commit
* 540b81b first commit
Check the content of the git commit object '2c5cadd'
$ git cat-file -p 2c5cadd
tree 8522a84af8b611023a4d6ba70ee1f591aca9437f
parent 540b81b6fb3e8a6c8e8de363acf856ba77e6666f
author Frank <frank@demo.com> date
committer Frank <frank@demo.com> date
second commit
Check the content of the git tree object '8522a84'
$ git cat-file -p 8522a84
100644 blob 330e45055490c45a14f8676e02dfb737e9e083aa first_commit.py
100644 blob bb2310c44ce2dda23a59d6e3397c30947cc14f3f staged_data.py
100644 blob 5a72eb2edc5d0da32ff615d210d6fa90c31ed940 untracked_data.py
No comments:
Post a Comment