git stash
如何处理未跟踪的文件?
Git官方文档(link)将git-stash
定义为
git-stash - Stash the changes in a dirty working directory away
但对我来说(git的初学者),它的含义并不是很明显 “脏工作目录”的确切定义。没有跟踪 包含文件?
更确切地说,我注意到了 在“脏”工作目录中,我们可以有三种类型的脏状态:
git add
(更改在索引中)git add
(更改不在索引中,但跟踪文件又称“要提交的更改”)git add
从未运行过的文件所做的更改(文件未跟踪)当我们运行git stash
时,#1,#2和#3会发生什么?
答案 0 :(得分:1)
我认为他们的意思是实际的更改只是git正在跟踪的文件中的更改。
以一种在git中出现的方式,因为如果你有一个未跟踪的文件,那么它不是一个改变,直到你跟踪它是没有的。您甚至可以使用未跟踪的更改自由切换分支之间的分支。
从git的外部然而这是错误的,因为它是本地存储库中的实际更改,但由于我们正在讨论git功能,因此git中的视图是正确的,即使它看起来有点非didatic。
这可能看起来像是一个意见问题,但由于更改是git中的关键字,因此它必须具有单一含义。
较长的描述解决了它:
该命令将您的本地修改保存起来,并恢复工作目录以匹配 HEAD 提交。
答案 1 :(得分:0)
我想在这里提供自己的答案。
我是git
的新手。但对我来说,描述命令的单行应修改为此
git-stash - Stash away the tracked changes in a dirty working directory
(untracked changes are ignored)
换句话说,git stash
(没有选项-u
)会隐藏#1和#2但不会隐藏#3。如果#1和#2发生在同一个文件中,那么#2将优先于#1。
使用选项-u
,git stash -u
还可以包含未跟踪的文件。
有关详细信息,请参阅此SO文章(link)。
<强>实验强>
以下实验说明了git stash
(-u
)如何处理
还包括三种情况(基于案例,历史中的文件t1.txt
)。
设置四种不同的状态
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
检查四种状态
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)
现在执行藏匿
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)
请注意,git stash
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ git stash show
tmp/t1.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
如果你输了t2.txt; git stash将无法为您恢复
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)
索引与已跟踪(未提交的更改)
顺便说一下,还要注意发生在
状态的事情#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
和git stash
操作后, git stash pop
也丢失了。
保留的是#2
。换句话说,工作目录状态在存储操作中优先。
MINGW64 ~/proj/tmp/sandbox/tmp (f2)
$ cat t1.txt
Hello in Working Directory (tracked)
答案 2 :(得分:0)
git stash
如何处理未跟踪的文件?
在Git 2.16.x / 2.17之前,可能很糟糕!
&#34; git stash -- <pathspec>
&#34;错误地将未经跟踪的文件吹走了
与pathspec匹配的目录,已经更正。
commit bba067d见Thomas Gummerer (tgummerer
)(2018年1月6日)
帮助:Junio C Hamano (gitster
)。
(由Junio C Hamano -- gitster
--合并于commit 087d1a8,2018年1月23日)
stash
:不要删除与pathspec匹配的未跟踪文件
目前{&#39;
git stash push -- <pathspec>
&#39;使用,未跟踪的文件 匹配pathspec的将被删除,即使它们没有结束 藏在任何地方。这是因为原始提交引入了pathspec功能
git stash push
(df6bba0(&#34; stash:teach&#39; push&#39;(和&#39; create_stash&#39;) 荣誉pathspec&#34;,2017-02-28,Git v2.13.0-rc0))使用了以下序列:
git reset <pathspec> && git ls-files --modified <pathspec> |
git checkout-index && git clean <pathspec>
目的是模仿&#39;
git reset --hard -- <pathspec>
&#39;将 这样做。
致电&#39;git clean
&#39;应该清理那些文件 没有被&#39;git reset
&#39; 如果在几个未跟踪的文件之前匹配任何文件,那么这将正常工作。git stash push -- <pathspec>
&#39;。
但是,如果<pathspec>
与未调整的文件匹配,则会在调用&#39; stash&#39;之前命令,所有与pathspec匹配的未跟踪文件也会被无意中删除,即使它们不会在藏匿处结束,因此也会丢失。这种行为绝不是预期的,只有blob也会结束 之前,存储区应该重置为HEAD中的状态 未跟踪的文件应该保持不变。
实现这一目标:
- 首先匹配索引中的内容以及中的内容 通过向索引添加所有更改来工作树,
- 询问
diff-index
HEAD
与当前索引之间的变化,以及- 然后反向应用该补丁以消除更改,包括删除添加的文件和复制已删除的文件。