git 为什么不能将 stash 应用到工作目录?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10508903/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why can't stash be applied to the working directory?
提问by Miguel Angelo
I cannot apply stash back to the working directory.
我无法将 stash 应用回工作目录。
Little story:
小故事:
First I tried to push some committed changes, but it said: "no you can't, pull first"... OK then, I'll pull things from GitHub and then push my changes. When I tried to pull, it said that I had changes that would be overwritten, and that I should stash my changes. OK, I stashed the changes... did the pull, and push the committed changes. But now, I cannot restore the uncommitted changes I was working on.
首先,我尝试推送一些已提交的更改,但它说:“不,您不能,先拉取”……好吧,我将从 GitHub 拉取内容,然后推送我的更改。当我尝试拉取时,它说我的更改将被覆盖,并且我应该隐藏我的更改。好的,我隐藏了更改...做了拉动,并推送了已提交的更改。但是现在,我无法恢复我正在处理的未提交的更改。
This is the error:
这是错误:
MyPath/File.cs already exists, no checkout
Could not restore untracked files from stash
For sure I don't yet understand all the concepts of git, they confuse me a bit... maybe I did something wrong.
当然我还没有理解 git 的所有概念,它们让我有点困惑……也许我做错了什么。
It would be great if someone could help me solve this... I've been searching google and everything for more than an hour now, and I didn't come to a solution yet.
如果有人能帮我解决这个问题,那就太好了……我已经搜索了 google 和所有东西一个多小时了,但我还没有找到解决方案。
Help is much appreciated. Thanks!
非常感谢帮助。谢谢!
回答by blahdiblah
It sounds like your stash included an untracked file that was subsequently added to the repo. When you try and check it out, git rightly refuses because it would be overwriting an existing file.
听起来您的存储包含一个未跟踪的文件,该文件随后被添加到存储库中。当您尝试检查它时,git 正确地拒绝了,因为它会覆盖现有文件。
To fix, you could do something like deleting that file (it's okay, it's still in the repo), applying your stash, and then replacing the stashed version of the file with the in-repo version as appropriate.
要修复,您可以执行一些操作,例如删除该文件(没关系,它仍在 repo 中),应用您的存储,然后根据需要将文件的隐藏版本替换为 in-repo 版本。
Edit:It's also possible that the file has only been created in the working tree withouthaving been added to the repo. In this case, don't simply delete the local file, rather:
编辑:该文件也可能只在工作树中创建,而没有添加到存储库中。在这种情况下,不要简单地删除本地文件,而是:
- move it somewhere else
- apply the stash
- manually merge the two file versions (working tree vs. moved).
- 把它移到别处
- 应用藏匿处
- 手动合并两个文件版本(工作树与移动)。
回答by Koraktor
The safest and easiest way would probably be stashing things again:
最安全和最简单的方法可能是再次藏东西:
git stash -u # This will stash everything, including unstaged files
git stash pop stash@{1} # This will apply your original stash
Afterwards if you're happy with the result you may call
之后,如果您对结果感到满意,您可以致电
git stash drop
to remove your "safe" stash.
删除您的“安全”藏匿处。
回答by studgeek
As mentioned by @bentolo, you can manually delete the files it is complaining about, switch branches, and then manually add them back. But I personally prefer to stay "within git".
正如@bentolo 所提到的,您可以手动删除它抱怨的文件,切换分支,然后手动将它们添加回来。但我个人更喜欢“在 git 范围内”。
The best way to do this is to convert the stash to a branch. Once it is a branch you can work normally in git using the normal branch-related techniques/tools you know and love. This is actually a useful general technique for working with stashes even when you don't have the listed error. It works well because a stash really is a commit under the covers (see PS).
最好的方法是将 stash 转换为分支。一旦它成为一个分支,您就可以使用您熟悉和喜爱的与分支相关的普通技术/工具在 git 中正常工作。这实际上是一种有用的通用技术,即使您没有列出的错误,也可以使用 stashes。它运行良好,因为 stash 确实是隐藏的提交(请参阅 PS)。
Converting a stash to a branch
将存储转换为分支
The following creates a branch based on the HEAD when the stash was created and then applies the stash (it does not commit it).
下面在创建存储时基于 HEAD 创建一个分支,然后应用存储(它不提交它)。
git stash branch STASHBRANCH
Working with the "stash branch"
使用“stash 分支”
What you do next depends on the relationship between the stash and where your target branch (which I will call ORIGINALBRANCH) is now.
您接下来要做什么取决于存储与您的目标分支(我将其称为 ORIGINALBRANCH)现在所在的位置之间的关系。
Option 1 - Rebase stash branch normally (lots of changes since stash)
选项 1 - 正常重新设置 stash 分支(自 stash 以来发生了很多变化)
If you have done a lot of changes in your ORIGINALBRANCH, then you are probably best treating STASHBRANCH like any local branch. Commit your changes in STASHBRANCH, rebase it on ORIGINALBRANCH, then switch to ORIGINALBRANCH and rebase/merge the STASHBRANCH changes over it. If there are conflicts then handle them normally (one of the advantages of this approach is you can see and resolve conflicts).
如果您对 ORIGINALBRANCH 进行了大量更改,那么您可能最好像对待任何本地分支一样对待 STASHBRANCH。在 STASHBRANCH 中提交您的更改,在 ORIGINALBRANCH 上对其进行变基,然后切换到 ORIGINALBRANCH 并在其上变基/合并 STASHBRANCH 更改。如果存在冲突,则正常处理它们(这种方法的优点之一是您可以看到并解决冲突)。
Option 2 - Reset original branch to match stash (limited changes since stash)
选项 2 - 重置原始分支以匹配 stash(自 stash 以来更改有限)
If you just stashed while keeping some staged changes, then committed, and all you want to do is get the additional changes that where not staged when you stashed you can do the following. It will switch back to your original branch and index without changing your working copy. The end result will be your additional stash changes in your working copy.
如果您只是在保留一些暂存更改的同时进行隐藏,然后提交,并且您想要做的就是获取隐藏时未暂存的其他更改,则可以执行以下操作。它将切换回您的原始分支和索引,而无需更改您的工作副本。最终结果将是您在工作副本中的额外存储更改。
git symbolic-ref HEAD refs/heads/ORIGINALBRANCH
git reset
Background
背景
Stashes are commits likes branches/tags (not patches)
Stashes 是像分支/标签一样的提交(不是补丁)
PS, It is tempting to think of a stash as a patch (just like it is tempting to think of a commit as a patch), but a stash is actually a commit against the HEAD when it was created. When you apply/pop you are doing something similar to cherry-picking it into your current branch. Keep in mind that branches and tags are really just references to commits, so in many ways stashes, branches, and tags are just different ways of pointing at a commit (and its history).
PS,人们很容易将 stash 视为补丁(就像将提交视为补丁一样),但 stash 在创建时实际上是对 HEAD 的提交。当您申请/弹出时,您正在做类似于将其挑选到当前分支中的操作。请记住,分支和标签实际上只是对提交的引用,因此在许多方面,存储、分支和标签只是指向提交(及其历史记录)的不同方式。
Sometimes needed even when you haven't made working directory changes
有时甚至在您尚未更改工作目录时也需要
PPS, You may need this technique after just using stash with --patch and/or --include-untracked. Even without changing working directories those options can sometimes create a stash you can't just apply back. I must admit don't fully understand why. See http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.htmlfor some discussion.
PPS,在使用带有 --patch 和/或 --include-untracked 的 stash 后,您可能需要这种技术。即使不更改工作目录,这些选项有时也会创建一个您不能直接应用的存储。我必须承认不完全理解为什么。有关一些讨论,请参阅http://git.661346.n2.nabble.com/stash-refuses-to-pop-td7453780.html。
回答by qwertzguy
The solution:You need to delete the file in question, then try to stash pop/apply again and it should go through. Don't delete other files, just the ones mentioned by the error.
解决方案:您需要删除有问题的文件,然后再次尝试隐藏 pop/apply,它应该会通过。不要删除其他文件,只删除错误提到的文件。
The problem:Git sucks sometimes. When running git stash -u
it includes untracked files (cool !) but it does notremove those untracked files and does notknow how to apply the stashed untracked files on top of the leftovers (not cool !), which really makes the -u
option pretty useless.
问题:Git 有时很糟糕。运行时git stash -u
它包含未跟踪的文件(很酷!),但它不会删除那些未跟踪的文件,也不知道如何将隐藏的未跟踪文件应用到剩余文件上(不酷!),这确实使该-u
选项毫无用处。
回答by ciphersimian
To apply the code differences in the stash as a patch instead, use the following command:
要将存储中的代码差异作为补丁应用,请使用以下命令:
git stash show --patch | patch -p1
回答by Helder Pereira
This has happened to me numerous times, I stash untracked files with git stash -u
which end up being added to the repo and I can't apply the stashed changes anymore.
这在我身上发生过很多次,我存储了未跟踪的文件,git stash -u
这些文件最终被添加到 repo 中,我无法再应用隐藏的更改。
I couldn't find a way to force git stash pop/apply
to replace the files, so I first remove the local copies of the untracked files that were stashed (be careful as it will delete any changes that haven't been committed) and then apply the stashed changes:
我找不到强制git stash pop/apply
替换文件的方法,所以我首先删除了隐藏的未跟踪文件的本地副本(小心,因为它会删除任何尚未提交的更改),然后应用隐藏的更改:
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply
Finally, I use git status
, git diff
and other tools to check and add back portions from the removed files if there's something missing.
最后,如果缺少某些内容,我会使用git status
,git diff
和其他工具检查并添加已删除文件中的部分。
If you have uncommitted changes that you want to keep, you can create a temporary commit first:
如果您想保留未提交的更改,您可以先创建一个临时提交:
git add --all
git commit -m "dummy"
rm `git ls-tree -r stash@{0}^3 --name-only`
git stash apply
Use whatever tools suits you to merge the previously committed changes back into the local files, and remove the dummy commit:
使用适合您的任何工具将先前提交的更改合并回本地文件,并删除虚拟提交:
git reset HEAD~1
回答by Nalan Madheswaran
Try this:
尝试这个:
git checkout stash -- .
git checkout stash -- 。
回答by deasserted
My similarly blocked pop operation was because leftover ignoredfiles (see the .gitignore file). Git status showed me tracked and untracked, but my activities didn't clean up the ignored files.
我类似的阻止弹出操作是因为剩余的忽略文件(请参阅 .gitignore 文件)。Git 状态显示我已跟踪和未跟踪,但我的活动并没有清理被忽略的文件。
Details:I had used git stash save -a
, checked out the master to compile and see original behavior, then tried to put it all back to continue editing. When I checked out my branch and tried to pop, my ignored files were still there from before the stash save. That is because the checkout of master only affected committed files -- it didn't wipe the ignored files. So the pop failed, essentially saying it didn't want to restore my stashed ignored files on top of files that were still there. It is unfortunate that I couldn't figure out a way to start a merge session with them.
详细信息:我曾经使用过git stash save -a
,检查了大师进行编译并查看原始行为,然后尝试将其全部放回以继续编辑。当我检出我的分支并尝试弹出时,我被忽略的文件在存储保存之前仍然存在。那是因为 master 的检出只影响提交的文件——它没有擦除被忽略的文件。所以 pop 失败了,基本上是说它不想在仍然存在的文件之上恢复我隐藏的被忽略的文件。不幸的是,我无法找到与他们开始合并会话的方法。
Ultimately, I used git clean -f -d -x
to remove the ignored files. Interestingly, of my ~30, 4 files still remained after cleaning (buried in subdirectories). I'll have to figure out what category they are in, that they had to be manually deleted.
最终,我曾经git clean -f -d -x
删除被忽略的文件。有趣的是,在我的大约 30 个文件中,清理后仍然有 4 个文件(埋在子目录中)。我必须弄清楚它们属于哪个类别,必须手动删除它们。
Then my pop succeeded.
然后我的流行音乐成功了。
回答by VonC
With Git 2.14.x/2.15 (Q3 2017), qwertzguy's solutionfrom 2014 won't be necessary anymore.
使用 Git 2.14.x/2.15(2017 年第三季度),将不再需要qwertzguy2014 年的解决方案。
Before Q3 2017, you had to delete the file in question, then try to stash pop/apply again.
With the next Git release, you won't have to do that.
在 2017 年第三季度之前,您必须删除有问题的文件,然后再次尝试隐藏 pop/apply。
在下一个 Git 版本中,您将不必这样做。
See commit bbffd87(11 Aug 2017) by Nicolas Morey-Chaisemartin (nmorey
).
(Merged by Junio C Hamano -- gitster
--in commit 0ca2f32, 23 Aug 2017)
请参阅Nicolas Morey-Chaisemartin ( ) 的commit bbffd87(2017 年 8 月 11 日)。(由Junio C Hamano合并-- --在commit 0ca2f32,2017 年 8 月 23 日)nmorey
gitster
stash
: clean untracked files before resetIf calling
git stash -u
on a repo that contains a file that is not ignored any more due to a current modification of thegitignore
file, this file is stashed but not remove from the working tree.
This is due togit-stash
first doing areset --hard
which clears the.gitignore
file modification and then callgit clean
, leaving the file untouched.
This causesgit stash pop
to fail due to the file existing.This patch simply switches the order between cleaning and resetting and adds a test for this usecase.
stash
:重置前清理未跟踪的文件如果调用
git stash -u
包含由于gitignore
文件的当前修改而不再被忽略的文件的存储库,则该文件将被隐藏但不会从工作树中删除。
这是因为git-stash
首先执行 areset --hard
清除.gitignore
文件修改,然后调用git clean
,保持文件不变。由于文件存在,
这会导致git stash pop
失败。此补丁只是在清理和重置之间切换顺序,并为此用例添加测试。
回答by RahulMohan Kolakandy
The safest way to following stashing
跟踪藏匿的最安全方法
git stash -u
git stash -u
This will stash all including unstaged change
这将隐藏所有包括未分阶段的更改
git stash drop
git 藏匿处
after you are done working on it ,to remove your "safe" stash.
完成工作后,删除您的“安全”藏匿处。