【问题标题】:Modify old release on Github for pushing out a patch在 Github 上修改旧版本以推出补丁
【发布时间】:2015-03-16 23:03:04
【问题描述】:

假设我有各种标签/版本,1.0、1.0.1、1.0.2、1.0.3。 Master 分支目前是最前沿的,正在为 1.1.0 做准备。

我现在意识到我需要推送一个小补丁,1.0.4。

制作基于 1.0.3 的补丁,将其推送到 github,将其标记为 1.0.4,但仍将 master 分支保持在最前沿并为 1.1.0 做准备的最佳方法是什么?

编辑: 有问题的存储库(注意,它实际上是 v1.0.5 -> v1.0.6):https://github.com/brashrebel/render

【问题讨论】:

  • 如果可能的话,我认为查看相关存储库可能会有所帮助。
  • 你真的应该考虑使用工作流like this。这将使您能够轻松管理版本,而不必担心在处理主要版本时必须发布修补程序。
  • 我一定会阅读并考虑实施它。

标签: git github


【解决方案1】:

您检查了您想要作为补丁基础的提交。你做必要的事情,创建你的提交,标记结果并推送。为了让它们进入你的主线,你可以挑选那些提交或合并分支。

现在,如果新标签不在分支上,可能会有点尴尬。我当然从未见过只能通过标签访问的分支。所以我个人的建议是将分支合并回来。

更具体一点:

$ git checkout -b v1.0.5_fixes v1.0.5    # create a bugfix branch
# ... do some work ...
# ... make commits ...
$ git tag v1.0.6
$ git checkout master
$ git merge v1.0.5_fixes     # merge back, solve merge conflicts if any
$ git branch -d v1.0.5_fixes # delete the branch, it's not needed anymore

【讨论】:

  • 第 6 行可能是 git merge v1.0.5_fixes 吗? v1.0.5 应该已经在 master ... 否则,通过在没有变基的情况下将该分支合并回 master 中,1.0.5 的更改不会“高于”1.0.6 的更改吗?
  • @logc 是的,v1.0.5_fixes,谢谢。在我看来,rebase 不是解决这个问题的好方法。我不确定你所说的“在上面”是什么意思。 v1.0.5 是一个版本,添加了一些修复程序,它变成了v1.0.6
  • @logc - musiKk 已经完美地描述了 IMO - 在这种情况下根本不应该使用 rebase。 (编辑 - 哎呀,我看到有一个导致评论混乱的编辑)
  • 也许我错了。我在答案中添加了一些图表,以解释我如何看待这种情况。但是,如果我错了,请纠正我——今天我真的很累:)
【解决方案2】:

我会说您有两种可能性:一种将 1.0.4 作为悬空提交留在其自己的分支中,另一种将您以后的所有提交重新定位在该新分支之上,然后将其丢弃。

第一个意思是:

$ git checkout v1.0.3
$ git checkout -b patch-for-1.0.4
# ... edit files ...
$ git commit -a -m 'Patch for 1.0.4'
$ git tag v1.0.4

在此之后,您的标签 v1.0.4 不在 master 分支中,但可以在 repo 中找到,您可以从中发布。您只需要注意不要删除分支patch-for-1.0.4

第二个意思是做前面提到的,然后继续:

$ git checkout master
$ git rebase patch-for-1.0.4
# ... solve conflicts ...
$ git branch -d patch-for-1.0.4

这假设从 1.0.3 到 1.1.0 的所有提交都在 master 上完成。如果你预计会有很多冲突,你可能想先在 master 上的一个分支上测试这个,或者做一个--interactive rebase。

第二种选择更简洁,您可以删除patch-for-v1.0.4 分支;但它需要在新提交之上重新构建旧提交,这并不是每个人都喜欢做的事情,特别是如果你在一个团队中工作。

编辑

这是你的起始情况:

A -------- B - C - D  ( ... will become v1.1.0)
(v1.0.3)

第一个 sn-p 创建一个补丁并将其作为悬空提交留在自己的分支中:

A -------- B - C - D
\
 --- E
     (v1.0.4)

如果此时进行合并,您将得到:

A --------- B - C - D --------- E
(v1.0.3)            (v1.1.0)    (v1.0.4)

为了避免E 被放在B - C - D 提交之上,做一个rebase:

A --------- E ------- B' - C' - D'
(v.1.0.3)  (v1.0.4)             (v1.1.0)

请注意,此更改将B - C - D 提交到B' - C' - D',它们具有相同的内容(冲突修复除外),但哈希值不同,因为它们现在位于E 之上,而不是A。这可能会破坏您团队中其他人的 master 分支或他们的功能分支,但会按照逻辑顺序进行。

【讨论】:

  • 我猜我们的差异源于这样一个事实,即在 git 中,历史不必是“有序的”。分支可以随时启动和合并。为什么你会关心“E 在上面”?您只需要关心 E 在固定版本以及即将发布的版本中(v1.1.0 和更高版本)。如果在 B、C、D 中有十个其他版本怎么办?那是GPG签名的吗?如果它比你自己的玩具项目稍微多一点,你应该在这里变基。
  • @musiKk :我不同意这一点。如果在提交 B 上添加了文件 X(或更改了公共 API Y),那么如果您在提交 B 之后合并提交 E,则版本 1.0.4 将包含这些更改。好吧,变基不是玩具,特别是在主分支上;我同意。我在这里展示了如何完成一项操作,但由 OP 知道在他的情况下是否可以接受。
  • 这不是真的。事实上,你的合并图片是错误的。合并引入了一个额外的提交,比如 M,它加入了 master 和 fix 分支。在任何情况下,标签v1.0.4“移动”都不会像你显示的那样。
  • @musiKk 如果我听起来很激进,我很抱歉。我愿意被纠正。但是我只是在本地git仓库做实验,是的,我的合并图是对的——有一个合并提交,但是E放在之后 B,C和D。你可以检查一下关于这个要点:gist.github.com/logc/21450abfa3000897f8cf
  • 你听起来并不咄咄逼人。我的假设是你做一个git checkout master; git merge E。如果是这样,那图像肯定是不对的。 E 和 D 都会导致新的合并提交 M。如果你想看到,你必须查看 git log --graph 的输出。 git log 输出总是线性的,但这并不意味着历史是线性的。 (不知道它是否在示例中,因为我觉得很难阅读。它非常嘈杂,我不知道你的别名。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-18
  • 1970-01-01
  • 2016-08-28
  • 2010-09-21
  • 2022-12-17
  • 1970-01-01
相关资源
最近更新 更多