是否可以保持2个类似的git repos与不同的文件名同步?

时间:2012-02-02 00:04:57

标签: git repository

我们有2个git repos,其中一个我们向第三方库公开,我们希望在git历史记录中共享我们的变更集,但它们的文件名略有不同。

目前我们有一个shell脚本,它将复制所有文件并处理重命名,但是,这并不理想,因为当我们在另一个存储库中提交时,它会作为一个大型提交(因此它丢失)变化,以及这些变化的原因)。

我们所做的事情的一个例子是: 让我们说在回购A(我们日常工作的来源)中我们有一个类似的结构:

module-x/
    module-x.js

在repo B中(我们要将提交复制到其中),结构如下所示:

gallery-module-x/
    gallery-module-x.js

(此外,文件内容还有其他可编写脚本的更改)。

有没有办法复制历史记录并在文件上运行脚本来同步它们(但保持内容更改并提交消息,以便在第三方仓库中创建新的提交)?

我在考虑在本地设置post-commit钩子,或者在github上设置post-receive钩子,但是不确定是否可以这样做,或者是否有更好的方法来做到这一点。

有什么建议吗?提前谢谢,

2 个答案:

答案 0 :(得分:1)

你做的任何事情都会非常丑陋,因为基本级别的Git知道文件名应该是什么。具有不同文件名的树具有不同的SHA1,因此提交也会执行,并且任何内容都不会匹配。这意味着你可以在GitHub上做任何合理的事情,因为必须进行大量的历史重写。

您可以尝试做两件事。

一个:使用git filter-branch与树或索引过滤器重写一个仓库中的所有历史记录,重命名文件。您可以阅读文档或在线搜索或在此处查找相关示例。在联机帮助页中有一个示例,它与您的用例非常接近,示例部分中的最后一个示例将所有文件移动到子目录中,这样做基本上等同于删除或添加前缀。您的版本可能类似于:

git filter-branch --index-filter \
               'git ls-files -s | sed "s/module-x/gallery-module-x/" |
                       GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
                               git update-index --index-info &&
                mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD

(sed替换模式是您需要小心的地方。)您希望在新的克隆中运行它,以避免实际重写原始仓库中的分支。

如果您在两个存储库中工作,这将需要大量谨慎的工作才能保持同步,避免两个存储库之间的不匹配,并且您必须执行相反的转换以将其他方式带回来。但如果暴露/共享的是只读的,那么这个选项很棒;将filter-branch视为导出的前身。保存脚本来执行此操作,您所要做的就是克隆,过滤分支和推送。

二:手动转移补丁。您可以使用git format-patch <revision-range>创建补丁,然后在这些补丁中自动替换文件名,然后将其应用到其他存储库中。这很难看,但确实有效。

我认为你可能从本地提交后的钩子中触发这些事件中的任何一个,但它们可能比你想要的更耗时,因为你可能经常提交并且想要继续前进。另一个选项,我认为你已经考虑过并因某些原因被解雇了,就是使用现有的脚本,从提交后的钩子开始,将文件复制/重命名到另一个仓库,然后立即提交。 (每次提交一次提交,而不是每次提交一次大型提交。)

答案 1 :(得分:0)

如果只有git存储库(目录)具有不同的名称,您可以通过设置另一个git remote来简化自己:git remote add <their-remote> <git-remote-url>。我希望你能做到这一点,因为这是一个更容易的方法。

但是,如果文件名也不同,但这些文件中的代码相同,您可以创建git patch,并运行sed或其他find-replace命令来更改文件名单个补丁文件,然后git apply到另一个存储库的补丁。这确实可以使用post commit hook和脚本来完成。