我从SVN迁移到git,我在每个参考SVN修订版号的git提交中都有一个注释。
在repo导入后,我使用BFG repo清理器从二进制文件和其他垃圾中清除git历史记录。
不幸的是,当我输入git log
时,我看不到注释。我想BFG忘记更新笔记提交的引用。
BFG以下列格式留下* .txt报告,其中将旧对象id映射到新对象id:
0001b24011381e8885683cd1119ba4cb077fa64b c81149b1b52b9e1e1767d6141f292891d715edb5
00024eecdc31f2f6e67018f7d6f00e7c1ad03f1f 326ee3b508e3dd2934ec1f50069195f86ea1a1c7
00028e04dcc2d59bd835b447bd3a207ae481696c 3d18e9b9d3336e59d62093200b81603ffefcc747
根据上述映射,你能否建议一些脚本快速修复笔记?
PS:我几乎可以肯定问题是由未更新的引用引起的,因为当我在第二位键入git notes
时,我可以看到在BFG报告object-id-map.old-new.txt
中被认为是旧的引用
答案 0 :(得分:1)
我编写了以下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
答案 1 :(得分:0)
没有内置任何东西可以做到这一点;你必须自己编写脚本或程序。好的一面是,BFG给你留下了地图文件:它比git filter-branch
好得多,它将它扔掉,这样你更新笔记所需的信息就不见了。
注释中的底层实现是refs/notes/commits
(或者你为core.notesRef
设置的任何内容)指向普通提交,至少在理论上你可以git checkout
(可能是暂时的)你专门为此目的设立的工作树)。此树包含的文件的名称是带注释的提交,略有修改。例如,如果:
0001b24011381e8885683cd1119ba4cb077fa64b c81149b1b52b9e1e1767d6141f292891d715edb5
是一个映射条目,0001b24011381e8885683cd1119ba4cb077fa64b
是旧提交,如果0001b24011381e8885683cd1119ba4cb077fa64b
有一个备注条目,则会有一个 name 为{{1}的文件} - 通常,它可能是0001b24011381e8885683cd1119ba4cb077fa64b
或00/01b2...
。
所有这些添加的子目录的嵌套深度由注释代码动态管理,一般的想法是&#34;根据需要添加尽可能多的树来查找是否有注释,快速;但是当从00/01/b2...
开始的音符很少时,没有那么多的树可以占用存储库中的大量空间。这种扇出对您的目的并不重要,尽管您可能希望以相同的速度维护它。
您的工作是在旧名称下查找此树中的每个文件,并将其移动(或复制)到与新提交ID匹配的 new 名称。由于此案例中的新名称为0001b2...
,因此您可以将文件重命名为c81149b1b52b9e1e1767d6141f292891d715edb5
或c8/1149b1b52b9e1e1767d6141f292891d715edb5
等。一旦重命名了所有文件(通过索引:使用{ {1}}或c8/11/49b1b52b9e1e1767d6141f292891d715edb5
和git mv
根据需要),您可以将其转换为常规提交对象,git rm --cached
后跟git add
。使新提交的父级成为现有git write-tree
提交,并使用git commit-tree
更新refs/notes/commits
以指向新提交,并且您的注释应重新出现,后过滤。
(一旦你有这样的工作,最好加入git update-ref
和/或BFG本身。)