恐怕我找不到任何类似的场景。

我有一个有很多历史的git存储库:500多个分支,500多个标签,可以追溯到2007年年中。它包含大约19,500个提交。我们希望删除2010年1月1日之前的所有历史记录,使其更小,更容易处理(我们将在存档存储库中保留历史记录的完整副本)。

我知道我想要成为新存储库根的提交。然而,我不能找出正确的git mojo来截断回购以提交开始。我猜是某种变体

git filter-branch

涉及到移植是必要的;可能还需要分别处理我们想要保留的200多个分支中的每个分支,然后将回购补丁重新组合在一起(我确实知道如何做)。

有人做过这样的事吗?我有git 1.7.2.3,如果这很重要的话。


当前回答

对于先前使用——depth克隆的现有存储库

git clone --depth=1 ...

只做

git pull --depth=1 --update-shallow

https://git-scm.com/docs/git-pull

其他回答

根据BFG工具的Git repo,它“像Git -filter-branch一样删除大的或麻烦的blobs,但更快——并且是用Scala编写的”。

https://github.com/rtyley/bfg-repo-cleaner

删除git数据,rm .git git init 添加一个git远程 力推动

注意:为了支持git替换,这个已经被弃用了。

你可以将你的新根提交的父节点移植到没有父节点的节点上(或者移植到一个空的节点上,例如你的存储库的真正根节点上)。例如:echo "<NEW-ROOT-SHA1>" > .git/info/graft

在创建嫁接后,它立即生效;你应该可以查看git日志,看到不想要的旧提交已经消失了:

$ echo 4a46bc886318679d8b15e05aea40b83ff6c3bd47 > .git/info/grafts
$ git log --decorate | tail --lines=11
commit cb3da2d4d8c3378919844b29e815bfd5fdc0210c
Author: Your Name <your.email@example.com>
Date:   Fri May 24 14:04:10 2013 +0200

    Another message
 
commit 4a46bc886318679d8b15e05aea40b83ff6c3bd47 (grafted)
Author: Your Name <your.email@example.com>
Date:   Thu May 23 22:27:48 2013 +0200

    Some message

如果一切看起来都像预期的那样,您可以使用git filter-branch -- --all将其永久化。

注意:在执行过滤分支步骤之后,所有的提交id都将发生变化,因此任何使用旧回购的人都不能与使用新回购的人合并。

在我的情况下,我想分成两个回购,保持历史记录,但清理日志历史从文件过滤出新的回购。

这就是解决方案:

PATHS=path_a path_b
git filter-branch -f --prune-empty --index-filter "git read-tree --empty                                                                                    
git reset \$GIT_COMMIT -- $PATHS " -- --all -- $PATHS

通过这种方式,我得到了一个具有完整提交日志历史的新回购,但仅用于我想保留的路径;

裁判:https://stackoverflow.com/a/56334887/2397613

这种方法简单易懂,效果良好。脚本的参数($1)是一个引用(标签,散列,…),指向您想要保存历史记录的提交。

#!/bin/bash
git checkout --orphan temp $1 # create a new branch without parent history
git commit -m "Truncated history" # create a first commit on this branch
git rebase --onto temp $1 master # now rebase the part of master branch that we want to keep onto this branch
git branch -D temp # delete the temp branch

# The following 2 commands are optional - they keep your git repo in good shape.
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

注意,旧的标签将仍然存在;因此,您可能需要手动删除它们

备注:我知道这和@yoyodin几乎一样,但是这里有一些重要的额外命令和信息。我试着编辑答案,但由于这是@yoyodin的答案的实质性变化,我的编辑被拒绝了,所以这是信息!