我的开发分支中有一些修改过的文件,很少有新创建但未被git攻击的文件。我想将这些更改移动到功能分支,因此我运行了git stash
。
在用git status
检查后,我意识到git没有存储未跟踪的文件。所以我跑了git stash -u
。
这里发生了一些奇怪的事情,因为在我检查了我的功能分支并试图查看两个存储的更改后,使用git stash show stash@{0}
和git stash show stash@{1}
,它没有显示第0个存储索引的任何内容并且第一个存储索引显示未跟踪的文件。没有第二个指数。
git stash list
根本没有显示任何内容。我继续做了git stash apply
并且只返回了未跟踪的文件更改,而不是修改过的文件。
应用未跟踪的文件更改后,我再次运行了git stash show stash@{0}
和git stash show stash@{1}
。这次,第0个索引再次为空,修改后的文件更改移至第1个索引。应用存储@ {1},恢复了我的所有更改,但我无法理解存储的行为。有没有人见过这个?
答案 0 :(得分:1)
为清楚起见:
$ git stash; git stash -u
这是两个单独的git stash
命令。每个人都会git stash save
,因为最后没有更具体的动词。
第一个git stash
保存了当前索引和当前工作树(通过进行两次单独的提交,两者都不在分支上)。之后,您的索引与HEAD
提交匹配,您的工作树也很干净,当然除了未跟踪的文件。
通常情况下,如果您尝试重复git stash save
,它只会告诉您没有任何内容可以保存,并且什么都不做,但是对于您的第二个save
,您添加了-u
} flag:保存(然后删除)未跟踪的文件。所以这创建了一个第二个存储,使用您当前的索引 - 第一个save
等于HEAD
提交 - 和您当前的工作树 - 再次相等到HEAD
提交 - 并使用第三个提交作为存储包的一部分:u
提交。请参阅this answer中的图纸,但请注意,在您的特定情况下,您有两个单独的存储袋挂在同一个(HEAD
)提交上。
当您使用一些活动存储保存存储时,stash
脚本使用git的“reflogs”将当前存储“推送”到“存储堆栈”中,使新存储成为最重要的存储一,stash@{0}
。所以你的隐藏包含u
提交,此时为stash@{0}
,而你的存储包含修改后的索引和/或工作树(并且没有u
包含未跟踪文件的提交)在stash@{1}
。
然后你做了:
git checkout feature
或类似于将HEAD
更改为指向其他分支。我们现在通过假设存储在名为X
的分支上完成来绘制情况:
... - o - o - o <-- HEAD=feature
\
o - * <-- X
|\
| \
|\ \
i-w \ <-- stash@{1}
|\
i-w <-- stash@{0}
/
u
同样,两个存储包都挂起了提交*
; stash@{1}
中的文件具有未跟踪的文件,但其i
和w
提交与提交*
本身相同。
你说:
使用
git stash show stash@{0}
和git stash show stash@{1}
,它没有显示第0个存储索引的任何内容,第1个存储索引显示未跟踪的文件......
这似乎不太可能。但是,如果你写的是git show stash@{0}
而不是git stash show stash@{0}
,而git show stash@{1}
而不是git stash show stash@{1}
,那么就是你会看到的,因为{{ 1}}将合并提交显示为“组合差异”,您基本上要求git show
查看每个存储包中的git show
提交。每个w
提交都是合并提交,它不是通常的合并类型,因此w
会产生很大程度上无用的结果。
我继续执行git stash apply并且只返回未跟踪的文件更改,而不是修改后的文件。
这就是预期的结果:git show
(适用git stash apply
)告诉stash@{1}
比较工作树和索引提交(git stash
和{{1} })到他们的父(commit w
),在三父stash-bag的情况下,提取第三个父(i
)中的文件。 *
和u
之间没有变化,但会带回w
。
应用
*
,带回了我的所有更改......
同样,这是预期的:u
告诉stash@{1}
将工作树(对于git stash apply
)和索引提交与其父对象(git stash
)进行比较。这里,是更改,它会提取这些更改并将其应用于新的stash@{1}
提交。此另一个存储袋中没有第三个父级,因此此时*
已完成。
如果你喜欢这个结果,请继续HEAD
这两个藏匿袋。