如何仅解锁某些文件?

How to unstash only certain files?

提问人:morpheus 提问时间:3/7/2013 最后编辑:alexmorpheus 更新时间:9/28/2023 访问量:248345

问:

我把我的零钱藏了起来。现在我只想从储藏室中解藏一些文件。我该怎么做?

git git-stash

评论

5赞 Richard 3/7/2013
我认为你必须应用整个储藏室,但你可以有选择地重新储藏。
5赞 alex 3/17/2016
@AbdouTahiri 藏匿处有什么问题?
52赞 dudewad 5/11/2016
@AbdouTahiri 呃......Git Stash 是一个合法的功能,非常有用。我每天都使用它。比如说,一位同事需要我审查一些东西,但我正处于一个复杂的变更集中。我不会为了切换分支而提交一堆损坏的代码。我要藏起来,切换分支,审查,切换回来,取消藏起来。你是否愿意详细说明为什么 git stash 被认为是“不推荐”的?仅仅因为你的 git 藏匿历史是混乱的和难以阅读的,并不意味着其他人都是。凌乱的 git 存储集只是糟糕的工作流程,而不是 Git 的缺陷。
10赞 dudewad 5/11/2016
@alex什么都没有。git s藏起来没什么问题。继续使用它。
5赞 Jeff Puckett 9/7/2016
如何从 git 存储中提取单个文件(或对文件的更改)的可能副本?

答:

671赞 VonC 3/7/2013 #1

如下所述,并在“如何从 git 存储中提取单个文件(或对文件的更改)?”中详细说明,您可以应用 use git checkoutgit show 来还原特定文件。

git checkout stash@{0} -- <filename>

在 Git 2.23+(2019 年 8 月)中,使用 git restore,它取代了令人困惑的 git checkout 命令

git restore --source=stash@{0} -- <filename>

这确实覆盖了:确保您没有进行本地修改,或者您可能希望合并隐藏的文件filename

(正如 Jaime M. 所评论的那样,对于某些 shell,如 tcsh,您需要转义特殊字符,语法为:git checkout 'stash@{0}' -- <filename>)

或将其保存在另一个文件名下:

git show stash@{0}:<full filename>  >  <newfile>

(请注意,这里是相对于项目顶级目录的文件的完整路径名(想想:相对于))。<full filename>stash@{0}

Yucer 在评论中建议:

如果要手动选择要从该文件应用的更改:

git difftool stash@{0}..HEAD -- <filename>
# or
git checkout -p stash@{0} -- <filename>

Vivek在评论中补充道:

看起来 “” 恢复了执行存储时的文件版本 -- 它应用(仅)该文件的隐藏更改。
要执行后者,请执行以下操作:
git checkout stash@{0} -- <filename>

git diff stash@{0}^1 stash@{0} -- <filename> | git apply

(正如 Peterflynn 所评论的那样,在某些情况下,您可能需要从传统的 diff 路径中删除一个 () 前导斜杠)| git apply -p1p1


如评论:“unstash”(),则:git stash pop

  • 将要保留的内容添加到索引 (git add)
  • 存放其余部分:git stash --keep-index

最后一点是允许您在存储其他文件的同时保留一些文件。
如何从已更改的多个文件中仅存储一个文件”中对此进行了说明。

评论

6赞 Andrey 12/22/2014
如果由于文件冲突而无法这样做,则此操作不起作用。在这种情况下,Balamurugan A 的回答对我有用。git stash pop
1赞 yucer 6/29/2016
如果要手动选择要从该文件应用哪些更改,可以使用 git difftool stash@{0}..HEAD -- <文件名>
6赞 Vivek 10/13/2016
看起来“git checkout stash@{0} -- <filename>” 恢复了截至执行存储时的文件版本 -- 它不应用(仅)该文件的隐藏更改。要执行后者:“git diff stash@{0}^1 stash@{0} -- <filename> |git apply”
1赞 VonC 9/5/2017
@JaimeM。谢谢。我已将您的评论包含在答案中,以提高知名度。
1赞 DylanYoung 10/17/2017
假设这意味着,在我看来,在大多数情况下可能会,这只能部分回答这个问题。然后,您如何从存储中删除有选择地应用的部分,以避免以后在弹出剩余更改时发生冲突和/或混淆?unstashpop
13赞 Ben Jackson 3/7/2013 #2

如果您(没有冲突),它将在应用后删除存储。但是,如果您,它将应用补丁而不会将其从存储列表中删除。然后,您可以使用以下命令恢复不需要的更改git stash popgit stash applygit checkout -- files...

评论

2赞 theflowersoftime 9/23/2016
为了澄清这篇文章的冲突部分,如果您和存在冲突,则必须手动修复它们,并且不会删除存储。git stash pop
41赞 Mike Monkiewicz 3/8/2013 #3

我认为 VonC 的答案可能是你想要的,但这里有一种方法可以进行选择性的“git apply”:

git show stash@{0}:MyFile.txt > MyFile.txt

评论

4赞 Rhubbarb 11/5/2015
在某些情况下,这可能是您想要的,但请注意,此命令将覆盖而不是与任何工作目录更改合并。
0赞 Tom Russell 10/26/2016
这对我有用,因为我只是想复制一个只存在于储藏室中的文件,而不关心任何事情。checkout
1赞 Ian Kemp 6/9/2017
对于 Windows PowerShell: - 反引号对于 PS 来说是必需的,以便不专门解释大括号,并且 是必需的,因为 PS 的 > 运算符默认为 UTF-16(实际上是 UCS-2),这可能不是您想要的。@Balamurugan A 的答案不受这些问题的影响。git show stash@`{0`}:Path/To/MyFile.txt |sc Path/To/MyFile.txtsc
132赞 Balamurugan A 3/21/2014 #4
git checkout stash@{N} <File(s)/Folder(s) path> 

例如。 要仅恢复上次存储的 ./test.c 文件和 ./include 文件夹,

git checkout stash@{0} ./test.c ./include

评论

13赞 4levels 6/20/2014
这是正确答案!单行命令仅应用特定文件中的隐藏更改,就像一个魅力!
2赞 Vivek 10/13/2016
要应用(仅)文件的隐藏更改:“git diff stash@{N}^1 stash@{N} -- <filename> |git apply”
0赞 Rajeev Ranjan 10/18/2017
这也适用于我。只需有选择地从储藏室中检出需要使用的文件,您就完成了。我被困在这个我在创建藏匿处时使用的标志中。-a
1赞 msouth 11/6/2019
@4levels我认为“应用隐藏的更改”不是发生的事情,对吧?我认为“用 s藏匿的副本覆盖你所拥有的任何东西”就是发生的事情。
18赞 LachoTomov 5/16/2018 #5

还有一种方式:

git diff stash@{N}^! -- path/to/file1 path/to/file2  | git apply -R

评论

4赞 cambunctious 12/8/2019
这是IMO唯一的正确答案。使用 or 会盲目地覆盖您的文件,而不仅仅是应用更改。“另一种方式”是轻描淡写的。checkoutshow
3赞 ThomasH 1/15/2020
我没有得到您想要针对工作区中的同一文件进行比较。省略第二条路径对我来说很好。- 我使用选项收到一条错误消息(“反向应用补丁”,试图修补隐藏的版本?!所以我的工作版本看起来像.path/to/file2-Rgit diff stash@{N}^! -- path/to/file | git apply -
2赞 John Mee 1/24/2020
“补丁失败”?尝试 3 路合并。...| git apply -3 -
0赞 kxr 8/20/2020
diff stash@{N}^!已经生成了前向差异,所以省略-R
0赞 Alwyn Schoeman 4/16/2021
这^!在我的情况下不起作用,所以我最终做到了git diff stash@{N} -- path/to/file | git apply -R
41赞 Black 6/7/2018 #6

首先列出所有藏匿处

git stash list

stash@{0}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{1}: WIP on Produktkonfigurator: 132c06a5 Cursor bei glyphicon plus und close zu zeigende Hand ändern
stash@{2}: WIP on master: 7e450c81 Merge branch 'Offlineseite'

然后显示哪些文件在存储中(让我们选择存储 1):

git stash show 1 --name-only

//Hint: you can also write
//git stash show stash@{1} --name-only

 ajax/product.php
 ajax/productPrice.php
 errors/Company/js/offlineMain.phtml
 errors/Company/mage.php
 errors/Company/page.phtml
 js/konfigurator/konfigurator.js

然后应用您喜欢的文件:

git checkout stash@{1} -- <filename>

或整个文件夹:

git checkout stash@{1} /errors

它也可以在没有的情况下工作,但建议使用它们。看这个帖子。--

通常将双连字符识别为信号 停止选项解释并处理以下所有参数 按照字面。

评论

1赞 Ramin Firooz 12/23/2018
我尝试了很多方法,这种方式是我需要的。我遇到了一个问题,该问题引发了未跟踪文件的错误。谢谢。git stash pop
15赞 Janac Meena 1/15/2019 #7

对于 Windows 用户:大括号在 PowerShell 中具有特殊含义。您可以用单引号括起来,也可以用反引号转义。例如:

git checkout 'stash@{0}' YourFile

如果没有它,您可能会收到错误:

Unknown switch 'e'

4赞 Vy Do 12/11/2020 #8

对于考试

git stash show --name-only

结果

ofbiz_src/.project
ofbiz_src/applications/baseaccounting/entitydef/entitymodel_view.xml
ofbiz_src/applications/baselogistics/webapp/baselogistics/delivery/purchaseDeliveryDetail.ftl
ofbiz_src/applications/baselogistics/webapp/baselogistics/transfer/listTransfers.ftl
ofbiz_src/applications/component-load.xml
ofbiz_src/applications/search/config/elasticSearch.properties
ofbiz_src/framework/entity/lib/jdbc/mysql-connector-java-5.1.46.jar
ofbiz_src/framework/entity/lib/jdbc/postgresql-9.3-1101.jdbc4.jar

然后弹出存储在特定文件中

git checkout stash@{0} -- ofbiz_src/applications/baselogistics/webapp/baselogistics/delivery/purchaseDeliveryDetail.ftl

其他相关命令

git stash list --stat
get stash show
3赞 abdella 5/15/2023 #9

对于Windows用户来说,为了避免在内部引用的需要,如下图所示Unknown switch 'e'stash@{0}

git restore --source='stash@{0}' -- <filename>

0赞 Jangwoong Kim 8/29/2023 #10
git stash apply // apply all files
git reset . // reset all
git add <wanted_file> // add only wanted file(s)
git checkout . // negate changes of the other files

评论

3赞 Jeremy Caney 8/30/2023
感谢您有兴趣为 Stack Overflow 社区做出贡献。这个问题已经有相当多的答案,包括一个已经得到社区广泛验证的答案。你确定你的方法以前没有给出过吗?如果是这样,解释你的方法有何不同,在什么情况下你的方法可能更受欢迎,和/或为什么你认为前面的答案不够充分,这将是有用的。你能编辑你的答案以提供解释吗?