为什么无法将隐藏应用到工作目录?


96

我无法将存储应用回工作目录。

小故事:

首先,我尝试推送一些已提交的更改,但它说:“不,您不能,先拉”。好吧,我将从GitHub拉东西,然后推送我的更改。当我尝试拉动时,它表示我所做的更改将被覆盖,并且我应该存储更改。好的,我隐藏了更改...拉了,然后推送了已提交的更改。但是现在,我无法恢复我正在处理的未提交的更改。

这是错误:

MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash

当然,我还不了解git的所有概念,它们使我有些困惑……也许我做错了什么。

如果有人可以帮助我解决这个问题,那就太好了...我已经搜索了Google和所有内容超过一个小时,而我还没有找到解决方案。

非常感谢您的帮助。谢谢!

Answers:


74

听起来您的存储中包含未跟踪的文件,该文件随后被添加到了回购中。当您尝试将其签出时,git正确地拒绝了,因为它将覆盖现有文件。

要解决此问题,您可以执行一些操作,例如删除该文件(没关系,它仍在存储库中),应用存储,然后根据需要使用存储库中的版本替换文件的隐藏版本。

编辑:也有可能仅在工作树中创建了文件,而未将其添加到存储库中。在这种情况下,不要简单地删除本地文件,而是:

  1. 将它移到其他地方
  2. 申请藏匿处
  3. 手动合并两个文件版本(工作树与已移动)。

2
有什么办法可以避免以后再藏东西呢?我来自SVN,它看起来如此向前……您只需更新,解决冲突然后提交即可。Git可以这么难,我需要在循环中添加2个步骤。再次感谢!
米格尔·安吉洛

2
@Miguel:藏起来不是障碍。它是Git提供的附加工具,可让您改善工作流程并避免冲突和不干净的提交。git-scm.com/docs/git-stash
Koraktor 2012年

8
虽然答案是正确的,但我真的不确定git在此方面是否“正确”。文件位于存储库中,因此没有数据丢失的危险。为什么不仅仅应用更改?看到这个线程-git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html
studgeek 2013年

5
我认为这个答案不是最有帮助。git stash应该有助于快速备份本地更改。手动删除一组文件以恢复它会中断流程。git stash branch其他答案中的方法听起来更好,但仍然比所需的手动得多。
bentolor

在相同情况下,此答案对我而言最有效。弹出存储库之后,我进行了合并,就像我一开始所希望的那样。
比利·拉扎罗

58

最安全,最简单的方法可能是重新存储东西:

git stash -u             # This will stash everything, including unstaged files
git stash pop stash@{1}  # This will apply your original stash

之后,如果您对结果满意,可以致电

git stash drop

删除“安全”藏匿处。


2
谢谢您的帮助,使我免于遭受很多痛苦和折磨!
danjarvis,2012年

9
藏书弹出将套用并放下原始藏书。只是为了安全使用apply而不是pop
Hilbrand Bouwkamp

2
实际上pop是组合applydrop,但只会drop如果apply没有冲突的工作。但是可以,apply通常更安全。
Koraktor 2012年

2
假设您要保留的工作目录中没有其他更改。对于这个特定的问题,他暗示(但没有明确说出)他处于干净的状态,但是我想为其他在这里进行本地更改的人指出这一点。
studgeek

1
如果没有解决冲突的问题,这只会解决问题。当他们提交了消息时,您会得到完全相同的消息(例如,使用干净的结帐),然后这不会改变任何事情……
Jasper

56

如@bentolo所述,您可以手动删除其抱怨的文件,切换分支,然后手动将其重新添加。但是我个人更喜欢保持“在git之内”。

最好的方法是将存储转换为分支。一旦它成为一个分支,您就可以使用您知道和喜欢的与分支相关的常规技术/工具在git中正常工作。即使您没有列出的错误,这实际上也是处理隐藏的有用的常规技术。它之所以有效,是因为隐藏实际上是在后台进行的提交(请参阅PS)。

将存储转换为分支

以下内容在创建存储时基于HEAD创建一个分支,然后应用该存储(不提交)。

git stash branch STASHBRANCH

使用“存储分支”

接下来的操作取决于存储区与目标分支(现在称为ORIGINALBRANCH)之间的关系。

选项1-正常重置存储分支(自存储以来的许多更改)

如果您在ORIGINALBRANCH中做了很多更改,那么您最好将STASHBRANCH像任何本地分支一样对待。在STASHBRANCH中提交更改,将其基于ORIGINALBRANCH,然后切换到ORIGINALBRANCH,然后对STASHBRANCH更改进行基础/合并。如果存在冲突,则可以正常处理它们(此方法的优点之一是可以看到并解决冲突)。

选项2-重置原始分支以匹配存储(自存储以来的有限更改)

如果您只是在保留某些已进行的变更的情况下进行藏匿,然后进行提交,那么您要做的就是获得藏匿时未转移的其他更改,则可以执行以下操作。它将切换回原始分支和索引,而无需更改工作副本。最终结果将是您在工作副本中的其他存储更改。

git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset

背景

垃圾是提交,就像分支/标签(不是补丁)

PS,很容易将存储视为一个补丁(就像将提交视为一个补丁一样),但是存储实际上是针对HEAD的提交。当您应用/弹出时,您所做的事情类似于将其挑选到当前分支中。请记住,分支和标签实际上只是对提交的引用,因此在许多方面,隐藏,分支和标签只是指向提交(及其历史)的不同方式。

即使没有更改工作目录,有时也需要

PPS,仅在与--patch和/或--include-untracked一起使用隐藏之后,您可能需要此技术。即使不更改工作目录,这些选项有时也可以创建存储,您不能仅仅将其应用回来。我必须承认不完全理解为什么。有关某些讨论,请参见http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html


5
此答案应标记为解决方案,因为它为如何最有效地解决“锁定的藏匿处”提供了最有用的指导。也许可以通过首先提及“简单删除解决方案”和将分支解决方案作为第二选择来改进它。
bentolor

8
如果您面对这种情况,“ git stash branch STASHBRANCH”似乎不起作用(与pop发生的错误信息完全相同)。您可能需要事先进行一些git reset。

+1我陷入了意大利面条的混乱之中,包括提交,更改和隐藏等。这使我摆脱了困境,感谢studgeek
隐藏

感谢您澄清隐藏物如何不是补丁以及它们如何与HEAD绑定(在隐藏时)。这很有意义。–所以...我想在某些情况下,创建补丁而不是存储比创建补丁更灵活/更方便/更方便(如您所提到的:进行大量更改时),以便可以将其应用于任何地方(并且只是解决冲突的问题)。也许git stash show -p正在帮助那里藏匿 -> * patch *。
卡马菲瑟

39

解决方案:您需要删除有问题的文件,然后尝试再次隐藏pop / apply,它应该可以通过。不要删除其他文件,仅删除错误所提及的文件。

问题: Git有时很烂。运行时,git stash -u它包含未跟踪的文件(很酷!),但是它不会删除那些未跟踪的文件,并且不知道如何将剩余的未跟踪文件应用于剩余的顶部(不很酷!),这实际上使该-u选项变得毫无用处。


3
如果是我的问题,我会接受这个答案。感谢@qwertzguy,您的回答解决了我的问题,
Kobus Myburgh 2014年

我自己遇到了同样的问题,直到我删除了有问题的文件,git stash pop才适用-然后我与一个文件发生冲突,导致该存储被拒绝。但是要删除未跟踪的文件,而是将它们留在后面。.因此,请注意未来的自我,远离git stash -u
notzippy 2015年

如果您需要受影响的文件的两个版本中的零件,则不建议这样做。
沃尔夫

2
“它不会删除那些未跟踪的文件”,并且不会在中列出它们git stash show。这个答案使灯泡继续发光。
jscs

2
加上Git有时会很烂。
Harish

29

要将隐藏代码中的代码差异作为补丁应用,请使用以下命令:

git stash show --patch | patch -p1

11
通常,最好解释一个解决方案,而不是仅仅发布一些匿名代码行。您可以阅读《我如何编写一个好的答案》,也可以解释完全基于代码的答案
Massimiliano Kraus

这对我git stash show --patch有用,因为来自的补丁程序不包含未跟踪的文件。
史蒂文·肖

这个答案对我很有帮助,因为自从推入存储库以来,由于回购中发生了很多更改,所以无法弹出存储库。
埃里克·芬曼

1

这无数次发生在我身上,我git stash -u隐藏了未跟踪的文件,这些文件最终被添加到了仓库中,我无法再应用隐藏的更改。

我找不到强制git stash pop/apply替换文件的方法,因此我先删除已隐藏的未跟踪文件的本地副本(请小心,因为它将删除尚未提交的所有更改),然后应用已隐藏的更改:

rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

最后,我用的git statusgit diff和其他工具来检查和删除的文件添加回的部分,如果有若有所失。


如果您要保留未提交的更改,则可以先创建一个临时提交:

git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply

使用适合您的工具将先前提交的更改合并回本地文件,并删除虚拟提交:

git reset HEAD~1

0

我类似地阻止了pop操作,是因为剩余的忽略文件(请参阅.gitignore文件)。Git状态向我显示了已跟踪和未跟踪,但是我的活动并未清除被忽略的文件。

详细信息:我曾经使用过git stash save -a,检出了master进行编译并查看原始行为,然后尝试将其放回去继续编辑。当我签出我的分支并尝试弹出时,从隐藏存储开始,我的被忽略文件仍然存在。这是因为检出母版仅影响受影响的已提交文件-它不会擦除忽略的文件。因此弹出失败了,基本上是说它不想将我藏匿的被忽略文件恢复到仍然存在的文件之上。不幸的是,我无法找到一种与它们开始合并会话的方法。

最终,我曾经git clean -f -d -x删除过被忽略的文件。有趣的是,在我的大约30个文件中,清理后仍然保留了4个文件(埋在子目录中)。我必须弄清楚它们属于哪个类别,必须手动删除它们。

然后我的流行音乐成功了。



-1

其他解决方案:

cd to/root/your/project

# Show what git will be remove
git clean -n

# If all is good
git clean -f

# If not all is good, see
git clean --help

# Finish
git stash pop

问题中提到的错误是由堆栈和工作目录中都存在的文件引起的。如果未跟踪此文件,则清理操作只能修复此问题,这肯定并非总是如此(并非OP的情况,因为他是从提取中获取文件的)。
Xavier Poinas

-1

使用Git 2.14.x / 2.15(2017年第三季度),不再需要qwertzguy从2014年开始的解决方案

在2017年第三季度之前,您必须删除有问题的文件,然后尝试再次隐藏弹出/应用。
在下一个Git版本中,您将不必这样做。

参见Nicolas Morey-Chaisemartin()的commit bbffd87(2017年8月11日(由Junio C Hamano合并--commit 0ca2f32中,2017年8月23日)nmorey
gitster

stash:重置前清理未跟踪的文件

如果调用git stash -u包含由于当前修改而不再被忽略的gitignore文件的存储库,则会隐藏该文件,但不会将其从工作树中删除。
这是由于git-stash首先执行a reset --hard会清除 .gitignore文件修改,然后调用git clean,使文件保持不变。由于文件存在而
导致git stash pop失败

该补丁仅在清理和重置之间切换顺序,并为此用例添加了一个测试。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.