Git 工作流:文件夹内容存在分歧但不会合并的公共和私有存储库



我正在寻找一种实用的方法来处理私有和公共存储库,其中特定文件夹中的私有存储库内容可能与公共分支中的内容不同。此文件夹必须存在于两个分支中,并且其内容在两个存储库中都有跟踪,但决不能合并。

这是存储库的简化设置:

/folderA  <-- public content
/folderB  <-- mixed public & private content
/folderB/private.files <-- this file is different in public & private repos
/folderB/newPrivateFolder <-- private repo may add more private-only folders here

这些是我看似简单的要求,但我还没有找到一个好的工作解决方案:

  • private.files必须存在于具有默认内容的公共回购中,项目才能工作
  • 公共回购中private.files的更改不应与私人回购合并
  • 必须在私有回购中跟踪private.files更改,因为团队成员需要它
  • 私有回购中对private.files的更改不得与公共回购合并
  • 私有回购中添加到folderB的其他文件/文件夹决不能添加到公共回购
  • 私人回购承诺应该是孤立的,私人回购的历史不应该与公共回购合并

私人回购是公共回购的复制品。

我尝试过的:

  • 将公共回购包括为子模块子树
    • 不能"覆盖"私有文件夹的内容,因为当将其作为子模块或子树包含时,更改将直接进入公共repo
    • 另外:将整个项目作为子树包含有点毫无意义,因为我想要同一存储库的两个不同版本
  • 稀疏校验
    • 合并仍然会合并所有文件/文件夹,即使是那些未在本地分支中签出的文件/文件夹
  • 属性合并过滤器
    • 仅适用于合并内容,但仍允许添加/删除文件

我还没有尝试的:

  • 两个完全断开连接的存储库(不是重复的),并以某种方式合并它们,同时确保folderB内容"干净"
  • 本地合并回购,在与公共回购分支合并之前,特定文件夹中的所有私有回购分支更改都会被撤消(如何?)

还有什么我可以试试的吗?

也许这个问题已经有了解决方案,但我已经在网上看了几十篇SO和几十篇其他文章,但似乎没有解决这个不同文件夹内容的问题。

在类似的情况下(通过小的本地但永久的修改部署到不同的安装),我使用了一个主分支,该分支在有问题的文件夹中不包含任何内容或伪文件。然后,对于每个本地配置(在您的情况下,它将是私有和公共的),我创建了一个分支off-master,并在那里进行了相关的更改。

开发发生在master上,偶尔我会切换到其他分支(私有/公共),并从master合并到这些分支,而不是相反。

不同的配置(private/public)只共享master的代码,而不是本地修改,我可以无限期地保留它们,而且我仍然有一个并且只有一个用于更改/开发的中心位置(master分支)。

现在看起来很简单,我已经想明白了。本质上,您只需在合并时删除folderB,并用其公共内容替换它,然后提交。

基本设置要求:

  • 在folderB中填充了初始"默认"内容的公共回购
  • 使用本指南将公共回购复制为私人回购(仅适用于第一个代码框)
  • 公共和私人回购都作为分支机构连接在本地回购中,各自有其来源——本地回购是发生合并的地方
  • 在私人部门工作

现在,当私人回购进行了修改&添加到folderA和folderB,并且您想将除folderB中的更改外的所有更改合并回公共回购,您可以按如下方式合并(我建议使用一个额外的合并分支来安全地进行实验):

  • 将私有分支合并到公共(或合并)分支-执行而不是提交
  • 在repo中运行以下命令(假定为合并分支):
    • git checkout merge-branch
    • git merge -s recursive -Xtheirs --no-edit --no-commit private-branch
    • rm -rf folderB
    • git reset <tree-ish> -- folderB/
    • git checkout --theirs <tree-ish> -- folderB/
  • 现在照常提交

它的作用:

  • 签出对合并分支的更改(建议使用一个,并且它应该是最新的原始分支)
  • merge接受来自私有分支的所有更改(merge"their"),no edit阻止merge需要我们的输入(commit消息),no commit阻止commit,因为我们希望在提交之前清理工作目录
  • rm从工作目录中删除整个文件夹B及其内容(包括子文件夹)。这可以防止任何添加的文件/文件夹在提交时被添加到分支的索引中,因为您刚刚删除了它们
  • reset使用"tree-ish"(即分支,或者在我的情况下,我使用提交SHA)来重置文件夹B的索引和工作目录
  • checkout然后拉取folderB的当前状态,将其恢复到公共repo中的HEAD状态。这意味着从公开回购的角度来看,folderB的全部内容保持不变

我不确定是否需要重置和结账,但我还是会这么做。请随意尝试。

因此,如果在合并之后和提交之前清理工作目录,则私有分支中对folderB的任何更改的提交历史记录都不会添加到公共repo中。

我试着用合并后挂钩来做这项工作,但如果你不提交,它似乎就无法运行。此外,将所有命令放在一个脚本中更容易。

将公共回购变更合并回私人回购操作正常,无需额外步骤。

As.git不支持.ignore(通过远程或分支差异);以下是我在NPM:中的简单工作

"scripts": {
    "deploy:public": "git add . && git commit -am 'master src committed'",
    "deploy:private": "git add . && git rm -r --cached src/* && git commit -am 'master src omitted.'" }

最新更新