git删除旧提交

时间:2018-05-08 12:55:15

标签: git github commit rebase

我犯了一个愚蠢的错误并意外地将一个node_modules文件夹提交给我的本地git然后将其推送到github。这是一个巨大的文件夹,任何下载我的repo的人也会在旧提交中下载此文件夹。我一直试图用rebase --ontorebase -i删除提交但没有运气。这就是我git log的样子。

$ git log --oneline
44549c5f (HEAD -> alex/matUI, origin/alex/matUI) fighting with gitignore
a5a5a79c changed ui to material   ##<---- remove me!
dbec4ab3 converting to material ui      ##<---- remove me!
cd4352f6 (origin/master, origin/HEAD, master) Merge pull request #1 from notsmart/addFullstack
a058bf1e moved files to new repo
80c82607 Added README.md

您如何删除这些提交?

2 个答案:

答案 0 :(得分:2)

你必须做两件事:

  1. 在本地删除这些提交
  2. 强行推动它们以覆盖原点上的分支
  3. 编辑:实际上备份将首先删除的文件,因为此方法会将它们从文件系统中删除。

    首先:

      

    git rebase -i HEAD~4

    现在你有一个开放的编辑器,其行与你写的类似。删除您不想要的提交行。保存并退出编辑器。

    检查*this是否正确。

    然后:

      

    git push -f

    <强>解释

    首先,您开始了一个交互式历史编辑会话。注释时,您可以在编辑器中找到以下选项。您可以执行许多操作,例如通过删除行来删除提交,将它们压缩在一起,通过重新排序行等进行重新排序等。

    然后删除了提交行并保存。发生了什么是git尝试创建新的提交链以应用您想要的更改。实际上创建了新的提交(提交的一部分链接到前一个提交),因此已经更改了提交的新哈希(因为从技术上讲它们是新的)。你会看到你的HEAD上不再有origin / alex / matUI(在this中)。

    最后你用力推了推。这用你当前的alex / matUI覆盖了origin / alex / matUI。这实际上会覆盖你的HEAD所指向的任何分支,并且与原点上的分支绑在一起(你的alex / matUI与origin / alex / matUI绑定,这不是魔术,它是一个明确的领带,您可以手动创建,也可以在拉/克隆时创建它。通常git log是保守的,只允许在分支提示后添加。 git log通过这种力量。使用力量卢克:)

答案 1 :(得分:1)

您可以应用的任何解决方案都将成为历史记录重写。这意味着它会对你的repo副本产生负面影响,并且如果他们在尝试恢复时做错了,它可能会撤消你的修复。

因此,在公开的回购中出现这种情况是一种非常不幸的情况,但如果您碰巧知道没有多少人(或许没有人)克隆它,那么在实践中可能并不太糟糕。重点是,以一种可以让所有回购用户都知道的方式传达您正在做的事情。

(通常我会说你需要协议/协调任何拥有回购副本的人;在这里,如果你认为它是你的回购,你让其他人克隆,我想你可以说只是一个协调的衡量标准很好;但除非你限制推送到原点,否则有人做错误修复&#34;并重新引入错误提交的可能性存在,无论我们怎么说都是&#34右&#34;。)

无论如何,要注意上述情况,但它无法得到帮助。你必须重写历史,问题是如何。

您可以删除自添加node_modules文件夹以来所做的所有提交,但当然您将从这些提交中丢失所有其他更改。在没有丢失其他历史记录(以及没有第三方工具)的情况下摆脱node_modules 的最简单方法是git filter-branch

当然你想确保你在本地拥有所有裁判。因为您的回购可能是您正在复制到github的真实原件,所以应该没问题。但是如果需要的话,你可以获取甚至做一个--mirror克隆的原点来开始。然后

git filter-branch --index-filter 'git rm --cached --ignore-unmatch -r node_modules' -- --all

如果您的提交在node_modules之外没有任何更改,并且想要放弃这些提交,则可以在--prune-empty分隔符之前添加--选项。

(在具有大量历史记录(许多提交)的仓库中,这可能会很慢;在这种情况下,您可能会考虑使用第三方工具,如BFG Repo Cleaner,这是一种更专业的工具,用于删除大量/不需要的来自历史的文件(而不是filter-branch,这是一个更通用的工具)。)

在您运行此操作并检查您的历史记录是否正常后,您将需要对本地仓库进行一些清理。可以说最简单的方法是用它来创建一个新的克隆。

cd ..
git clone file://localhost/path/to/old/repo newrepo

如果您要清理原始的本地仓库,则需要删除一组&#34;备份参考&#34; filter-branch已创建(refs/original下),可能会清除reflog,然后使用gc实际丢弃不需要的对象。

至于github上的repo,再次可能是删除它并重新创建它将是最简单的事情 - 特别是如果你有很多重写的分支。或者,您可以强制推送(git push -f)每个重写的分支,并查阅github文档以获取有关服务器端gc的信息