如何删除一些尚未提交到本地的提交到本地仓库的文件?

时间:2018-11-17 00:44:00

标签: git

我不小心将一些数据文件提交到本地存储库中,多次提交。我想从本地删除这些数据文件,而不撤消工作副本中的进度。

3 个答案:

答案 0 :(得分:2)

有几种方法。

变基

一种选择是使用git rebase。假设您的历史记录看起来像

... x -- o -- A -- B -- C <--(master)

o中发生不正确添加的地方(可能还有其他更改)。然后你可以说

git rebase -i master~5 master

之所以选择master~5是因为在此示例中,它是一个引用o的父代的表达式。 (当然,您可以根据回购的真实状态替换类似的表达式。)

这将显示一个带有TODO列表的文本编辑器。列表中的每一行将显示您的提交之一。找到提交o的条目,并将该行上的第一个单词从pick更改为edit。然后保存并退出编辑器。

稍作处理后,将出现命令提示符。从索引中删除不需要的文件

git rm --cached file/that/shouldn't/be/committed

然后继续变基。发生冲突的唯一原因是,如果随后的提交也编辑了其中一个文件,在这种情况下,您将通过再次确保从索引中删除文件来解决冲突。

过滤器分支

如果您的“最近的历史记录”很复杂,则rebase会有一些问题。在上面的示例中,只有一个参考(master)可以在其历史记录中“看到” o,并且该参考文献回到o的历史是线性的;所以重新设置就可以了。但是,如果还有其他分支或合并提交,则您可能应该尝试其他方法。

然后,您可以尝试将git filter-branch--index-filter一起使用。您可以编写一个Shell脚本来执行git rm命令。 (这与上面类似,但是您想说

git rm --cached --ignore-unmatch file/that/shouldn't/be/committed

假设您编写了此脚本并将其放在../index-filter.sh处;并且您拥有

之类的历史
                F -- G -- H
               /            \
... x -- o -- A -- B -- C -- M <--(master)
               \
                D -- E <--(feature)

然后您可以说类似

git filter-branch --index-filter ../index-filter.sh -- --all ^master~5

在这种情况下选择master~5是因为它指向xo的父对象)。请注意,我们在^之前放置了master~5;这限制了重写以排除x及其历史记录,因此您只需重写回o

由于某些原因,这可能很重要。

首先,如果您知道尚未推送o,那么您就不会重写任何已共享的内容。 (无论如何,即使相同的路径更早出现,您也不需要更改,对吧?)

此外,通过限制重写的提交次数,可以帮助避免filter-branch花费太长时间(这可能是一个运行时间很长的过程)。


还有其他选项,例如BFG回购清洁器;但对于您的用例而言,这些可能会显得过大了,我建议您首先尝试上述方法之一。

答案 1 :(得分:1)

如果将提交添加到上一次提交(git commit --amend),则可以对其进行修改。

如果这是您的最后一次提交,请在添加文件之前从上一次提交创建分支,然后重新创建不包含新文件的提交,然后将其他提交重新置于新提交的基础上。

然后删除旧分支并重命名新分支。

答案 2 :(得分:-5)

推送提交,进行拉取,删除不需要的文件,提交,推送。 -_-