git - 合并两个不同的分支,忽略一些目录

git - merge two divergent branches ignoring some directories

小故事:我想告诉 git 在合并时忽略一个目录。我知道 git 那样不行...

长话短说: 我有一个将部署在两个不同平台上的项目。每个平台都需要对部署代码进行一些调整。

我有两个分支,每个平台一个:PlatformA 和 PlatformB。这两个分支实际上是相同的。唯一的区别是几个文件和一个目录需要出现在一个平台上,而不是另一个平台上。这是场景:

PlatformA branch:
 - dir1
   - file1
 - dir2
   - file2

PlatformB branch:
 - dir1
   -file1

当我在 platformA 上工作并更改 file1 时出现问题。我希望这些更改也适用于平台 B。问题是当我进行合并时,git 将 dir2 和 file2 添加到 platformB。

我还希望能够在平台 B 上工作并更改 file1 并能够合并到平台 A 而无需 git 删除 dir2 和 file2。

所以问题是: 有什么办法可以有两个可合并的不同分支? 要么 有一种方法可以告诉 git 忽略 directory/commit?

我试过这个 solution 但只有在合并 ProjectB->ProjectA 时有效,反之则不行(git 将 dir2 和 file2 复制到 ProjectB)。

另外,我想我每次都可以挑选,但这看起来很麻烦而且容易出错。

提前致谢!

我不认为有一个直接的好和干净的解决方案,但作为一种解决方法,您可以使用 .gitignore 文件来完成它。如果您在 .gitignore 文件中包含 ./dir2/*,dir2 将永远不会从 A 合并到 b,也不会从 B 合并到 A,但是如果您从该目录修改文件,则不会跟踪这些文件git,除非您在提交前手动添加它们。
根据您需要多久执行一次操作(修改 A 中的 dir2 / 将 A 合并到 B 中),一个或其他解决方案可能更合适,但我认为您在从一个操作切换到另一个操作时总是需要修改。您可以有一个脚本来为您修改 .gitignore 文件,以防您需要从存储库中添加或删除许多目录。

我建议不要对特定于平台的文件使用分支。重新组织项目,以便所有平台都在一个目录树中,并且公共文件只存在一次。

类似于 Linux 内核 - 它具有 arch 包含平台特定代码的目录,而不是一堆分支。

当您需要开发一些比一次提交更大的新功能时会发生什么?您创建分支 PlatformA-CoolFeature 和 PlatformB-CoolFeature?那将是一个合并地狱:)

这可能并不理想,但这是我在几个类似项目中使用的方法...引入第三个分支,例如,名为 core。在该分支的两个平台上进行您希望在两个平台上都可用的所有开发,并且仅在特定于平台的分支上进行特定于平台的开发。定期将 core 合并到每个平台分支(但不是另一个方向!)。跟踪您要将哪些更改放在何处可能会变得很棘手,特别是如果您有一个特定的更改需要拆分为特定于平台和平台不可知的部分,但只要您记得思考,它就会起作用关于你在做什么。当您添加更多平台来跟踪...

时,这也会很痛苦

最接近熟悉的方法是进行合并 --no-commit --no-ff 并撤消您不喜欢其通常行为的任何内容,例如

git checkout A
git merge --no-commit --no-ff B
git checkout @ dir2       # nope, didn't want dir2 gone
git commit

这可能是最好的,因为通常的命令除了一些小事情之外已经做了你想要的,并且你想尽可能少地改变。

另一个选项:“”。他推荐并指出 linux 使用的设置是每个部署目标一个子目录。这可能是最好的,当你 (a) 可以自由地设置你的回购协议 (b) 一个适合的 build/test 工具包,并且 (c) 将所有东西作为一个项目来管理至少在某种程度上是合理的。这是一个很常见的案例,对于一家小商店来说,这是我第一个看的。

但是,如果这些会造成麻烦,或者可能会造成麻烦,那么我会选择的唯一剩余选项是单独管理 dir1,作为一个子模块。这伴随着管理开销,它远不是 "just works" 的事情,直到你花时间让自己感到非常困惑,然后找到掌握的方法(通过破坏几个玩具回购),但是: 这些仪式并不比带孩子过马路更难,您只需要学习如何正确地过马路,它确实提供了一个重要的优势:它实现了完全你想要什么。