同步两个存储库中的相应目录以实现访问控制 从代码中提取数据将数据合并为代码将数据从代码更改为数据

问题描述

代码提取数据

我的git存储库包含代码和资源。该项目是Scala,但Java与此类似:资源包含在shared/src/main/resources路径中,其余的则是源。让我们将此存储库称为“代码存储库”。

我希望某些人能够编辑资源,但不能对存储库的其余部分具有任何访问权限。为此,我创建了一个新的存储库(我们称其为“数据”),并向其中提交了两次提交:

  • 来自代码存储库的初始提交(我很幸运,此提交根本不包含任何文件),因此包括在内很容易(这可以防止无关的历史记录错误
  • 当前状态为shared/src/main/resources的提交

仅对数据做出贡献的人只能访问“数据”存储库。

将数据合并为代码

这很好用,我可以将在“数据”存储库中所做的所有更改合并到“代码”存储库中,而不会出现任何问题。

将数据从代码更改为数据

唯一的麻烦是,当我对“代码”存储库中的资源进行任何更改时。当我尝试合并此类更改时,git希望合并我以前未包含在“数据”存储库中的所有提交,从而将所有代码有效地添加到其中。我可以通过使用--no-ff--no-commit选项并在提交合并之前还原不需要的文件插入来修复这种合并。通过这种方式获得的结果在“数据”存储库中看起来不错,但是随后很难从“数据”合并到“代码”,因为此“还原”现在是合并提交的一部分,而git希望应用它。我可以用同样的方法来预防,但是这只会使问题再次出现。


是否存在可用于这种情况的工作流程或工具?我知道子模块,但是我想避免使用它们,因为它们会带来自己的问题。

我知道这可能不是Git的预期用途,也不是通常做的事情,我很期待答案“不,这是不可能的”,但是看到一些人在使用Git时会表现出巨大的创造力我告诉自己,我会在这里问,希望能找到一些解决方案。

解决方法

我可以看到两种不使用子模块的主要方法,具体取决于您是否要保留历史记录。两者都基于相同的想法:创建一个新分支,只更改您感兴趣的文件,然后合并该分支。我将假设两个存储库都包含一个包含相关文件夹的shared/src/main/resources路径:如果将“数据”中的一个移动到了根目录,它将变得更加复杂,因为提交与不同位置的文件相关。一种简单的解决方法是在“数据”中创建提交,将文件移动到shared/src/main/resources,合并“代码”中的更改,然后删除提交(使用git rebase -i)。另外,在“保存历史记录”中,您可以使用git-filter-repo重写文件夹位置。

丢失历史记录

一次性完成比较容易,但是很难自动化,并且可能导致合并困难。在这里,您执行与创建“数据”存储库时相同的操作:只需将文件夹的现有状态转储到数据存储库的顶部即可。如果您只是将“数据”合并到“代码”中,则“代码”包含您想要的更改:只需将resources文件复制到“数据”中并创建一个提交。

保存历史

进行另一个仅包含对shared/src/main/resources所做更改的仓库/分支。我建议使用git-filter-repo。请注意,这将重写您的存储库:我不确定是否可以仅重写分支来获得它。

cd /path/to/new/repo
git clone code
git checkout -b resources-only
git filter-repo --path shared/src/main/resources

然后,在“数据”中:

git remote add code-resources-only /path/to/new/repo/code
git fetch code-resources-only
git merge --allow-unrelated-histories code-resources-only/resources-only
git remote remove code-resources-only

“数据”存储库的一个小问题是它包含不在“代码”历史记录中的提交:

当前状态为shared/src/main/resources的提交

而“代码”将有很多提交来建立资源文件夹。第一次合并后,这实际上不是问题,但如果分支机构确实共享历史记录,则可能会更好。