105

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

小故事:

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

这是错误:

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

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

如果有人可以帮我解决这个问题,那就太好了......我已经搜索了一个多小时的谷歌和所有内容,但我还没有找到解决方案。

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

4

12 回答 12

82

听起来您的 stash 包含一个未跟踪的文件,该文件随后被添加到 repo 中。当您尝试检查它时,git 正确地拒绝了,因为它会覆盖现有文件。

要修复,您可以执行一些操作,例如删除该文件(没关系,它仍在 repo 中),应用您的存储,然后根据需要将文件的隐藏版本替换为 in-repo 版本。

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

  1. 把它移到别的地方
  2. 应用存储
  3. 手动合并两个文件版本(工作树与移动)。
于 2012-05-09T01:57:58.303 回答
66

最安全和最简单的方法可能是再次存储东西:

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

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

git stash drop

删除您的“安全”藏匿处。

于 2012-05-10T20:00:04.887 回答
62

正如@bentolo 所提到的,您可以手动删除它抱怨的文件,切换分支,然后手动将它们添加回来。但我个人更喜欢留在“git 内”。

最好的方法是将存储转换为分支。一旦它成为一个分支,您就可以使用您熟悉和喜爱的正常分支相关技术/工具在 git 中正常工作。这实际上是一种有用的通用技术,即使您没有列出的错误,也可以使用 stash。它运作良好,因为 stash 确实是在幕后提交(参见 PS)。

将存储转换为分支

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

git stash branch STASHBRANCH

使用“stash 分支”

您接下来要做什么取决于存储与您的目标分支(我将称之为 ORIGINALBRANCH)现在所在的位置之间的关系。

选项 1 - 通常重新设置 stash 分支(自 stash 以来进行了大量更改)

如果您在 ORIGINALBRANCH 中进行了很多更改,那么您最好将 STASHBRANCH 视为任何本地分支。在 STASHBRANCH 中提交您的更改,将其重新设置在 ORIGINALBRANCH 上,然后切换到 ORIGINALBRANCH 并重新设置/合并 STASHBRANCH 对其的更改。如果存在冲突,则正常处理它们(这种方法的优点之一是您可以看到并解决冲突)。

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

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

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

背景

Stashes 是提交,例如分支/标签(不是补丁)

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

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

PPS,您可能在仅使用带有 --patch 和/或 --include-untracked 的 stash 后需要此技术。即使不更改工作目录,这些选项有时也会创建一个无法应用的存储库。我必须承认不完全理解为什么。有关一些讨论,请参阅http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html

于 2013-01-29T00:35:46.057 回答
41

解决方案:您需要删除有问题的文件,然后尝试再次存储 pop/apply,它应该会通过。不要删除其他文件,只删除错误中提到的文件。

问题: Git 有时很糟糕。运行时git stash -u,它包含未跟踪的文件(酷!),但它不会删除那些未跟踪的文件,也不知道如何将隐藏的未跟踪文件应用到剩余文件之上(不酷!),这确实使该-u选项非常无用。

于 2014-05-19T16:50:52.833 回答
29

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

git stash show --patch | patch -p1
于 2017-10-05T20:29:24.130 回答
2

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

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

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

最后,如果缺少某些内容,我会使用git status,和其他工具检查并从已删除的文件中添加回部分。git 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
于 2018-08-09T17:15:04.477 回答
0

解决此问题的一种简单方法是将现有的冲突文件重命名为非冲突文件。

在您的情况下,重命名File.csFile.new.cs并重新运行git stash apply/pop,这次您不会收到错误,并且会同时拥有File.cs和供File.new.cs您使用。

于 2021-09-20T07:25:54.670 回答
0

尝试这个:

git checkout stash -- .

于 2019-03-12T11:22:15.157 回答
0

我同样被阻止的弹出操作是因为剩余的忽略文件(请参阅 .gitignore 文件)。Git 状态显示我被跟踪和未跟踪,但我的活动没有清理被忽略的文件。

详细信息:我曾经使用过git stash save -a,签出大师编译并查看原始行为,然后尝试将其全部放回去继续编辑。当我检查我的分支并尝试弹出时,我忽略的文件在存储保存之前仍然存在。那是因为 master 的检出只影响提交的文件——它没有擦除被忽略的文件。所以弹出失败了,基本上说它不想在仍然存在的文件之上恢复我隐藏的忽略文件。不幸的是,我无法找到与他们开始合并会话的方法。

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

然后我的pop成功了。

于 2017-05-11T00:18:34.163 回答
-1

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

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

请参阅Nicolas Morey-Chaisemartin ( )的提交 bbffd87(2017 年 8 月 11 日) 。(由Junio C Hamano 合并——提交 0ca2f32中,2017 年 8 月 23 日)nmorey
gitster

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

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

此补丁只是在清理和重置之间切换顺序,并为此用例添加测试。

于 2017-09-03T20:01:03.217 回答
-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
于 2017-01-24T07:12:45.000 回答
-1

跟踪存储的最安全方法

git stash -u

这将隐藏所有内容,包括未分阶段的更改

git 存储下降

完成工作后,删除“安全”存储。

于 2017-09-05T00:38:19.210 回答