2010-12-23 277 views
159

恐怕我找不到像这种特殊情况的东西。如何从git存储库中删除旧的历史记录?

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

我知道我希望成为新存储库根目录的提交。然而,我不能找出正确的git mojo来截断回购从那个提交开始。我猜

的一些变种
git filter-branch 

涉及移植物将是必要的;可能还需要对待我们要分开保存的200多个分支中的每一个,然后将回购补丁一起回收(我需要知道如何执行)。

有没有人做过这样的事情?如果有问题,我已经得到了git 1.7.2.3。

回答

93

只需创建一个新的根提交的父代的graft父代(或空的提交,例如您的存储库的真正的根提交)。例如。 echo "<NEW-ROOT-SHA1>" > .git/info/grafts

创建嫁接后,立即生效;你应该能够看到git log,看到不想要的旧提交已经消失:

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

    Another message 

commit 4a46bc886318679d8b15e05aea40b83ff6c3bd47 (grafted) 
Author: Your Name <[email protected]> 
Date: Thu May 23 22:27:48 2013 +0200 

    Some message 

如果一切如预期,你可以做一个简单的git filter-branch -- --all使其永久化。

当心:过滤分支步骤之后,所有提交的IDS才会有那么使用旧的回购人绝不能使用新的回购任何合并改变。

+5

如今,它似乎是“git的过滤分支 - --all” ... – aanno 2012-12-18 15:01:55

+1

好,营造出“的.git /信息/移植文件和过滤器分支后,我仍然需要一个” git的克隆 - - 没有本地 - 无硬链接“的副本(在此之前制作所有本地跟踪分支)。简单地删除'.git/info/grafts'并不能解决问题! – aanno 2012-12-18 16:18:51

+2

你可能想,当你想缩小到交叉检查http://stackoverflow.com/questions/7654822/remove-refs-original-heads-master-from-git-repo-after-filter-branch-tree-filte您的存储库大小。 – aanno 2012-12-20 08:08:09

41

试试这个方法How to truncate git history

#!/bin/bash 
git checkout --orphan temp $1 
git commit -m "Truncated history" 
git rebase --onto temp $1 master 
git branch -D temp 

这里$1是SHA-1的承诺,你要保持和脚本将创建一个包含$1master,所有的旧的历史之间的所有提交新的分支下降。请注意,这个简单的脚本假定您没有名为temp的现有分支。另请注意,此脚本不会清除旧历史记录的git数据。确认您确实想要丢失所有历史记录后,运行git gc --prune=all && git repack -a -f -F -d。您可能还需要rebase --preserve-merges,但请注意,该功能的git实现并不完美。如果你使用它,手动检查结果。

47

method很容易理解和正常工作。该脚本的参数($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的答案的一个实质性改变,我的编辑被拒绝了,所以这里是信息!

-8
  1. 删除git的数据,RM git的
  2. 的git的init
  3. 添加远程Git
  4. 力推
42

也许为时已晚来发表回复,但此页面Google的第一个结果,它可能仍然有帮助。

如果你想在你的git仓库中释放一些空间,但不想重建所有的提交(rebase或者移植),并且仍然能够从拥有完整仓库的人推/拉/合并,你可以使用 克隆(- 深参数)。

; 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 originalRepo 
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 

PS:混帐的旧版本不支持克隆/推/从/拉至浅回购。

15

如果你想保持上游库与完整的历史,但地方小签,做一浅克隆与git clone --depth=1 [repo]

推提交后,你可以做

  1. git fetch --depth=1修剪老的提交。这使旧提交及其对象无法访问。
  2. git reflog expire --expire-unreachable=now --all。要过期的所有旧的提交及其对象
  3. git gc --aggressive --prune=all删除旧的对象

How to remove local git history after a commit?见。

请注意,您无法将此“浅”存储库推送到其他位置:“浅度更新不允许”。请参阅Remote rejected (shallow update not allowed) after changing Git remote URL。如果你想这样做,你必须坚持嫁接。

1

变基头/主这个错误可能发生

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

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

删除主分支

enter image description here

the n您可以运行此命令

git push -f origin master 

git rebase --onto temp $1 master 
8

我需要读几个答案以及其他一些信息,了解我在做什么。

1.不顾一切超过一定年长提交

文件.git/info/grafts可以定义假父母提交。只有一个提交ID的行说,提交没有父项。如果我们想说,我们只关心最后的2000次提交,我们可以输入:

git rev-parse HEAD~2000 > .git/info/grafts 

混帐REV-解析为我们提供了目前提交的第2000父的提交ID。上述命令将覆盖移植文件(如果存在)。检查它是否在第一位。

2.重写提交历史(可选)

如果你想使这个嫁接假父一个真实的,然后运行:

git filter-branch -- --all 

它会改变所有提交的ID。该存储库的每个副本都需要进行强制更新。

3.清理磁盘空间

我没有做第3步。我想我的副本留在上游兼容。我只是想节省一些磁盘空间。为了忘记所有的旧提交:

git prune 
git gc 

备选:浅拷贝

如果您有其他仓库的浅拷贝,只是想节省一些磁盘空间,您可以更新.git/shallow。但要小心,没有任何东西指向之前的提交。所以你可以运行这样的事情:

git fetch --prune 
git rev-parse HEAD~2000 > .git/shallow 
git prune 
git gc 

浅层作品的入口像移植。但要小心不要同时使用移植物和浅层。至少,在那里没有相同的条目,它会失败。

如果你仍然有一些老引用(标签,分支机构,远程头)那点旧的承诺,他们将不会被清理,你会不会节省更多的磁盘空间。

-1

可以删除的目录,文件,也关系到目录或使用下面提到的jar文件的整个历史[下载]和命令

bfg.jar文件: https://rtyley.github.io/bfg-repo-cleaner/

混帐克隆--bare回购网址 CD repo_dir Java的罐子bfg.jar --delete文件夹文件夹名 混帐引用日志到期--expire =现在--all & &混帐GC --prune =现在--aggressive 混帐推--mirror repo_url

相关问题