问题描述
我正在努力从我的 MacO 中删除 Flutter,并使用命令 git stash save --keep-index,它删除了我 Mac 上的所有内容。我的笔记本电脑上有非常重要的文件,真的很需要这些文件。 非常感谢您的帮助。
提前致谢。
解决方法
TL;DR:git reset --hard && git stash pop
。不过请先阅读其余部分!
常规 git stash save
或 git stash push
的工作原理是:
- 进行两次提交,1no 分支;2
- 正在运行
git reset --hard
。
使用 git stash save
运行的 --keep-index
修改了第二步:而不是 git reset --hard
,Git 检查在第一步中进行的 index 提交。 >
这种做法背后的想法很简单。我们从这样一个事实开始,即 Git 进行new 提交不是来自您工作树中的内容,而是来自 Git 索引中的内容。然后,在这个事实之上,我们添加了这样一个想法,即有测试程序(编译器、linter、样式检查器等)读取一个充满文件的目录,例如您的工作树文件,以告诉您是否这些文件是 Good™ 还是 Bad.™
为了让这些不同的测试程序完成它们的工作,那么,我们需要接受提议的提交——它通常在 Git 的索引中,而不是在你的工作树中——并把它放在某个地方。然后我们就可以运行测试程序了。如果它认为你提出的提交是好的,你可以做出那个提交。如果它发现您提议的提交有问题,您可以修复它们并重试。
那么:git stash
应该把这个提议的提交放在哪里?也就是说,我们需要一棵树,就像你的工作树一样,里面装满了 Git 索引中的文件。有人想出的答案是:让我们把它放在你的工作树中。 但这意味着 Git 必须销毁你的工作树的内容!但是——等等—— git stash
刚刚保存您的工作树的内容,在它刚刚制作的这两个无分支提交之一中!所以现在摧毁它肯定没问题,因为它被保存了! stash
命令可以删除所有 那些 文件并将它们替换为 index 提交中的文件。
这就是 --keep-index
所做的。这就是 --keep-index
的全部要点:由于 git stash
已经进行了两次(或三个,每个脚注 1)提交,这为清除创造了足够的空间 em> 所有文件,并将在“在无分支上进行一些提交”步骤中所做的索引提交中的文件放入它们的位置。现在您可以测试这些文件,如果它们很好,就提交它们。
这种方法有一个大问题3(还有许多小问题),但它确实有效:你运行,例如,git stash --keep-index
或 git stash -a --keep-index
,然后运行linter 或任何你想要的程序,然后运行 git reset --hard
,然后运行 git stash pop
来应用并删除存储并放置所有东西——你的工作树和 Git 的索引——回到你运行 git stash
之前的样子。 linter 的错误(如果有的话)仍然在您的屏幕上,现在您可以修复它们。如果没有错误,现在您可以运行 git commit
。
然而,这确实让 git stash --keep-index
成为粗心大意的陷阱,因为 git stash pop
会尝试将保存的工作树应用到保存然后放入-你的工作树索引。如果你有一个“干净”的索引——如果 git status
,在 git stash
命令之前,会说没有“暂存以进行提交”的更改,但有些更改“不暂存以进行提交”——一切没问题,一个简单的 git stash pop
就足够了。否则,您首先需要 git reset --hard
......并且您必须意识到这会破坏您在自git stash save --keep-index
之后所做的任何工作。
1这两个提交分别保存 Git 索引和工作树的内容。如果您添加 -u
或 -a
选项(它们的长拼写,--include-untracked
/ --all
,在这里做完全相同的事情),git stash
添加一个 第三次提交包含额外文件,并添加第三步,从您的工作树中删除存储在第三次提交中的每个文件。
2请记住,任何提交都可以在零个、一个、两个、十个甚至数百万个分支上(如果有的话)。通过确保这两个提交完全没有分支,git stash
试图让您更容易“认为”这些提交可以从 all 获得em> 分支。我不认为这是一个特别好的主意,因为所有提交总是在任何时候都可用,但这就是 git stash
的工作原理。
3最大的问题是,如果您的工作树和索引与当前提交匹配,那么 git stash --keep-index
什么都不做。这使得自动化过程变得不可能(或者至少太困难以至于人们不断出错):人们在执行 linting 之前编写使用 git stash --keep-index
的预提交钩子,然后执行 git reset --hard && git stash pop
,如果git stash --keep-index
什么也没做,这会弹出其他一些藏匿处,带来可怕的副作用。