重写子模块的git历史记录后,更新对父存储库中子模块的引用 [英] Update references to a submodule in parent repository after submodule's git history is re-written

查看:86
本文介绍了重写子模块的git历史记录后,更新对父存储库中子模块的引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我用来重写多个父存储库中引用的子模块的历史记录的脚本.它在Windows环境中的Git bash中运行.

Following is the script I'm using to rewrite the history of a submodule which is referenced in multiple parent repositories. This runs in Git bash in a windows environment.

#!/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 ,以便可以在父存储库中更新相同的引用.有办法吗?我确实看过在重写子模块的历史记录后,带有子模块的存储库 ,但这并没有真正的帮助,因为我正在更新原始引用,以确保要删除的文件不会被重新打包.我对使用git还是比较陌生,因此任何指导都将不胜感激.

I need to somehow map the SHAs of the old commits to the newly created SHAs, so that I can update the same reference in the parent repositories. Is there a way to do it? I did look at Repository with submodules after rewriting history of submodule, but it's not really helping as I'm updating the original refs to make sure the files I'm removing are not repacked by any chance. I'm relatively new to using git so any guidance would be really appreciated.

修改:

按照接受的答案(@torek)的注释部分中所述的步骤为我工作.

Following the steps mentioned in comments section of the accepted answer (by @torek) worked for me.

推荐答案

没有做到这一点的好方法(至少使用git filter-branch和现有的Git工具-BFG保留了所需的地图文件,但仍然需要构造东西).

There is no good way to do this (at least with git filter-branch and existing Git tools—the BFG leaves the desired map file around, but still requires constructing something).

git filter-branch复制提交时,它将每个新提交的哈希值放入映射文件"(将旧ID和新ID配对-实际上是现有实现中的目录,尽管在大型过滤器中效果很差,所以它可能有一天会被更改),以便可以从原始提交的哈希值转换为重写的提交的哈希值.这就是它提供map函数的方式,该函数 git filter-branch文档指的是这里:

When git filter-branch copies commits, it places each new commit's hash into a "map file" (pairing up the old and new IDs—actually a directory in the existing implementation, although this performs very poorly in large filters, so it may someday be altered), so that it's possible to convert from original-commit hash to rewritten-commit hash. This is how it provides the map function that the git filter-branch documentation refers to here:

可用一个 map 函数,该函数带有原始sha1 id"参数,如果提交已经被重写,则输出重写的sha1 id",否则输出原始sha1 id";如果您的提交过滤器发出了多个提交,则 map 函数可以在单独的行上返回多个id.

A map function is available that takes an "original sha1 id" argument and outputs a "rewritten sha1 id" if the commit has been already rewritten, and "original sha1 id" otherwise; the map function can return several ids on separate lines if your commit filter emitted multiple commits.

不幸的是,当git filter-branch完成并清理后,它删除了映射表,而不是将其转换为有用的数据库.如果您的数据库带有映射,则可以将其与任何外部项一起使用(其他存储库,测试框架或您可能保存了它们的任何其他位置中的"gitlink"条目).没有地图,就没有很好的方法来处理此问题.超级项目说,例如,使用提交1234567",但是在重写的子模块存储库中不再存在该提交.新提交的ID将在地图中为 ,但没有地图.

Unfortunately, when git filter-branch finishes and cleans up, it removes the mapping table, rather than turning it into a useful database. If you had the database with the mappings, you could use that with any external items ("gitlink" entries in other repositories, test frameworks, or any other place you might have them saved). Without the map, there is no good way to handle this. The superproject says, e.g., "use commit 1234567" but that commit no longer exists in the rewritten submodule repository. The new commit's ID would be in the map, but there is no map.

这篇关于重写子模块的git历史记录后,更新对父存储库中子模块的引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆