git - 停止 git 历史记录,然后稍后再重新添加在一起

标签 git github version-control

我被带去版本控制一个以前不在版本控制中的项目。

没有提前考虑,我将所有文件添加到存储库中,并在开始处理它后立即开始跟踪它。

现在存储库非常庞大,太大而无法推送到 git hub。因此,我开始删除所有多余的文件,并使用 git filter-branch 使用此命令从历史记录中根除它们。

sudo git log --all --pretty=format: --name-only --diff-filter=D | sort -u | while read -r line; do sudo git filter-branch -f --tree-filter "rm -rf { $line }" HEAD; done

问题?有太多多余的文件,而且这需要很长时间,救世主可能会在完成之前返回,我需要快速将其上传到 github。

所以加快这个过程,我发现我可以在孤立分支中提交最新的文件

git checkout --orphan <new-branch-name>

因此,为了开始行动,我想做的就是将此提交推送到 github,继续运行清理操作,然后在完成后将两个分支重新粘在一起。

这样

1-----10
         1a------Xa  (1a = 10) 

成为

1-----10-1a------Xa

或者可能

1------10------Xa

所以最终我们保存了几乎所有的历史。

这可能吗?我时间紧迫,不想失去一切。

最佳答案

正如所描述的那样,这是不可能的,因为提交的 ID(“真实名称”)是其哈希校验和,其中包括其所有历史记录。因此,在两个分支上包含这五个提交的存储库中:

A--B--C--D   <-- with-big-files

         D'  <-- cleaned

您可以推送任一分支,但您永远无法使 D' 与前任一样具有任何其他提交。 D' 是根提交并且始终是根提交。

可以做的是,例如,添加此cleaned2分支:

A--B--C--D   <-- with-big-files

         D'     <-- cleaned

           A'-B'-C'   <-- cleaned2

然后 merge :

A--B--C--D   <-- with-big-files

         D'---------E   <-- cleaned
                   /
           A'-B'-C'    <-- cleaned2

然后丢弃名称cleaned2。 (如果您愿意,cleaned2 可以包含 D'',它是 D 和/或 D' 的副本,但以 C' 作为其父级。)

请注意,无论您使用 git filter-branch 或 BFG 甚至此手动方法,您最终得到的都是原始提交的一堆副本 ,您已从副本中取出大文件。


编辑:这不是问题的答案,但我认为我应该添加此旁注。您已发现过滤器分支太慢,但现在正在解决不同的问题,而不是简单地加快过滤器分支的速度。

首先,您与 git filter-branch 一起使用的过滤器(--tree-filter )是最慢的方法。将每个删除操作作为 --index-filter 进行会快得多(尽管仍然不是非常快)。

第二,实际上更重要的是,您应该对存储库中的每个提交进行一次传递以删除,而不是一次性删除每个文件以完全复制存储库中的每个提交所有此类文件(仍然使用索引过滤器,以避免将每个提交复制到工作树)。

驱动这一切的关键是 git filter-branch 的工作方式,我在上面提到过。在 Git 中,不可能更改提交,因此与所有 Git 命令一样,filter-branch 也不能。它只是似乎,并且为了让某些提交看起来好像被更改了,Git 将每个这样的提交复制到一个新的> 提交,然后 stash 原件并假装副本是原件。

运行 git filter-branch HEAD 复制可从 HEAD 访问的每个提交。我不知道您的存储库中有多少提交,但假设可以从 HEAD 访问 150 个提交,并有 20 个文件需要删除。您每次删除一个文件,因此首先复制 150 个提交来删除文件 A。然后复制 150 个提交(减去文件 A 的提交)来删除文件 B。然后复制 150 个提交(减去 A 和 A 的提交) B) 删除文件C,依此类推。这意味着您要复印 150 x 20 = 3000 份。

使用 --index-filter (与 git rm --cached --ignore-unmatch)将使 3000 个副本的运行速度比使用 快几个数量级>--树过滤器。一次性删除所有文件将生成 150 个副本。如果每一项改进都能将时间减少到原来的 1/20,那么两者一起进行就会将时间减少到大约 1/400。

关于git - 停止 git 历史记录,然后稍后再重新添加在一起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37799336/

相关文章:

image - 使用Jenkins docker镜像无法连接github

Github 仓库 - 'fatal: Could not read from remote repository.'

git - 如何通过 Tor 匿名在 github 上做贡献?

git - git存储模型是不是很浪费?

version-control - Mercurial,永远忘记文件

android-studio - Android Studio 从版本控制 : Google Cloud checkout

Ubuntu [22.04 LTS] 上的 Git 配置

git - merge 不同目录级别的 git 存储库

git - 按提交/merge 日期排序 git diff --name-only list

c - 使用 libgit2 进行 Git checkout