2015-10-25 41 views
3

我使用了GitHub的instructions for scrubbing a file from the commit history,但它从我的系统中删除了有问题的文件。这对我来说是令人惊讶的,因为git rm --cached命令本身应该保持文件本身不变。但是,该行为也可以在该页面上的工作示例中看到:尝试在大git filter-branch ...命令前后运行ls从Git历史中删除文件而不删除文件

我使用的是Git 2.6.1。

如何从提交历史记录中删除文件,而不删除文件本身?很明显,我可以做一个备份(我在我的情况下),但这是一个解决方法,而不是一个解决方案。

+1

进行备份是解决方案。 – Schwern

+0

Git主要是一个Unix程序。在Unix中,您不会将每个令人担忧的情况都集成到您的可执行文件中。你(希望)小型单独程序合作实现你的目标。 – PSkocik

回答

4

git-filter-branch完成时,它检出新的分支头。这会将您的工作目录更新为干净的状态。您希望从历史中删除的文件已被删除。预先备份是解决方案。

如果您忘记备份它,仍然可以将其还原! Git需要很长时间才能完成,原来的提交仍然存在。在git-filter-branch之后,将会有一个名为original/refs/heads/master(如果您过滤了master)的分支,其中包含原始提交。你可以从那里恢复文件。

一般来说,您可以使用git reflog恢复过滤器和底座。这是每次登录HEAD时的日志(即,您签出或重新绑定或合并或过滤或...)。例如,在做GitHub的过滤器后,例如,git reflog是...

abaabaf (HEAD -> master, origin/master, origin/HEAD) [email protected]{0}: filter-branch: rewrite 
8ef0c30 (refs/original/refs/remotes/origin/master, refs/original/refs/heads/master) [email protected]{1}: clone: 

我可以使用8ef0c30[email protected]{1}(即的HEAD以前的位置)或original/refs/remotes/origin/masteroriginal/refs/heads/master要回,事情是前过滤器运行。

+0

感谢您的彻底解答。这个问题需要在问题中提到的指南中加以说明。 – shadowtalker

4

首先:

(它需要说的。)

当使用git filter-branch你正在做历史根据你自己(也许越野车)规范在自动方式重写。因此,你应该在做这件事之前备份你的repo,或者在你的repo的新独立克隆上执行操作。

为什么文件还从你的工作消失复制

git filter-branch应用指定的命令给每个适用的承诺。但是,它并没有检查你的工作副本中的这些提交。取而代之的是,默认情况下,它会将它们检出到.git-rewrite/-d选项的目录中。 (参见git filter-branch文档,选项-d <目录>。)

具有重写的适用提交后,GIT中检出所得到的新的分支。由于这是从文件分支(该分支的预重写版本)切换到没有该文件的分支(该分支的重写版本),因此该文件也会从工作副本中删除。

如何保存文件

那么,做一个备份。

(请注意,如果你重写所有部门和所有的标签,在例如在https://help.github.com/articles/remove-sensitive-data/做了标记或分支机构将不再是一个足够的备份。)

你怎么可以,如果你检索文件没有那样做

请参阅Schwern's answer

相关问题