Context
我是主要作者立即下一步 https://github.com/UnlyEd/next-right-now这是一个开源“样板”,包含使用 Next.js 框架构建 Web 应用程序的多个“预设”。每个预设都带有内置功能,并且旨在进行分叉,以便其他人可以基于它构建他们的应用程序。每个预设都位于其自己的 git 分支中,例如:
- https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-at-lcz-sty https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-at-lcz-sty
- https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-gcms-lcz-sty https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-gcms-lcz-sty
我正在研究 NRN 并使其定期发展。
但是,我还分叉了可用的 NRN 预设之一,并从中制作了我自己的专有应用程序。
定义
以下是一些定义,以避免术语误解。
- 分叉:NRN 预设分叉到另一个项目,无论是开源项目还是专有项目。
- 来源:用于生成 Fork 的 NRN 预设。(举个例子,假设 Source git 分支是https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-at-lcz-sty https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-at-lcz-sty,这是我用来创建我的 Fork 的 NRN 预设)
Problem
这种做法的问题是我不确定如何使“Fork”与 NRN 样板预设保持同步。两者都以自己的方式发展。此外,NRN 不是一个框架,而是一个样板文件,它意味着可以重写它来定制基本代码,这最终会导致 Fork 和 Source 之间的大量冲突。
到目前为止我一直在做什么
为了使我的 Fork 与源上的最新更改保持同步,我基本上rebase
我自己的工作基于 Source git 历史记录。 (例如:git rebase NRN-v2-mst-aptd-at-lcz-sty
)
这具有以下优点(优点):
- 它使历史保持干净且易于理解/比较。通过比较它们的历史记录,我可以轻松地知道哪一个是我从源同步的最新提交。 Fork 中完成的所有工作均已完成在之上源代码中做了什么。
- git 树分为两个不同的部分:源提交树和分叉提交树。
- 我可以使用 git rebase 使我的 Fork 保持最新状态,从而将从源完成的新更改同步到 Fork 中,然后
push --force
覆盖遥控器。
但也有一些缺点(cons):
- 当 Fork 中只有一个分支时,处理两个分支之间的同步并不是那么复杂,但是一旦有多个分支,它就会变得非常混乱,因为它重写了所有分支的 git 历史记录,当有多个分支时,它会变得相当复杂叉子中其他“功能”分支正在进行的工作。首先,我需要对 Fork:master 进行变基,然后用 Fork:master 对每个分支进行变基。如果我以错误的方式这样做,它就会弄乱整棵树(我犯过一次错误,并且到处都是 --force 进行 rebase 是痛苦的两个小时)
- 它使用 --force
Fork:master
分支,恕我直言,这不是很好,如果处理不当,可能会导致很多麻烦。我对自己正在做的事情有点熟悉,但如果团队中有更多人,这将是不可行的。
- 总的来说,我对自己有一天不会把事情搞砸的能力没有信心。
- 它感觉不适合团队,它起作用只是因为我独自工作,恕我直言。
- 当发生冲突时,解决起来可能会很痛苦,而且我也曾多次犯过错误。
- git 历史记录是不可信的,我的 Fork 工作分支在与源同步时会重写其提交历史记录,并且所有 GitHub 注释都失去了用处,因为它们不再与任何提交匹配。
使用 rebase,我最终不得不擦除整个工作分支,并通过挑选我在 Fork 中完成的所有提交来从源重新创建它,因为历史记录不再匹配,我需要一个干净的开始。这是在我以错误的方式变基而犯了一些错误之后发生的。
我在寻找什么
我目前的方式工作得很好,只要我是独奏,只要我很好地了解我的 git 分支,只要我不通过 rebase 和推动 --force 搞砸了它。但它并不能令我满意。
我正在寻找一种更好的方法,该方法对团队有用,并且我可以将其用作“官方推荐”的方法来保持 Fork 与其 NRN 源同步。
备择方案
我想过cherry-pick
-ing 从 Source 提交到我的 Fork,但我不确定这是否是更好的选择,因为它将 Source 和 Fork 提交混合在一起(两者之间不再分离)。这最终会导致在比较两棵树并弄清楚哪些提交已被精心挑选而哪些提交未被挑选时遇到困难。此外,它并不能保护我免于忘记挑选一个提交并在几周后遇到麻烦,这可能会导致使用 --force 重写历史记录以在正确的位置包含丢失的提交。
我没有考虑过任何其他选择,因为我不知道。
因此,我正在为我的特定用例寻找“最佳实践”。我很确定 Git 有一些很棒的方法来处理这个问题,但我不知道。
我看到几个选项:
Merge
正如一些人建议的,使用原始(根)存储库上的新提交“更新”分叉的最简单选项是合并。这将确保:
- 您可以轻松地从根存储库库/框架/获得最新的修复
- 你在分叉中的提交和根中的提交是完全分开的
I would 阻止变基对于这个特殊问题。正如您所提到的,分叉存储库的历史记录将被有效修改,这可能会影响在那里工作的其他开发人员/功能分支(甚至在单一开发人员存储库上)等......
如果你必须以相反的方向合并补丁,fork -> root,那么你会git cherry-pick
git submodule
另一种选择是将基础库/框架作为git submodule
在叉子里。在标准形式中,git 子模块只是指向另一个存储库+提交的指针。历史是分开的,因为它们确实是两个不同的存储库。
要在基础上集成新的更改,您只需重新指向git submodule
到这个新的提交。
一个重要的说明;仅当您的分叉存储库不触及根存储库的文件时,这才有效。
git subtree
我还不够熟悉git subtree
才能判断。但你也许也应该看看,因为这听起来像是另一个可行的解决方案
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)