储藏与清理

大约 5 分钟

当想要切换分支做别的事,又不想把当前分支做到一半的代码提交时,可以使用贮藏命令(git stash)。

贮藏会跟踪文件的修改与暂存的改动,然后将未完成的修改保存到一个栈上,可以在任何时候重新应用这些改动。

# 贮藏工作

实例:

改动文件后,执行 git status 查看当前状态:

$ git status
On branch master
Your branch is up to date with 'origin/master'.
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:   my_Unfinished_Work.txt
no changes added to commit (use "git add" and/or "git commit -a")

贮藏当前的工作,执行 git stashgit stash push 命令:

$ git stash
Saved working directory and index state WIP on master: a66ee73 unfinishedwork

再次查看当前状态,现在分支是干净的了。此时,你可以切换分支并在其他地方工作;你的修改被存储在栈上。

$ git status
On branch master
Your branch is up to date with 'origin/master'.
nothing to commit, working tree clean

查看当前贮藏列表,执行 git stash list 命令:

$ git stash list
stash@{0}: WIP on master: a66ee73 unfinishedwork
stash@{1}: WIP on master: 60434ac Subject line (try to keep under 50 characters)

应用贮藏其中的一个工作,执行 git stash apply 命令。如果不指定一个贮藏,Git 认为指定的是最近的贮藏。

$ git stash apply stash@{0}
On branch master
Your branch is up to date with 'origin/master'.
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:   my_Unfinished_Work.txt
no changes added to commit (use "git add" and/or "git commit -a")

移除贮藏,执行 git stash drop 命令:

$ git stash drop stash@{1}
Dropped stash@{1} (ae8139183fd57272bf32c1f7eaabda0c2bf99081)

# 贮藏的创意性使用

贮藏变种有用且流行的几个选项:

1、git stash 命令的 --keep-index 选项:告诉 Git 不仅要贮藏所有已暂存的内容,同时还要将它们保留在索引中。

$ git status -s
M  my_Unfinished_Work2.txt
M  my_Unfinished_Work3.txt
$ git stash --keep-index
Saved working directory and index state WIP on master: a732e98 add work
$ git status -s
M  my_Unfinished_Work2.txt
M  my_Unfinished_Work3.txt

2、git stash 指定 --inc lude-untracked-u 选项:Git 会贮藏任何未跟踪文件(默认情况下,git stash只会贮藏已修改和暂存的已跟踪文件)。

$ git status -s
M  my_Unfinished_Work2.txt
M  my_Unfinished_Work3.txt
?? my_Unfinished_Work4.txt
$ git stash -u
Saved working directory and index state WIP on master: a732e98 add work
$ git status -s
$

3、git stash 指定 --patch 标记:Git 不会贮藏所有修改过的任何东西, 但是会交互式地提示哪些改动想要贮藏、哪些改动需要保存在工作目录中。

$ git stash --patch
diff --git a/my_Unfinished_Work2.txt b/my_Unfinished_Work2.txt
index e69de29..eaca4b7 100644
--- a/my_Unfinished_Work2.txt
+++ b/my_Unfinished_Work2.txt
@@ -0,0 +1 @@
+miss you!
\ No newline at end of file
Stash this hunk [y,n,q,a,d,e,?]? y

diff --git a/my_Unfinished_Work3.txt b/my_Unfinished_Work3.txt
index e69de29..79a1388 100644
--- a/my_Unfinished_Work3.txt
+++ b/my_Unfinished_Work3.txt
@@ -0,0 +1 @@
+hate you!
\ No newline at end of file
Stash this hunk [y,n,q,a,d,e,?]? n

Saved working directory and index state WIP on master: a732e98 add work

# 从贮藏创建一个分支

如果贮藏了一些工作,将它留在那,然后继续在贮藏的分支上工作,在重新应用工作时可能会有问题。 如果应用尝试修改刚刚修改的文件,你会得到一个合并冲突并不得不解决它。 如果想要一个轻松的方式来再次测试贮藏的改动,可以运行 git stash branch <new branchname> 以你指定的分支名创建一个新分支,检出贮藏工作时所在的提交,重新在那应用工作,然后在应用成功后丢弃贮藏:

$ git stash branch testchanges
Switched to a new branch 'testchanges'
M       my_Unfinished_Work2.txt
M       my_Unfinished_Work3.txt
A       my_Unfinished_Work4.txt
On branch testchanges
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
        modified:   my_Unfinished_Work2.txt
        modified:   my_Unfinished_Work3.txt
        new file:   my_Unfinished_Work4.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:   my_Unfinished_Work2.txt
Dropped refs/stash@{0} (69fd89ac16b7bf45163922fbedac81ed6356a842)

这是在新分支轻松恢复贮藏工作并继续工作的一个很不错的途径。

# 清理工作目录

git clean 命令可用来移除工作目录中以一些工作或文件。

但它被设计为从工作目录中移除未被跟踪的文件,是无法找回文件内容的,需谨慎使用。较安全的选项是运行 git stash --all 来移除每一个东西并存放在栈中。

你可以使用 git clean 命令去除冗余文件或者清理工作目录。使用 git clean -f -d 命令来移除工作目录中所有未追踪的文件以及空的子目录。-f 意味着“强制(force)”或“确定要移除”,使用它需要 Git 配置变量 clean.requireForce 没有显式设置为 false

使用 --dry-run-n 选项:做一次演习,然后告诉你将要移除什么,即演练一遍即将要做的操作。

$ git clean -d -n
Would remove my_Unfinished_Work4.txt

默认情况下,git clean 命令只会移除没有忽略的未跟踪文件。任何与 .gitignore 或其他忽略文件中的模式匹配的文件都不会被移除。如果你也想要移除那些文件,例如为了做一次完全干净的构建而移除所有由构建生成的 .o 文件,可以给 clean 命令增加一个 -x 选项。

$ git status -s
 M my_Unfinished_Work2.txt
 M my_Unfinished_Work3.txt
?? my_Unfinished_Work4.txt
$ git clean -n -d
Would remove my_Unfinished_Work4.txt
$ git clean -n -d -x
Would remove my_Unfinished_Work4.txt

git clean 在将 -n 改为 -f 来真正做之前总是先用-n来运行它做双重检验。另一个小心处理过程的方式是使用 -i 或者 interactive 标记来运行它。

交互模式运行 clean 命令:

$ git clean -x -i
Would remove the following item:
  my_Unfinished_Work4.txt
*** Commands ***
    1: clean                2: filter by pattern    3: select by numbers
    4: ask each             5: quit                 6: help
What now>
上次编辑于: 2024年5月10日 22:00