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

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

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

git filter-branch

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

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


当前回答

如果你想保留上游存储库的完整历史,但本地签出较小,使用git clone——depth=1 [repo]进行浅克隆。

在执行提交后,您可以执行

Git fetch——depth=1来删除旧的提交。这使得旧的提交及其对象不可访问。 Git reflog expire——expire-unreachable=now——all。使所有旧提交及其对象过期 Git gc—aggressive—prune=全部删除旧对象

参见如何在提交后删除本地git历史记录。

注意,您不能将这个“浅”存储库推到其他地方:“不允许浅更新”。在更改Git远程URL后,请参阅远程拒绝(不允许浅更新)。如果你想做到这一点,你必须坚持嫁接。

其他回答

作为重写历史记录的替代方法,可以考虑使用git replace,就像Pro git书籍中的这篇文章一样。讨论的示例涉及替换父提交来模拟树的开始,同时仍然将完整的历史记录作为一个单独的分支进行安全保管。

如果你想在你的git repo中释放一些空间,但不想重新构建所有的提交(rebase或graft),并且仍然能够从拥有完整repo的人那里推/拉/合并,你可以使用git clone shallow clone(——depth参数)。

; Clone the original repo into limitedRepo
git clone file:///path_to/originalRepo limitedRepo --depth=10

; Remove the original repo, to free up some space
rm -rf originalRepo
cd limitedRepo
git remote rm origin

你可以通过以下步骤来降低你现有的回购:

; Shallow to last 5 commits
git rev-parse HEAD~5 > .git/shallow

; Manually remove all other branches, tags and remotes that refers to old commits

; Prune unreachable objects
git fsck --unreachable ; Will show you the list of what will be deleted
git gc --prune=now     ; Will actually delete your data

如何删除所有git本地标签?

Ps:旧版本的git不支持从/到浅回购的克隆/推/拉。

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

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

当rebase或push到head/master时,可能会发生此错误

remote: GitLab: You are not allowed to access some of the refs!
To git@giturl:main/xyz.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'git@giturl:main/xyz.git'

要解决git仪表板中的这个问题,应该从“受保护的分支”中删除主分支

然后可以执行该命令

git push -f origin master

or

git rebase --onto temp $1 master

这种方法简单易懂,效果良好。脚本的参数($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的答案的实质性变化,我的编辑被拒绝了,所以这是信息!