【问题标题】:How can I make git history reflective of development reality when merging upstream changes onto a shared branch?将上游更改合并到共享分支时,如何使 git 历史反映开发现实?
【发布时间】:2018-08-23 05:36:33
【问题描述】:

我与其他一些开发人员一起在一个流行的公共 git 存储库的分支上工作。我们需要定期将上游更改合并到我们的分叉中。我怎样才能做到这一点并使历史反映发展现实?例如,在我合并上游更改后,我希望我们的一位开发人员能够轻松地同步到我们分支上的某个位置,该位置准确反映了 N 个月前我们的开发团队发送提交和执行测试时的世界状态,所以我们可以例如运行相同的测试并期望得到与 N 个月前相同的结果,例如轻松地对历史进行二进制搜索,以缩小引入后期发现的错误的范围。

我尝试过的一些事情:

  1. 似乎默认的 git merge 最终会根据提交的日期将上游更改与我们自己的更改交错,这使得几乎不可能同步到世界的真实状态,因为它发生了在我们开发的时候。

  2. 通过使用 --squash 合并,git 历史正确地反映了开发现实(在上游更改合并之前和之后容易同步,并且最终与 N 个月前发生的实际状态相同),但是似乎 --squash 告诉 git 忘记所有单独的提交,由于巨大的冲突,这使得将来合并新的上游更改变得极其困难。

  3. 我也试过 --no-ff 但这似乎根本没有帮助。仍然将上游历史与我们的历史交织在一起。

我是否正在尝试做一些 git 从未打算做的事情?一种可行的策略是经常合并上游的变化(比如每天或每周),这样上游和我们之间的开发现实就非常相似。但是现在我们已经几个月没有合并上游,如果有一种方法可以基本上实现良好的 --squash 行为,但又不放弃 git 对单个提交的了解,那就太好了。我考虑手动进行许多较小的 --squash 合并,例如上游历史的每一周。我猜这将更容易合并未来的上游更改,但这非常痛苦。有什么强有力的理由这样做或不这样做吗?有更好的想法吗?

哦,实际上还有一个想法:也许我可以将上游的更改重新定位到我们的分支上,如果我理解正确,这将实现我想要的“反映开发现实的状态”(有人可以确认这是真的吗?),但是我'仍然想稍微压缩一下,以便我的团队的提交数量大大减少,不会被上游提交所淹没,这使得检查和理解我们的分支历史变得更加困难。在这种情况下,rebase+squash 是否有意义,或者与纯 squash 相比没有真正的优势?

【问题讨论】:

  • 您可能(正如 Tim Beigeleisen 回答的那样)想要使用变基模型,但请注意,当您查看提交并看到它们像这样交错时,这只是 Git 向您显示像这样交错的提交,on这就是你希望 Git 向他们展示的方式的理论。 git log 可以选择过滤和/或排序根据您想要显示的内容将提交按不同的顺序。特别是,考虑添加--graph 或使用图形查看器和--simplify-by-decoration 以获得“30,000 英尺”视图。

标签: git github merge


【解决方案1】:

使用变基工作流程可能是您在此处寻找的内容。要了解变基的工作原理,请考虑以下简单的分支图:

remote: A -- B
               \
local:           C

这里,我们从一个本地分支开始,从远程分支,添加了一些新的提交C,但还没有推送。当然,实际上,您团队中的其他人可能会将他们自己的新提交推送到远程,所以我们也这样做:

remote: A -- B -- D
               \
local:           C

现在明白您不能简单地将本地分支推送到远程。解决此问题的一种方法是将远程合并到您的本地分支中。但这会创建一个合并提交,给你留下一个非线性的历史,随着时间的推移,可能会变得难以阅读。这里有一个替代方案;你可以使用git rebase。如果您运行以下命令:

git fetch origin
git rebase yourBranch origin/yourBranch

那么您将得到以下分支图:

remote: A -- B -- D
                    \
local:                C'

换句话说,您的本地分支将是完全线性的,并且您只需执行一个简单的git push 即可将您的更改集成到远程。这样的推送实际上只是快进遥控器,放下你的新提交。

如果您能找到遵循变基工作流程的方法,那么您的远程分支将始终是线性的,并且在某种程度上,您将及时回到开发过程中的任何确切点。

【讨论】:

  • 感谢您的快速回复。不过,我认为这在这种情况下没有帮助,似乎更多的是个人推动个人更改的工作流程,而不是大型上游合并案例。在您的示例中,让我们想象“远程”是每月有数百次提交的公共仓库,让我们想象“本地”是我们的几个开发人员团队用作他们的 master 概念的共享分支。如果我们变基,我们将失去同步到 N 个月前存在的时间点的能力,因为上游更改现在存在,而当我们在 N 个月前进行测试时它们不存在。
  • @RonPaul 不,您的推理/理解已失效。当任何人从远程分支拉取时,他们会做git pull --rebase origin master。所以每个人都领先于远程分支。许多开源项目都使用此工作流程。
  • 嗯,我还没关注。你能再澄清一点吗?应该涉及 3 个分支,而不仅仅是 2 个。有官方上游公共 repo 的 master(我们称之为 public_master),然后是我们团队的 fork(我们使用最多,并认为它是我们的 master,但我们称之为master_fork),然后有一个假设开发人员的本地分支正在开发一个功能。在大多数情况下,我们的开发人员只与 master_fork 及其本地分支合作。每隔一段时间,我们需要从 public_master 拉取上游更改并将它们放入 master_fork。
  • 您的问题很长且令人费解,但我从中了解到您希望在分支历史中有所明确。变基工作流是实现这一目标的一种方法,因为它使事情保持线性。
  • 我同意这个问题很长,但并不复杂。我努力解释得很清楚。我仍然是 git newb,但您似乎没有阅读完整的问题,然后回答了一个不适用于这种情况的通用变基示例。
猜你喜欢
  • 2021-09-03
  • 2017-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-11
  • 2019-03-29
  • 2014-12-04
相关资源
最近更新 更多