1.保存进度
git stash(会保存当前进度。会分别对暂存区和工作区的状态进行保存)
2.查看进度git stash list
显示进度列表。此命令显然暗示了git stash可以多次保存工作进度,并且在恢复时候可以以列表的形式进行选择
3.恢复进度git stath pop [--index][<stash>]
如果不适用任何参数默认会恢复最新保存的工作进度,并将恢复的工作进度从存储的工作进度列表删除
如果选择<stash>参数(来自于git stash list显示的列表),则从该<stash>中恢复.恢复完后也会从进度列表中删除<stash>
选项--index除了恢复工作区的文件外,还尝试恢复暂存区
4.命令: git stash [save [--patch]] [-k] --[no-]keep-index] [-q|--quiet] [<messges>]]此命令相当于git stash的完整版
使用参数--patch会显示工作区和HEAD的差异,通过对差异文件的编辑决定在进度中最终要保存的工作的内容,通过编辑差异文件可以在进度中排除无关内容
使用-k或--keep-index参数,在保存进度后不会将暂存区重置。默认会将暂存区和工作区强重置。
5.git stash apply[--index] [<stash>]
除了不删除恢复的进度之外,其余和git stash pop命令一样
6.git stash drop [<stash>]
删除一个存储的进度。默认删除最新的进度
7.git stash clear
删除所有存储的进度
8.git stash branch <branchname> <stash>
基于进度创建分支。
x查看git stash 安装哪里
jagent@ubuntu:~/xin/mytest$ git --exec-path
jagent@ubuntu:~/xin/mytest$ ls /usr/lib/git-core/
git git-check-ref-format git-diff-index git-help git-merge-index git-pack-refs git-remote-fd git-sh-i18n--envsubst git-unpack-objects
git-add git-cherry git-difftool git-http-backend git-merge-octopus git-parse-remote git-remote-ftp git-shortlog git-update-index
git-add--interactive git-cherry-pick git-difftool--helper git-http-fetch git-merge-one-file git-patch-id git-remote-ftps git-show git-update-ref
git-am git-clean git-diff-tree git-http-push git-merge-ours git-prune git-remote-http git-show-branch git-update-server-info
git-annotate git-clone git-fast-export git-imap-send git-merge-recursive git-prune-packed git-remote-https git-show-index git-upload-archive
git-apply git-column git-fast-import git-index-pack git-merge-resolve git-pull git-remote-testsvn git-show-ref git-upload-pack
git-archive git-commit git-fetch git-init git-merge-subtree git-push git-repack git-sh-prompt git-var
git-bisect git-commit-tree git-fetch-pack git-init-db git-mergetool git-quiltimport git-replace git-sh-setup git-verify-pack
git-bisect--helper git-config git-filter-branch git-instaweb git-mergetool--lib git-read-tree git-request-pull git-stage git-verify-tag
git-blame git-count-objects git-fmt-merge-msg git-log git-merge-tree git-rebase git-rerere git-stash git-web--browse
git-branch git-credential git-for-each-ref git-ls-files git-mktag git-rebase--am git-reset git-status git-whatchanged
git-bundle git-credential-cache git-format-patch git-ls-remote git-mktree git-rebase--interactive git-revert git-stripspace git-write-tree
git-cat-file git-credential-cache--daemon git-fsck git-ls-tree git-mv git-rebase--merge git-rev-list git-submodule mergetools
git-check-attr git-credential-store git-fsck-objects git-mailinfo git-name-rev git-receive-pack git-rev-parse git-submodule--helper
git-check-ignore git-daemon git-gc git-mailsplit git-notes git-reflog git-rm git-subtree
git-check-mailmap git-describe git-get-tar-commit-id git-merge git-p4 git-relink git-send-pack git-symbolic-ref
git-checkout git-diff git-grep git-merge-base git-pack-objects git-remote git-shell git-tag
git-checkout-index git-diff-files git-hash-object git-merge-file git-pack-redundant git-remote-ext git-sh-i18n git-unpack-file
jagent@ubuntu:~/xin/mytest$ file /usr/lib/git-core/git-stash
/usr/lib/git-core/git-stash: POSIX shell script, ASCII text executabl
从上面看我们知道这个命令是用shell写的,而其他很多命令都是基于C写的
下面举例来使用命令
jagent@ubuntu:~/xin$ git clone ssh://xwx496887@10.148.192.216:29418/ST/mytest
Cloning into 'mytest'...
remote: Counting objects: 17, done
remote: Finding sources: 100% (17/17)
remote: Total 17 (delta 3), reused 17 (delta 3)
Receiving objects: 100% (17/17), done.
Resolving deltas: 100% (3/3), done.
Checking connectivity... done.
jagent@ubuntu:~/xin$ cd mytest/
jagent@ubuntu:~/xin/mytest$ ll
total 20
drwxrwxr-x 4 jagent jagent 4096 Nov 6 15:37 ./
drwxrwxr-x 4 jagent jagent 4096 Nov 6 15:37 ../
-rw-rw-r-- 1 jagent jagent 0 Nov 6 15:37 1.txt
-rw-rw-r-- 1 jagent jagent 0 Nov 6 15:37 2.txt
-rw-rw-r-- 1 jagent jagent 0 Nov 6 15:37 3.txt
drwxrwxr-x 2 jagent jagent 4096 Nov 6 15:37 ddd/
drwxrwxr-x 8 jagent jagent 4096 Nov 6 15:37 .git/
-rw-rw-r-- 1 jagent jagent 6 Nov 6 15:37 README.md
jagent@ubuntu:~/xin/mytest$ touch test-stash.txt
jagent@ubuntu:~/xin/mytest$ echo "this is a helloworld" >> test-stash.txt
jagent@ubuntu:~/xin/mytest$ echo "this is a helloworld" >> 1.txt
jagent@ubuntu:~/xin/mytest$ git add test-stash.txt
jagent@ubuntu:~/xin/mytest$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: test-stash.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: 1.txt
jagent@ubuntu:~/xin/mytest$ git stash
Saved working directory and index state WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test Team:ETCD1_CI Feature or Bugfix:Feature Binary Source:No PrivateCode(Yes/No):No
HEAD is now at 6c8826b TicketNo:DTS2020062200775
jagent@ubuntu:~/xin/mytest$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
nothing to commit, working directory clean
备注ps:当版本库中没有执行过git add暂存区没有文件的情况执行git stash的情况是会保存失败的
jagent@ubuntu:~/xin/mytest$ touch ddd.txt
jagent@ubuntu:~/xin/mytest$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
ddd.txt
nothing added to commit but untracked files present (use "git add" to track)
jagent@ubuntu:~/xin/mytest$ git stash
No local changes to save
恢复工作进度
jagent@ubuntu:~/xin/mytest$ git stash list
stash@{0}: WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test Team:ETCD1_CI Feature or Bugfix:Feature Binary Source:No PrivateCode(Yes/No):No
stash@{1}: WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test Team:ETCD1_CI Feature or Bugfix:Feature Binary Source:No PrivateCode(Yes/No):No
jagent@ubuntu:~/xin/mytest$ git stash pop stash@{0}
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: ddd.txt
Dropped stash@{0} (47f73e52612aff2b93301de21845851a1e8a9863)
jagent@ubuntu:~/xin/mytest$ git status
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: ddd.txt
jagent@ubuntu:~/xin/mytest$ git stash list
stash@{0}: WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test Team:ETCD1_CI Feature or Bugfix:Feature Binary Source:No PrivateCode(Yes/No):No
jagent@ubuntu:~/xin/mytest$ git stash pop
On branch master
Your branch is up-to-date with 'origin/master'.
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
new file: ddd.txt
new file: test-stash.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: 1.txt
Dropped refs/stash@{0} (1caf69261af154b3c45fce2e3da88a2083c3d09a)
从上面能得出2个结论:
第一:git stash比如有添加暂存区的文件,否则无法保存
第二:每个进度都有标识stash@{<n>},和前面reflog的格式类似,其实就是用reflog的引用变更日志实现的,所有的操作日志保存再.git/refs/stash记录下来的,研究下.git/refs/stash就会发现问题
0000000000000000000000000000000000000000 77be4cdef38cb7b47f8edd54f48e6cdd8739fb97 xwx496887 <xwx496887@notesmail.huawei.com> 1604651362 +0800 WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test Team:ETCD1_CI Feature or Bugfix:Feature Binary Source:No PrivateCode(Yes/No):No
77be4cdef38cb7b47f8edd54f48e6cdd8739fb97 4c591980aa673adacc5ce9381e9d0121bcace1c2 xwx496887 <xwx496887@notesmail.huawei.com> 1604651460 +0800 WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test Team:ETCD1_CI Feature or Bugfix:Feature Binary Source:No PrivateCode(Yes/No):No
然后再通过git stash list
jagent@ubuntu:~/xin/mytest$ git stash list
stash@{0}: WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test
stash@{1}: WIP on master: 6c8826b TicketNo:DTS2020062200775 Description:ci test
最后通过比较差异就能发现他主要就是操作就是保存.git/refs/stash日志也可以通过commitid出发。
原基线和原暂存区的差异比较
jagent@ubuntu:~/xin/mytest$ git diff stash@{1}^2^ stash@{1}^2
diff --git a/ddd.txt b/ddd.txt
new file mode 100644
index 0000000..e69de29
diff --git a/test-stash.txt b/test-stash.txt
new file mode 100644
index 0000000..651b312
--- /dev/null
+++ b/test-stash.txt
原暂存区和原工作区的差异比较
jagent@ubuntu:~/xin/mytest$ git diff stash@{1}^2 stash@{1}
diff --git a/1.txt b/1.txt
index e69de29..651b312 100644
--- a/1.txt
+++ b/1.txt
@@ -0,0 +1 @@
+this is a helloworld
原基线和原工作区的差异
diff --git a/test-stash.txt b/test-stash.txt
new file mode 100644
index 0000000..651b312
--- /dev/null
+++ b/test-stash.txt
@@ -0,0 +1 @@
+this is a helloworld
我们可以通过git stash clear命令删除保存进度
然后你发现 .git/refs/stash文件不存在了
jagent@ubuntu:~/xin/mytest$ ls -l .git/refs/stash .it/logs/ref/stash
ls: cannot access .git/refs/stash: No such file or directory
ls: cannot access .it/logs/ref/stash: No such file or directory