git workflow:公共和私有存储库,其中文件夹内容发散但不会合并

时间:2013-08-30 12:02:06

标签: git version-control merge repository workflow

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

这是存储库的简化设置:

/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必须存在 public repo中,并且项目的默认内容才能正常工作
  • 公开回购中private.files的更改不应与私人回购合并
  • private.files更改必须在私人回购中跟踪,因为团队成员需要
  • 私有回购中private.files的更改绝不能与公共回购合并
  • 私人回购中添加到folderB的其他文件/文件夹绝不能添加到公开回购
  • 私人回购提交应该被隔离,私人回购的历史不应该与公共回购合并

私人回购是公共回购的副本。

我尝试过:

  • 将公开回购列为子模块子树
    • 无法“覆盖”私人文件夹的内容,因为当将其作为子模块或子树包含时,更改会直接转到公共存储库
    • plus:将整个项目包含为子树有点没有意义,因为我想要同一个存储库的两个不同版本
  • 稀疏结账
    • 合并仍会合并所有文件/文件夹,即使是那些未在本地分支中签出的文件/文件夹
  • 属性合并过滤器
    • 仅在合并内容时适用,但仍允许添加/删除文件

我还没有尝试过:

  • 两个完全断开连接的存储库(不重复),并以某种方式合并它们,同时确保folderB内容为“干净”
  • 本地合并仓库,其中特定文件夹中的所有私人仓库分支更改在与公共仓库分支合并之前撤消(如何?)(好吧,实际上我已经尝试了这个并且它似乎与稀疏结账一起使用 - 但是一旦被推送所有私人变化直接进入公共回购)

我还能尝试其他什么?

也许已经有了这个问题的解决方案 - 但我一直在网上看几十篇SO和几十篇文章,但似乎没有办法解决这个分歧的文件夹内容问题。

3 个答案:

答案 0 :(得分:1)

在类似的情况下(部署到具有小的本地但永久修改的不同安装)我使用了一个主分支,在所讨论的文件夹中不包含任何内容或虚拟文件。然后对于每个本地配置(在您的情况下将是私有和公共)我创建了一个分支主,并在那里做了相关的更改。

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

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

答案 1 :(得分:1)

现在我觉得这很简单。实质上,您只需在合并时删除folderB并将其替换为其公共内容,然后提交。

基本设置要求:

  • public repo填充了folderB中的初始“默认”内容
  • 使用this guide(仅应用第一个代码框)将公共仓库复制到私人仓库
  • 公共和私人仓库在本地仓库中连接为具有各自来源的分支 - 这个本地仓库是合并发生的地方
  • 在私人分支机构开展工作

现在私人回购已经进行了修改&amp;添加了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接受来自私有分支的所有更改(合并“他们的”),没有编辑阻止合并来自我们的输入(提交消息)并且没有提交阻止提交因为我们想要在提交之前清理工作目录
  • rm从工作目录中删除整个folderB及其内容(包括子文件夹)。这可以防止在提交时将任何添加的文件/文件夹添加到分支的索引中,因为您刚删除它们。
  • reset使用“tree-ish”(即分支或在我的情况下使用提交SHA)来重置folderB的索引和工作目录
  • checkout然后拉出folderB的当前状态,将其恢复到HEAD状态,因为它在公共仓库中。这意味着从公共仓库的角度来看,folderB的全部内容保持不变。

我不确定是否需要重置和结账,但无论如何我都在做。随意尝试。

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

我尝试使用合并后的钩子来完成这项工作,但如果你不提交它似乎没有运行。此外,将所有命令放在一个脚本中更容易。

将公共回购更改合并回私有仓库正常工作,无需其他步骤。

答案 2 :(得分:0)

由于.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.'" }