2017-06-08 69 views
0

以下是我用来重写多个父存储库中引用的子模块的历史记录的脚本。这在Windows环境中运行在Git bash中。重新编写子模块的git历史记录后,更新对父存储库中子模块的引用

#!/bin/bash 

cd submodule_repo 

git filter-branch --index-filter 'git rm -q --cached --ignore-unmatch files_to_remove' \--tag-name-filter cat -- --all 

git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d 

git reflog expire --expire=now --all 
git gc --prune=now 

我需要的SHA一个旧提交的某种方式映射到新创建的SHA S,这样我就可以更新父库相同的参考。有没有办法做到这一点?我确实看过Repository with submodules after rewriting history of submodule,但这并不是真正的帮助,因为我正在更新原始参考文件,以确保我删除的文件不会被任何机会重新打包。我对使用git比较陌生,所以任何指导都会非常感激。

编辑

继公认的答案(由@torek)的评论部分中提到的步骤为我工作。

回答

0

没有好办法做到这一点(至少在git filter-branch和现有的Git工具 - BFG离开所需的地图文件,但仍然需要构建的东西)。

git filter-branch副本提交时,它将每个新提交的散列放入一个“映射文件”(配对旧和新ID--实际上是现有实现中的一个目录,虽然这在大型过滤器中表现很差,所以它可能有一天会被修改),这样就可以将原始提交哈希转换为重写提交哈希。这是怎么回事提供map功能the git filter-branch documentation指的是在这里:

一个地图功能是可用,接受一个“原始的SHA1 ID”的说法,并输出“重写SHA1 ID”如果犯已被重写,否则“原始sha1 id”; 函数可以在单独的行上返回多个标识符,如果您的提交过滤器发出多个提交。

不幸的是,当git filter-branch饰面和清理,它移除映射表中,而不是把它变成一个有用的数据库。如果你的数据库中有映射,你可以将它用于任何外部项目(其他存储库,测试框架或其他可能已保存的地方的“gitlink”条目)。没有地图,没有好办法来处理这个问题。超级项目说,例如,“使用提交1234567”,但该提交在重写的子模块存储库中不再存在。新提交的ID 在地图上是,但没有地图。

+0

谢谢@torek这是令人失望的:(应该有一个选项来保留或放弃地图一旦过滤器分支完成,将在这种情况下非常有用。任何解决方法,我可以用来手动创建地图? –

+0

最简单的方法就是修改过滤分支代码,这是一个shell脚本,所以修改起来非常简单,只需找到删除临时目录的地方,然后让它对地图进行一些有用的操作即可保存。 – torek

+0

已经有一段时间了,但现在我又回到了这个任务,所以我使用了'$ GIT_COMMIT'变量,如[这里]所述(https://stackoverflow.com/questions/14782906/how-do-i-get- ),并创建了地图作为filter-branch的一部分,它似乎正确地填充地图(所有我的修改提交在地图中注册)以及旧的提交。 –