ebn*_*ter 188 git git-filter-branch
我恐怕找不到任何类似这种特殊场景的东西.
我有一个有很多历史的git存储库:500多个分支,500多个标签,可以追溯到2007年中期.它包含~19,500次提交.我们想在2010年1月1日之前删除所有历史记录,以使其更小更容易处理(我们将在存档库中保留历史记录的完整副本).
我知道我想要成为新存储库的根目录的提交.但是,我不能找出正确的git mojo来截断repo以从那个提交开始.我猜的是一些变种
git filter-branch
Run Code Online (Sandbox Code Playgroud)
涉及移植是必要的; 它也可能是必要的对待每一个我们要分别保持在200多个分支机构,然后修补回购重新走到一起(这是我不知道该怎么做).
有没有人做过这样的事情?如果重要的话,我有git 1.7.2.3.
ape*_*arr 112
只需创建新根提交的父级的移植到没有父级(或者空提交,例如存储库的真正根提交).例如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 <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
Run Code Online (Sandbox Code Playgroud)
如果所有看起来都是预期的,你可以做一个简单git filter-branch -- --all
的使其永久化.
请注意:执行过滤器分支步骤后,所有提交ID都将更改,因此使用旧回购的任何人都不得与使用新回购的任何人合并.
Ale*_* T. 101
发布回复可能为时已晚,但由于此页面是Google的第一个结果,因此它可能仍然有用.
如果你想在你的git仓库中释放一些空间,但又不想重建你所有的提交(rebase或者贪污),并且仍然可以从拥有完整仓库的人推/拉/合并,你可以使用git克隆 浅克隆(--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
Run Code Online (Sandbox Code Playgroud)
您可以通过以下步骤来浅显现有仓库:
; 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
Run Code Online (Sandbox Code Playgroud)
Ps:旧版本的git不支持克隆/推/拉/从浅层回购.
Chr*_*aes 57
这种方法易于理解并且工作正常.script($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
Run Code Online (Sandbox Code Playgroud)
请注意,旧标签仍然存在; 所以你可能需要手动删除它们
评论:我知道这与@yoyodin几乎相同,但这里有一些重要的额外命令和信息.我试着编辑答案,但由于@ yoyodin的答案是一个重大变化,我的编辑被拒绝了,所以这里是信息!
yoy*_*dyn 49
试试这个方法如何截断git历史记录:
#!/bin/bash
git checkout --orphan temp $1
git commit -m "Truncated history"
git rebase --onto temp $1 master
git branch -D temp
Run Code Online (Sandbox Code Playgroud)
这里$1
是SHA-1的承诺,你要保持和脚本将创建一个包含之间的所有提交新的分支$1
,并master
与所有的旧的历史将被丢弃.请注意,此简单脚本假定您没有调用现有分支temp
.另请注意,此脚本不会清除旧历史记录的git数据.运行git gc --prune=all && git repack -a -f -F -d
您确认后,你真正想失去所有的历史.您可能还需要rebase --preserve-merges
警告该功能的git实现并不完美.如果使用,请手动检查结果.
Jef*_*ica 33
作为替代,以改写历史,可以考虑使用git replace
如本文来自临Git的书.讨论的示例涉及替换父提交以模拟树的开头,同时仍将完整历史记录保存为单独的分支以便安全保存.
kop*_*por 22
如果你想保持在上游与仓库全部历史记录,但地方小签,做一浅克隆用git clone --depth=1 [repo]
.
推送提交后,您可以这样做
git fetch --depth=1
修剪旧的提交.这使得旧提交及其对象无法访问.git reflog expire --expire-unreachable=now --all
.使所有旧提交及其对象失效git gc --aggressive --prune=all
删除旧对象另请参阅如何在提交后删除本地git历史记录?.
请注意,您无法将此"浅"存储库推送到其他位置:"不允许浅层更新".更改Git远程URL后,请参阅远程拒绝(不允许浅更新).如果你想这样做,你必须坚持嫁接.
小智 16
我需要阅读几个答案和其他一些信息来了解我在做什么.
1.忽略比某个提交更旧的所有内容
该文件.git/info/grafts
可以为提交定义伪父母.只有一个提交ID的行表示提交没有父级.如果我们想说我们只关心最近的2000次提交,我们可以输入:
git rev-parse HEAD~2000 > .git/info/grafts
Run Code Online (Sandbox Code Playgroud)
git rev-parse为我们提供了当前提交的第2000个父级的提交ID.如果存在,上面的命令将覆盖移植文件.检查它是否在那里.
2.重写Git历史(可选)
如果你想让这个嫁接的假父母成为真正的父母,那么运行:
git filter-branch -- --all
Run Code Online (Sandbox Code Playgroud)
它将更改所有提交ID.需要有力地更新此存储库的每个副本.
3.清理磁盘空间
我没有完成第2步,因为我希望我的副本与上游保持兼容.我只是想节省一些磁盘空间.为了忘记所有旧提交:
git prune
git gc
Run Code Online (Sandbox Code Playgroud)
替代方案:浅拷贝
如果您有另一个存储库的浅表副本并且只想保存一些磁盘空间,则可以更新.git/shallow
.但要小心,没有任何东西指向之前的提交.所以你可以运行这样的东西:
git fetch --prune
git rev-parse HEAD~2000 > .git/shallow
git prune
git gc
Run Code Online (Sandbox Code Playgroud)
浅入口就像贪污一样.但要注意不要同时使用移植物和浅层.至少,那里没有相同的条目,它将失败.
如果您仍然有一些旧引用(标记,分支,远程头)指向较旧的提交,它们将不会被清除,您将不会节省更多的磁盘空间.
这里有太多的答案不是最新的,有些没有完全解释后果。以下是我使用最新 git 2.26 缩减历史记录的方法:
首先创建一个虚拟提交。此提交将显示为截断存储库中的第一个提交。您需要这个,因为此提交将保存您所保留的历史记录的所有基本文件。SHA 是您要保留的提交的上一次提交的 ID (在此示例中为8365366
)。字符串“Initial”将显示为第一次提交的提交消息。如果您使用的是 Windows,请从 Git Bash 命令提示符键入以下命令。
# 8365366 is id of parent commit after which you want to preserve history
echo 'Initial' | git commit-tree 8365366^{tree}
Run Code Online (Sandbox Code Playgroud)
上面的命令将打印 SHA,例如d10f7503bc1ec9d367da15b540887730db862023
.
现在只需输入:
# d10f750 is commit ID from previous command
git rebase --onto d10f750 8365366
Run Code Online (Sandbox Code Playgroud)
这将首先将提交时的所有文件放入8365366
虚拟提交中d10f750
。然后它将回放8365366 之后的d10f750
所有提交。最后master
分支指针将更新为上次播放的提交。
现在,如果您想推送这些被截断的存储库,只需执行git push -f
.
需要记住的几件事(这些适用于其他方法以及此方法): 标签不会转移。虽然保留了提交 ID 和时间戳,但您将看到 GitHub 以一次性标题显示这些提交,例如Commits on XY date
.
幸运的是,可以将截断的历史记录保留为“存档”,稍后您可以将修剪后的存储库与存档存储库连接起来。要执行此操作,请参阅本指南。
归档时间: |
|
查看次数: |
110218 次 |
最近记录: |