我遇到问题
git stash pop
因为某些dos2unix问题。我想恢复到隐藏状态,而不必合并仅行尾不同的整个文件。 我当时想过要回到藏匿处
git checkout BRANCHNAME
但我不知道如何确定代表此藏匿地来源的BRANCHNAME。 有人有线索吗?
答案 0 :(得分:5)
使用git stash branch
创建一个新分支并应用存储:
git stash branch newbranch
这始终有效(好,只要您当前的状态是干净的:请参见下面的较长部分),并且等效于创建一个新分支,其父级是您进行隐藏时提交的当前提交,然后运行git apply --index
(意味着它分别还原索引和工作树)。
您需要做的就是找出是否有任何分支名称标识与该存储的父代相同的提交,因此:
git for-each-ref --format='%(refname:short)' \
--points-at $(git rev-parse refs/stash~1) refs/heads
将找到可能的分支名称(如果有)。 (这取决于git for-each-ref
的相对现代的功能。)
每个存储本身本身就是两次提交,有时甚至是三个提交。 git stash
所做的是,它提交了这两个(或三个)提交,但是将它们放在 no 分支上。
Git中的 branch 单词本身有点含糊(请参见What exactly do we mean by "branch"?),但是在这里,我们使用它的含义是分支 name 像master
或develop
只是指向其分支上的 last 提交:
...--E--F--G <-- master
\
H <-- develop
当您git checkout
像develop
这样的分支名称时,您正在告诉Git:
将名称HEAD
附加到分支名称,以便Git知道您现在已签出的提交:
...--E--F--G <-- master
\
H <-- develop (HEAD)
现在,Git知道哈希为H
的提交是当前提交或HEAD
提交,如名称develop
所指向。
如果此时进行普通的新提交(通过将更新的文件或新文件从工作树复制回索引/暂存区,然后运行git commit
将其冻结为新的提交), Git使用当前提交作为其父提交写入新提交,然后更新分支名称:
...--E--F--G <-- master
\
H--I <-- develop (HEAD)
名称HEAD
仍附加在分支名称上,但是现在分支名称标识了提交I
而不是提交H
。
git stash
的作用是进行两次提交-一个用于索引,一个用于工作树,而没有分支名称。取而代之的是,Git使用名称refs/stash
查找w
提交(而w
查找原始提交和i
提交):
...--E--F--G <-- master
\
H <-- develop (HEAD)
|\
i-w <-- refs/stash
保存i
和w
提交后,git stash
运行git reset --hard
,将索引和工作树设置回与当前提交匹配的位置(此处为{{ 1}})。
在这种情况下,此时,存储的父提交也由现有分支名称H
指向。但是假设您已完成develop
,然后继续进行不同的一组更改并进行了新的提交git stash
?然后,您将拥有:
I
现在有 no 分支名称指向现有的历史提交...--E--F--G <-- master
\
H--I <-- develop (HEAD)
|\
i-w <-- refs/stash
,即使可以保证使用H
的提交也是如此。
因此,如果您的索引和工作树现在是干净的(即,匹配提交refs/stash
并附加了I
的内容),并且现在运行HEAD
, git stash branch recover
要做的是附加一个 new 分支名称git stash
来提交recover
,并检查该提交并将新分支设为当前分支将H
附加到它:
HEAD
,并作为...--E--F--G <-- master
\
H <-- recover (HEAD)
\
I <-- develop
操作的最后一步,应用并删除存储,以使索引恢复为您git stash branch
签出并运行{{ 1}},工作树又回到了您H
签出并运行git stash
时的工作树。现在,您可以完成H
的创建和git stash
的新提交git add
的提交:
git commit
J
仍指向提交...--E--F--G <-- master
\
H--J <-- recover (HEAD)
\
I <-- develop
,该怎么办?如果您没有移动上一个分支,那么现在您仍然有一个新分支。也就是说,现在您将拥有:
develop
(我在这里将新提交保留为H
,以便更轻松地与先前的图进行匹配)。此设置没有错。当然,如果您在这里不想要...--E--F--G <-- master
\
H <-- develop
\
J <-- recover (HEAD)
分支,则不必使用J
,但它仍然有效。
三提交存储是由recover
(git stash branch
)或git stash save -a
(--all
)制成的。应用(或弹出)这种存储方式要求第三次提交中的文件不与工作树中的文件冲突。通常,这意味着工作树不仅必须按照git stash save -u
是“干净的”,而且还必须以运行带有适当选项的--include-untracked
提供的意义上是干净的。在这种情况下,甚至git status
有时也会失败。如果失败,则不会隐藏存储。
有关更多信息,请参见Why does git stash pop say that it could not restore untracked files from stash entry?
答案 1 :(得分:1)
git stash list
可能会给您您想要的东西。
如果您使用git stash save
或git stash push
保存了存储,则git在存储中添加了一条注释,其中包括分支名称和特定的提交:
$ git stash list
stash@{0}: WIP on master: 039142b Initial commit
即使您为存储库指定了自定义名称,git仍会保存分支名称:
$ git stash save "My stash"
Saved working directory and index state On master: My stash
$ git stash list
stash@{0}: On master: My stash