无法将存储应用于工作目录

问题描述 投票:81回答:11

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

小故事:

首先,我试图推动一些改变,但它说:“不,你不能,先拉”...好吧,然后,我会从github拉出东西,然后推动我的改变。当我试图拉动时,它说我的变化会被过度改写,我应该把我的变化藏起来。好吧,我隐藏了变化......做了拉动,并推动了提交的更改。但现在,我无法恢复我正在进行的未经修改的变化。

这是错误:

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

当然我还没有理解git的所有概念,他们让我有点困惑......也许我做错了什么。

如果有人可以帮我解决这个问题会很棒...我现在一直在搜索谷歌和所有东西超过一个小时,我还没有找到解决方案。

非常感谢帮助。谢谢!

git git-stash
11个回答
72
投票

这听起来像你的藏匿包括一个未跟踪的文件,后来被添加到仓库。当你尝试检查出来时,git正确拒绝,因为它会覆盖现有文件。

要修复,你可以做一些事情,比如删除那个文件(没关系,它仍然在repo中),应用你的存储,然后根据需要用in-repo版本替换文件的存储版本。

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

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

-1
投票

使用Git 2.14.x / 2.15(2017年第3季度),将不再需要2014年的qwertzguysolution

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

请参阅commit bbffd87撰写的Nicolas Morey-Chaisemartin (nmorey)(2017年8月11日)。 (由Junio C Hamano -- gitster --合并于commit 0ca2f32,2017年8月23日)

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

如果在包含由于当前修改git stash -u文件而不再被忽略的文件的repo上调用gitignore,则此文件将被保留但不从工作树中删除。 这是因为git-stash首先做了一个reset --hard,它清除了.gitignore文件修改,然后调用git clean,保持文件不变。 这会导致git stash pop因文件存在而失败。

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


-1
投票

跟进存款最安全的方法

git stash -u

This will stash all including unstaged change

git stash drop

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


54
投票

最安全,最简单的方法可能是再次收藏:

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

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

git stash drop

删除你的“安全”存储。


52
投票

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

执行此操作的最佳方法是将存储转换为分支。一旦它成为一个分支,你就可以使用你熟悉和喜爱的常规分支相关技术/工具在git中正常工作。即使您没有列出错误,这实际上也是一种有用的常用技术。它运作良好,因为存储确实是一个隐藏的承诺(见PS)。

Converting a stash to a branch

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

git stash branch STASHBRANCH

Working with the "stash branch"

你接下来要做什么取决于藏匿处和目标分支(我将称之为ORIGINALBRANCH)之间的关系。

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

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

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

如果你只是在保留一些阶段性更改时被隐藏,然后提交,而你想要做的就是获得额外的更改,当你被隐藏时,你可以执行以下操作。它将切换回原始分支和索引,而不会更改您的工作副本。最终结果将是您的工作副本中的其他隐藏更改。

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

Background

Stashes是像树枝/标签(不是补丁)的提交

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

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

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


39
投票

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

问题:Git有时很糟糕。当运行git stash -u时,它包含未跟踪的文件(酷!)但它不会删除那些未跟踪的文件,也不知道如何在剩余的顶部应用隐藏的未跟踪文件(不酷!),这真的使-u选项相当无用。


22
投票

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

git stash show --patch | patch -p1

0
投票

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

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

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

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


0
投票

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

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

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
投票

试试这个:

git checkout stash - 。


-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
© www.soinside.com 2019 - 2024. All rights reserved.