如何删除旧的git历史记录?

Nip*_*ips 19 git git-rewrite-history

我有很多很多(2000+)提交的git存储库,例如:

                 l-- m -- n   
                /
a -- b -- c -- d -- e -- f -- g -- h -- i -- j -- k
                     \
                      x -- y -- z
Run Code Online (Sandbox Code Playgroud)

我想截断旧的日志历史记录 - 从(例如)commit"f"开始删除日志历史记录中的所有提交,但作为存储库的开头.

怎么做?

Chr*_*aes 33

为了不丢失一些历史; 最好先取一下你的存储库:).我们在这里:( <f>是你希望成为新的根提交的提交f的sha)

git checkout --orphan temp <f>      # checkout to the status of the git repo at commit f; creating a branch named "temp"
git commit -m "new root commit"     # create a new commit that is to be the new root commit
git rebase --onto temp <f> master   # now rebase the part of history from <f> to master onthe temp branch
git branch -D temp                  # we don't need the temp branch anymore
Run Code Online (Sandbox Code Playgroud)

如果您有一个遥控器,您希望拥有相同的截断历史记录; 你可以使用git push -f.警告这是一个危险的命令; 不要轻易使用它!如果你想确保你的代码的最后版本仍然相同; 你可以跑git diff origin/master.这应该没有显示任何变化(因为只有历史记录发生变化;而不是文件内容).

git push -f  
Run Code Online (Sandbox Code Playgroud)

以下2个命令是可选的 - 它们可以使您的git repo保持良好状态.

git prune --progress                 # delete all the objects w/o references
git gc --aggressive                  # aggressively collect garbage; may take a lot of time on large repos
Run Code Online (Sandbox Code Playgroud)

  • 听起来我需要什么,但每次运行第三步(git rebase ...)时,我都会遇到冲突。正常吗 (2认同)
  • @ChrisMaes,我也有冲突。我从提交消息中看到,第三个命令尝试在&lt;f&gt;之前应用旧提交 (2认同)
  • 我也遇到冲突了 这可能不适用于大型仓库。 (2认同)
  • 我也遇到了冲突..是否有任何强制变基 (2认同)

axi*_*iac 12

git clone使用该--shallow-since选项可以为您的问题提供可能的解决方案.如果之后只有少量提交,f并且计算它们没有问题,那么您可以使用该--depth选项.

第二个选项(--depth)仅克隆指定的分支.如果您需要其他分支,则可以将原始仓库添加为远程并使用git fetch并检索它们.

如果对结果感到满意,请删除旧存储库并重命名新存储库以替换它.如果旧存储库是远程存储库,则在删除后重新创建它并从新存储库推送到其中.

这种方法具有尺寸和速度的优点.新的repo只包含你想要的提交,不需要运行git prunegit gc删除旧对象(因为它们不在那里).

  • 一个不错的选择.+1 (3认同)
  • 重新创建远程的建议对我不起作用:“ [远程拒绝]开发-&gt;开发(不允许浅更新)”。 (3认同)