Git 隐藏工作区问题

5

我在使用 git stash 时遇到了问题。

例如,我在仓库中有三个文件,分别是 a.txt,b.txt 和 c.txt,并且目录是干净的。

现在我正在修改其中的两个文件:a.txt 和 b.txt

现在我还没有完成这两个文件的更改,所以我通过以下命令将它们存储:

$ git stash save "First Stash"

如果我执行$ git stash list,我会得到以下结果。
stash@{0}: On master: First Stash

如果我修改第三个文本文件 c.txt 并将其作为隐藏的更改,那么不会。
$ git stash save "Second Stash"

如果我执行 $git stash list 命令,最终不会有任何结果。
stash@{0}: On master: Second stash
stash@{1}: On master: First Stash

这里混淆了储藏编号和消息。发生了什么事情? 现在,如果我弹出stash@{0},我会得到第一个储藏内容,但消息被反转了,显示为“Second stash”,但应该是“First Stash”。 这是我的工作流程
admin:stud:/demo/stash_demo> ls
a.txt  b.txt
admin:stud:/demo/stash_demo> echo Hello World >> a.txt
admin:stud:/demo/stash_demo> git stash save "First"
Saved working directory and index state On master: First
HEAD is now at cff03c6 Initail Commit
admin:stud:/demo/stash_demo> echo Hello World >> b.txt
admin:stud:/demo/stash_demo> git stash save "Second"
Saved working directory and index state On master: Second
HEAD is now at cff03c6 Initail Commit

这是我的可用藏品:
admin:stud:/demo/stash_demo> git stash list
stash@{0}: On master: Second
stash@{1}: On master: First

现在我将尝试应用stash@{1},它是第一个stash,并且应该应用于文件a.txt。
admin:stud:/demo/stash_demo> git stash apply `stash@{1}`
# On branch 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:   b.txt
#
no changes added to commit (use "git add" and/or "git commit -a")

如上所述,我获得了最近应用的更改。

如果我尝试不使用反引号“`”,则会出现以下错误。

admin:stud:/demo/stash_demo> git stash apply stash@{1}
fatal: ambiguous argument 'stash@1': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'

дҪ дҪҝз”ЁдәҶВҙstash@{1}Вҙеҗ—пјҢеҢ…жӢ¬еҸҚеј•еҸ·пјҹжҲ‘и®°еҫ—git stash applyдјҡй»ҳй»ҳең°еҝҪз•ҘжңӘзҹҘзҡ„еӯҳеӮЁеҗҚз§°пјҢ然еҗҺеҸӘеә”з”Ёstash@{0}гҖӮ - Koraktor
是的,我确实包含了反引号。 - david.colais
所以,试一下不用它们。 ;) - Koraktor
我尝试过不使用引号,但它会报错,说这是一个模棱两可的参数。我会更新问题并提供完整的输出。 - david.colais
我刚刚注意到,当我使用反引号应用stash@{1}时,会出现“stash@1:命令未找到”的消息,并且最近的stash被应用。我认为我使用的语法是错误的。但是如果我尝试不使用反引号,什么也不会发生。 - david.colais
最终在使用双引号而非反引号后成功运行。 - david.colais
2个回答

5

Git的暂存区(默认情况下)是一个LIFO存储

使用git stash applygit stash pop命令,您将始终获得最后一个被隐藏的补丁(也可以使用stash@{0}引用,0是隐藏中的索引)。如果隐藏一个新的补丁,它将放在其他已隐藏的补丁之上,从而使它们的索引增加一(stash@{0}将变成stash@{1})。

也就是说,如果您想应用或弹出除最后一个隐藏的补丁之外的其他补丁,则需要将其引用传递给命令:

$ git stash apply stash@{1}

即使我应用了stash@{1},我仍然会得到最近的更改应用到repo中。 - david.colais
你确定 stash@{1} 是你想要的吗?例如可以使用 git stash listgit stash show stash@{1} 来验证。 - Koraktor
当我尝试使用 git stash show stash@{1}git stash show stash@{0} 命令时,我得到了相同的输出。无论我应用或弹出哪个存储,我都会得到最近的更改。即使我想要 stash@{1},我也会得到最近的更改。 - david.colais
这意味着stash@{0}stash@{1}都具有相同的内容,因此您可能会错误地存储两次,例如使用git stash; git apply; git stash。如果您确定内容相同,则可以安全地删除其中一个:git stash drop stash@{1} - Koraktor
不,它们不一样。第一次我修改了 a.txt 并将其存储。稍后我修改了 b.txt 并将其存储。现在当我列出所有存储的内容时,我得到的结果是我有2个可用的存储。现在无论我应用或弹出什么,我都会得到 b.txt 应用,然后当我应用另一个存储时,我会得到 a.txt。给我2分钟,我将把整个日志作为问题的编辑粘贴。 - david.colais

1
他们没有混淆! 存储将“提交”(这里不是正确的词,我知道)存储在堆栈中:

http://en.wikipedia.org/wiki/Stack_(abstract_data_type)

所以,pop操作总是获取您在其中放置的最后一件物品。

这种行为是有意设计的。

编辑:如果您需要翻转某些内容,则需要逐个弹出堆栈(stash)中的每个项目-进行真正的提交-并交互式重置或其他操作。

编辑/编辑:执行

git stash pop 

然后提交您的更改(无论此提交是否有用)

然后再次执行git stash pop,再次提交

现在您可以重新排序或删除单个提交-请查看此处:http://gitready.com/advanced/2009/03/20/reorder-commits-with-rebase.html 或搜索交互式重置(再次执行分支时,此概念比存储更强大)


有没有办法获取我存储的第一件东西? - david.colais
就像我在编辑中所说的那样,单独弹出所有内容并进行提交(可能在不同的分支上 - 为了保持干净),然后您最终将得到您存储的第一件事。 - Stephan
顺便说一句:我真的更喜欢快速分支而不是藏匿,因为你可以对所有东西更加掌控。 - Stephan
git stash应用stash@{n}没有意义,因为它总是弹出/应用最近的stash。我已将我的工作流程作为问题中的编辑添加。 - david.colais
我尝试在“编辑/修改”部分更好地描述这个解决方案。 - Stephan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接