0

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

这是存储库的简化设置:

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

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

我试过的:

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

我还没有尝试过的:

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

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

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

4

3 回答 3

1

现在看来很简单,我想通了。本质上,您只需在合并时删除 folderB 并将其替换为其公共内容,然后提交。

基本设置需要:

  • 公共仓库在文件夹B 中填充了初始“默认”内容
  • 使用本指南将公共回购复制到私人回购(仅应用第一个代码框)
  • 公共和私人回购在本地回购中连接为具有各自来源的分支 - 这个本地回购是合并发生的地方
  • 在私人分支机构做你的工作

现在,当私有存储库对文件夹A 和文件夹B 进行了修改和添加,并且您想要将除文件夹B 中的更改之外的所有更改合并回公共存储库时,您可以按如下方式进行合并(我建议使用额外的合并分支来安全地试验它):

  • 将私有分支合并到公共(或合并)分支 -不要提交
  • 在 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/
  • 现在像往常一样提交

这是做什么的:

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

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

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

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

将公共回购更改合并回私人回购正常工作,不需要额外的步骤。

于 2013-08-31T09:43:56.973 回答
1

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

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

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

于 2013-08-30T12:23:12.773 回答
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.'" }
于 2020-09-21T06:19:00.033 回答