当分叉项目都在发展时,Git 的良好实践可以使其源代码保持最新

2023-12-27

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 是痛苦的两个小时)
  • 它使用 --forceFork: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(使用前将#替换为@)

当分叉项目都在发展时,Git 的良好实践可以使其源代码保持最新 的相关文章

随机推荐

  • 是否需要“设置字符集utf8”?

    我正在重写我们的数据库类 基于 PDO 并陷入困境 我被教导要同时使用SET NAMES utf8 and SET CHARACTER SET utf8在 PHP 和 MySQL 中使用 UTF 8 时 在 PDO 中我现在想使用PDO M
  • PHP 日期比较

    如何检查 2008 02 16 12 59 57 格式的日期是否小于 24 小时前 if strtotime 2008 02 16 12 59 57 gt time 24 60 60 LESS
  • 如何确定 _POSIX_PATH_MAX 的系统值

    谁能告诉我如何找到系统值 POSIX PATH MAX在 Linux 薄荷中 我知道它在 文件中可用 但我不知道如何找到它的值 根据 POSIX 要使用的工具被命名为getconf http pubs opengroup org onlin
  • React Router Lazy 组件不起作用

    所以这有效 import Page from components Page render return
  • 有选择地将 C++ 核心逻辑暴露给 QML 的最佳方法

    我想设置特定 QML 组件的上下文属性 而不是在根上下文中 我不希望在组件外部访问该属性 C 有没有一种方法可以访问组件的上下文 只允许从组件的上下文中访问命名属性 而不是从全局命名空间中访问 我想保持 QML 声明性 而不是在 C 中创建
  • Seaborn 群图和点图躲避对齐

    有没有办法将点图的平均值 SEM 与相应的群图对齐 这是我的代码 import seaborn as sns import numpy as np import pandas as pd import matplotlib pyplot a
  • 如何在pyspark中自动删除常量列?

    我在 pyspark 中有一个 Spark 数据框 我需要从数据框中删除所有常量列 由于我不知道哪些列是常量 因此我无法手动取消选择常量列 即我需要一个自动过程 我很惊讶我无法在 stackoverflow 上找到简单的解决方案 Examp
  • 如何保持火车步骤之间的状态?

    我的计算图中有一个张量 我想在每个训练步骤之后添加一行 我怎样才能做到这一点 更详细 我正在获取渐变optimizer compute gradients 我想根据渐变历史修改这些渐变 这是我尝试使用的代码 def process grad
  • 使用 Charles 和 SSL Apple 推送地址

    我必须确认我的用于发送推送通知的 PHP 代码正在与代理一起使用 我安装了 Charles 并且可以通过代理 127 0 0 1 8888 观看我的所有网络流量 现在我想看看我的脚本是否可以正确用于推送通知 我有 stream contex
  • Python:多维数组(“矩阵”)与列表中的列表相同吗?

    我试图理解人们所说的矩阵和人们所说的列表中的列表之间的区别 它们是否相同 一旦创建 您就可以对它们执行相同的操作 在其中以相同的方式引用元素等 例子 在列表中创建列表 ListsInLists 1 2 3 4 5 6 制作多维数组 np r
  • 动态创建 zip 并将其流式传输到客户端

    我正在使用 NodeJs w express 并且尝试将 zip 文件流式传输回客户端 zip 中包含的文件并不存在于文件系统中 而是动态创建的 我想将文件内容流式传输到 zip 并将 zip 流式传输回客户端 IE 我希望客户收到 tmp
  • django allauth 自定义注册表单分配不同的组

    我的系统中有两种类型的用户 我想在注册时分配适当的组 参考使用 django allauth 时如何自定义用户配置文件 https stackoverflow com questions 12303478 how to customize
  • 如何在 Chrome 扩展中使用 Python?

    我想用 Python 创建一个 Chrome 扩展 这可能吗 还是我必须使用 JavaScript 你可以看看Pyjamas http pyjs org 因为这可以让你用 Python 编写代码 但将代码编译为 Javascript
  • JavaScript 函数未定义错误(但已定义)

    我有一个 JavaScript 函数 它会在模糊时触发 奇怪的是 我第一次运行它时它工作得很好 从那时起我就收到了一个错误 提示 JavaScript 函数未定义 并且它停止运行 我用谷歌搜索过类似的问题 但没有一个建议能够解决该问题 As
  • NTFS(Windows XP 和 Windows Vista)中的最大文件名长度?

    我正在设计一个数据库表 它将保存上传文件的文件名 Windows XP 或 Vista 使用的 NTFS 文件名的最大长度是多少 文件名的各个组成部分 即路径上的每个子目录和最终文件名 限制为 255 个字符 总路径长度限制为大约 32 0
  • OpenSSL SSL_connect:SSL_ERROR_SYSCALL 连接到 api.amazonalexa.com:443

    我一直在尝试让技能管理 API 正常工作 今天早上我遇到了一个新的障碍 但没有进行任何更改 我收到一条 用户昨晚未同意此操作错误 并且今天早上没有更改任何内容 这是我收到的卷曲日志 尝试使用与昨 晚相同的代码访问 API 现在我得到 str
  • 图执行模式下张量流 tf.data 数据集的分割示例

    Goal 我有一个tf data Dataset其中一些示例太长 0 轴的尺寸太大 我想将这些过长的示例分成几个示例 其中每个示例都是原始示例的一部分 如果特定示例不能被所需的块大小整除 我想截断余数 例如 如果原始数据集的 numpy 视
  • 如何自动刷新 Excel 文件并通过电子邮件发送?

    我有一些 Excel 文件 数据透视表和图表 它们与 Access 数据库有数据连接 我希望做的是让它们自动刷新并在每个月的 1 号收到电子邮件 我在 Access 中做了类似的事情 其中 我有一个数据库 其中包含一个可以运行并通过电子邮件
  • -O3 和 (-O2 + man gcc 说 -O3 添加到 -O2 的标志) 之间有什么区别?

    我最近收到了一份有关无法使用 O3 开关进行编译的程序的错误报告 请参阅https github com cschwan sage on gentoo issues 66 https github com cschwan sage on g
  • 当分叉项目都在发展时,Git 的良好实践可以使其源代码保持最新

    Context 我是主要作者立即下一步 https github com UnlyEd next right now这是一个开源 样板 包含使用 Next js 框架构建 Web 应用程序的多个 预设 每个预设都带有内置功能 并且旨在进行分