Git 良好实践,在两者都在发展时保持分叉项目与其源来源保持同步

Vad*_*est 5 git rebase git-fork next-right-now

语境

我是Next Right Now的主要作者,这是一个开源“样板”,其中包含使用 Next.js 框架构建 Web 应用程序的几个“预设”。每个预设都带有内置功能,旨在进行分叉,以便其他人可以基于它构建他们的应用程序。每个预设都位于自己的 git 分支中,例如:

我正在研究 NRN 并使其定期发展。但是,我也分叉了一个可用的 NRN 预设,并从中制作了我自己的专有应用程序。

定义

为了避免术语误解,这里有一些定义。

问题

这种做事方式的问题在于我不确定如何使“Fork”与 NRN 样板预设保持同步。两者都以自己的方式发展。此外,NRN 不是一个框架而是一个样板,它旨在被覆盖以自定义基本代码,这最终会导致 Fork 和 Source 之间的许多冲突。

到目前为止我一直在做什么

为了让我的 Fork 与 Source 上的最新更改同步,我基本上rebase是在 Source git 历史记录之上进行自己的工作。(如:git rebase NRN-v2-mst-aptd-at-lcz-sty

这具有以下优点(优点):

  • 它使历史保持干净且易于理解/比较。通过比较它们的历史记录,我可以很容易地知道哪个是我从源同步的最新提交。在 Fork 中完成的所有工作都是在Source 中完成的工作之上完成的。
  • git 树分为两个不同的部分,源提交树和 Fork 提交树。
  • 我可以通过使用 git rebase 将我的 Fork 更新到最新,然后push --force覆盖远程,将 Source 中完成的新更改同步到 Fork 中。

但也有一些缺点(缺点):

  • Fork只有一个分支的时候,处理两个分支之间的同步并没有那么复杂,但是一旦有多个分支就会变得很乱,因为它重写了所有分支的git历史,当有分支时就变得相当复杂Fork 中其他“功能”分支的持续工作。首先,我需要重新设置 Fork:master 的基础,然后使用 Fork:master 重新设置每个分支的基础。如果我以错误的方式做它会弄乱整棵树(我犯了一次错误,并且到处都使用 --force 进行重新定位是两个痛苦的小时)
  • 它使用 --force Fork:master分支,恕我直言,这不是那么好,如果处理不当可能会导致很多麻烦。我对我正在做的事情有点熟悉,但是如果团队中有更多人,这将不可行。
  • 总的来说,我对自己有能力不把事情搞砸的能力没有信心。
  • 它感觉不适合团队,它只是因为我正在独自工作,恕我直言。
  • 当它发生冲突时,解决起来可能会很痛苦,而且我碰巧犯了好几次错误。
  • git 历史是不可信的,我的 Fork 工作分支在与 Source 同步时重写了它们的提交历史,并且所有 GitHub 评论都失去了用处,因为它们不再与任何提交匹配。

使用 rebase,我最终不得不擦除我的整个工作分支并通过挑选我在 Fork 中完成的所有提交从源重新创建它,因为历史不再匹配,我需要一个干净的开始。这是在我以错误的方式重新定位而犯了一些错误之后发生的。

我在找什么

我目前的方式工作正常,只要我是独奏,只要我很好地了解我的 git 分支,只要我不通过重新设置和推动 --force 错误的方式来搞砸。不过,这并不能让我满意。

我正在寻找一种更好的方法,该方法可用于团队,并且我可以将其用作“官方推荐”的方式来保持 Fork 与其 NRN 源同步。

备择方案

我想过 cherry-pick过从 Source 向 Fork 提交 -ing 提交,但我不确定这是否是更好的选择,因为它会将 Source 和 Fork 提交混合在一起(两者之间不再分离)。这最终会导致在比较两棵树并找出哪些提交已经被挑选出来而哪些没有被挑选时遇到困难。此外,它并不能保护我免于忘记挑选一个提交并在数周后遇到麻烦,这可能会导致使用 --force 重写历史记录以将丢失的提交包含在正确的位置。

我没有考虑任何其他选择,因为我不知道。


因此,我正在为我的特定用例寻找“最佳实践”。我很确定 Git 有一些很棒的方法来处理这个问题,这是我不知道的。

Sim*_*mon 1

git --force-with-lease是一个更安全的选项,如果将更多提交添加到远程分支(由另一个团队成员或同事或您拥有的其他人),则不会覆盖远程分支上的任何工作。它确保您不会通过强制推送来覆盖别人的工作。

如果每个功能都经过拉取请求,并且没有直接在 master 分支上进行任何更改,则单独 Rebase 仍然是一个不错的选择

  • 更好(很快):`git push --force-with-lease --force-if-includes`,[从 Git 2.30 开始](/sf/answers/4523943301/)。 (2认同)