git BFG 之后的笔记?
git notes after BFG?
我从 SVN 迁移到 git 并且我在每个 git 提交中都有一个注释引用 SVN 修订号。
回购导入后,我使用 BFG 回购清理器从二进制文件和其他垃圾中清除 git 历史记录。
不幸的是,现在我在键入 git log
时看不到注释。我想 BFG 忘记更新对注释提交的引用。
BFG 留下一份 *.txt 报告,其中包含以下格式的旧对象 ID 到新对象 ID 的映射:
0001b24011381e8885683cd1119ba4cb077fa64b c81149b1b52b9e1e1767d6141f292891d715edb5
00024eecdc31f2f6e67018f7d6f00e7c1ad03f1f 326ee3b508e3dd2934ec1f50069195f86ea1a1c7
00028e04dcc2d59bd835b447bd3a207ae481696c 3d18e9b9d3336e59d62093200b81603ffefcc747
你能推荐一些脚本来根据上述映射快速修复注释吗?
PS:我几乎可以肯定问题是由没有更新的 refs 引起的,因为当我在第二位输入 git notes
时,我可以看到 BFG repot 中被认为是旧的 refs object-id-map.old-new.txt
[编辑: Git 2.15 版,2017 年 11 月发布,添加 --state-branch
到 filter-branch。此选项将地图保存在第一个过滤器分支操作创建的分支中的文件中。随后的过滤器分支操作将使用现有地图。因此,自 Git 2.15 起,将 --state-branch <name>
添加到您的过滤器分支操作中,然后在新创建的分支中使用映射。]
没有内置的东西可以做到这一点;您将不得不自己编写脚本或程序。从好的方面来说,BFG 给你留下了地图文件:这比 git filter-branch
好得多,后者把它扔掉了,这样你更新笔记所需的信息就没有了。
注释中的底层实现是refs/notes/commits
(或者你为core.notesRef
设置的任何内容)指向一个普通的提交,你至少在理论上可以git checkout
(可能进入您专门为此目的设置的临时工作树)。该树包含名称为带注释的提交的文件——仅略微修改。例如,如果:
0001b24011381e8885683cd1119ba4cb077fa64b c81149b1b52b9e1e1767d6141f292891d715edb5
是一个映射条目,0001b24011381e8885683cd1119ba4cb077fa64b
是一个旧的提交,如果0001b24011381e8885683cd1119ba4cb077fa64b
有一个注释条目,就会有一个文件name是 0001b24011381e8885683cd1119ba4cb077fa64b
——只是,它可能是 00/01b2...
或 00/01/b2...
.
所有这些添加的子目录的嵌套深度由注释代码动态管理,总体思路是“根据需要添加尽可能多的树以查找是否有注意,快;但是当很少有以 0001b2...
开头的注释时,没有那么多树占用存储库中的大量 space。尽管您同样速度的原因不妨维护一下。
您的任务是在该树中的 old 名称下找到每个文件,并将其移动(或复制)到 new 与新提交 ID 匹配的名称。由于在这种情况下新名称将是 c81149b1b52b9e1e1767d6141f292891d715edb5
,您可以将文件重命名为 c8/1149b1b52b9e1e1767d6141f292891d715edb5
,或 c8/11/49b1b52b9e1e1767d6141f292891d715edb5
,等等。一旦您重命名了所有文件(通过索引:使用 git mv
或 git rm --cached
和 git add
根据需要),您可以使用 git write-tree
后跟 git commit-tree
将它们变成常规提交对象。使新提交的父级成为现有的 refs/notes/commits
提交,并使用 git update-ref
更新 refs/notes/commits
以指向 new 提交,并且您的注释应该重新出现,post-过滤。
(一旦你有了这样的东西,最好将它与 git filter-branch
and/or BFG 本身结合起来。)
我编写了以下 bash 脚本来从旧对象转移我的笔记。该解决方案在单线程中很慢,不确定 运行 多个 git notes
并行命令是否安全。
while read string; do
hashesArray=($string)
git notes copy ${hashesArray[0]} ${hashesArray[1]}
git notes remove --ignore-missing ${hashesArray[0]}
done <object-id-map.old-new.txt
我从 SVN 迁移到 git 并且我在每个 git 提交中都有一个注释引用 SVN 修订号。
回购导入后,我使用 BFG 回购清理器从二进制文件和其他垃圾中清除 git 历史记录。
不幸的是,现在我在键入 git log
时看不到注释。我想 BFG 忘记更新对注释提交的引用。
BFG 留下一份 *.txt 报告,其中包含以下格式的旧对象 ID 到新对象 ID 的映射:
0001b24011381e8885683cd1119ba4cb077fa64b c81149b1b52b9e1e1767d6141f292891d715edb5
00024eecdc31f2f6e67018f7d6f00e7c1ad03f1f 326ee3b508e3dd2934ec1f50069195f86ea1a1c7
00028e04dcc2d59bd835b447bd3a207ae481696c 3d18e9b9d3336e59d62093200b81603ffefcc747
你能推荐一些脚本来根据上述映射快速修复注释吗?
PS:我几乎可以肯定问题是由没有更新的 refs 引起的,因为当我在第二位输入 git notes
时,我可以看到 BFG repot 中被认为是旧的 refs object-id-map.old-new.txt
[编辑: Git 2.15 版,2017 年 11 月发布,添加 --state-branch
到 filter-branch。此选项将地图保存在第一个过滤器分支操作创建的分支中的文件中。随后的过滤器分支操作将使用现有地图。因此,自 Git 2.15 起,将 --state-branch <name>
添加到您的过滤器分支操作中,然后在新创建的分支中使用映射。]
没有内置的东西可以做到这一点;您将不得不自己编写脚本或程序。从好的方面来说,BFG 给你留下了地图文件:这比 git filter-branch
好得多,后者把它扔掉了,这样你更新笔记所需的信息就没有了。
注释中的底层实现是refs/notes/commits
(或者你为core.notesRef
设置的任何内容)指向一个普通的提交,你至少在理论上可以git checkout
(可能进入您专门为此目的设置的临时工作树)。该树包含名称为带注释的提交的文件——仅略微修改。例如,如果:
0001b24011381e8885683cd1119ba4cb077fa64b c81149b1b52b9e1e1767d6141f292891d715edb5
是一个映射条目,0001b24011381e8885683cd1119ba4cb077fa64b
是一个旧的提交,如果0001b24011381e8885683cd1119ba4cb077fa64b
有一个注释条目,就会有一个文件name是 0001b24011381e8885683cd1119ba4cb077fa64b
——只是,它可能是 00/01b2...
或 00/01/b2...
.
所有这些添加的子目录的嵌套深度由注释代码动态管理,总体思路是“根据需要添加尽可能多的树以查找是否有注意,快;但是当很少有以 0001b2...
开头的注释时,没有那么多树占用存储库中的大量 space。尽管您同样速度的原因不妨维护一下。
您的任务是在该树中的 old 名称下找到每个文件,并将其移动(或复制)到 new 与新提交 ID 匹配的名称。由于在这种情况下新名称将是 c81149b1b52b9e1e1767d6141f292891d715edb5
,您可以将文件重命名为 c8/1149b1b52b9e1e1767d6141f292891d715edb5
,或 c8/11/49b1b52b9e1e1767d6141f292891d715edb5
,等等。一旦您重命名了所有文件(通过索引:使用 git mv
或 git rm --cached
和 git add
根据需要),您可以使用 git write-tree
后跟 git commit-tree
将它们变成常规提交对象。使新提交的父级成为现有的 refs/notes/commits
提交,并使用 git update-ref
更新 refs/notes/commits
以指向 new 提交,并且您的注释应该重新出现,post-过滤。
(一旦你有了这样的东西,最好将它与 git filter-branch
and/or BFG 本身结合起来。)
我编写了以下 bash 脚本来从旧对象转移我的笔记。该解决方案在单线程中很慢,不确定 运行 多个 git notes
并行命令是否安全。
while read string; do
hashesArray=($string)
git notes copy ${hashesArray[0]} ${hashesArray[1]}
git notes remove --ignore-missing ${hashesArray[0]}
done <object-id-map.old-new.txt