git 修补以前版本的最佳做法是什么?

sh7euo9m  于 5个月前  发布在  Git
关注(0)|答案(1)|浏览(96)

我正在做一个项目,我们需要修补我们库的旧版本。我们将此包发布/发布到GitHub Package Registry并(不用说)使用语义版本控制。这是我们第一次修补以前的版本,我很难确定最佳实践。
我遇到了这个线程,除了几个问题外,大部分似乎都可以工作,尽管是主要的问题。按照我上面链接的评论中所描述的,这里是我在测试仓库中尝试的步骤。在这个例子中,让我们假设main分支上存在两个标记:v1.0.0v2.0.0,我需要用热修复程序(v1.1.0)修补v1.0.0版本。

  • checkout v1.0.0标签(git checkout v1.0.0
  • 创建修补程序分支(git checkout -b hotfix-v1.1.0
  • 将更改提交到修补程序分支(git add .;git commit -m "Hotfix v1.1.0 changes"
  • 在修补程序分支上创建修补程序标记(git tag v1.1.0
  • 交换机到中继(git checkout main
  • 将热修复程序分支合并到 Backbone.js (git merge hotfix-v1.1.0 --no-commit --strategy ours
  • 提交合并(需要手动干预)(git commit
  • 上推修补程序标签(git push --tags
  • 删除本地修补程序分支(git branch -d hotfix-v1.1.0

在这些操作之后,我在GitHub中检查了origin,发现v1.1.0 hotfix * 在最新的提交中存在 (良好),main的最新状态具有来自v2.0.0的代码(良好)。它还具有新的v1.1.0标记(良好)。
不过还是有几个问题。首先,当我在GitHub中切换到hotfix标签(v1.1.0)时,会出现以下警报:
“此提交不属于此仓库上的任何分支,可能属于仓库外的分支。"* 我不清楚这其中的含义,但这似乎不是一件好事。
更大的问题是,我执行的提交,合并等忽略了一个事实,即我的main分支受到各种状态检查的保护。能够确保现有的工作流和检查包括在此修复过程中是一个要求。
那么,修补以前版本的最佳实践是什么?提前感谢您的任何输入。

epfja78i

epfja78i1#

我只想谈谈您当前工作流程中存在的问题。
接下来,您可能希望在gitflow上有一个变化,在这里您可以从v1.0.0中创建一个发布分支,并将其保持为开放状态。如果您希望在v2中也包含这些修复,则可以在一个单独的功能分支中将它们cherry pick回v2中。您不会将v1合并到v2中,这将冒着冲突的风险,并在v2中重新启用旧的v1代码。
更大的问题是,我执行的提交、合并等操作忽略了我的主分支受各种状态检查保护的事实。能够确保现有的工作流和检查包含在此修补程序过程中是一个要求。
问题是您在没有检查的地方进行本地合并。没有工作流应该进行合并或直接提交到main。
相反,使用pull requests进行合并。这允许在合并到main * 之前 * 对分支运行检查并进行复查。
首先,当我切换到GitHub中的修补程序标签(v1.1.0)时,出现了以下警告:“此提交不属于此仓库上的任何分支,可能属于仓库外的分叉。”我不清楚这意味着什么,但这似乎不是一件好事。

注意:v1.1.0表示添加了新功能。只包含错误修复的版本应为v1.0.1。

不管git log和Github显示了什么,Git历史记录 * 不是 * 线性的。它是一个graph。每次提交都与它之前的提交相关联。你可以在git log --graph --decorateGit Kraken这样的工具上看到这一点。
分支和标记只是指向提交的标签。
Git告诉你的是提交是无法从任何分支到达的。
让我们来看看这是怎么发生的。
你可以这样开始:

local
         {v1.0.0}
A - B - C - D - E - F [main]

origin
         {v1.0.0}
A - B - C - D - E - F [main]

字符串
提交只连接到左侧。D可以到达C、B和A。C不能到达D。
v1.0.0标记指向提交C。主分支指向提交F。
A、B、C、D、E和F都可以从主服务器访问。
在这里,您的本地存储库和Github上的副本(您的“源”远程)是相同的。

#    checkout the v1.0.0 tag (git checkout v1.0.0)
#    create a hotfix branch (git checkout -b hotfix-v1.1.0)
#    commit changes to hotfix branch (git add .;git commit -m "Hotfix v1.1.0 changes")
#    create hotfix tag on hotfix branch (git tag v1.1.0)

local
         {v1.0.0}
A - B - C - D - E - F [main]
         \
          G {v1.1.0}
            [hotfix-v1.1.0]

origin
         {v1.0.0}
A - B - C - D - E - F [main]


您已经创建了修补程序分支,添加了一个提交,并标记了它。
修补程序只能访问G、C、B和A。
G是无法从主网络到达的。
尚未向Github推送任何内容。

#    switch to trunk (git checkout main)
#    merge hotfix branch into trunk (git merge hotfix-v1.1.0 --no-commit --strategy ours)
#    commit merge (which requires manual intervention) (git commit)

local
         {v1.0.0}
A - B - C - D - E - F - M [main]
         \             /
          G -----------
           {v1.1.0}
           [hotfix-v1.1.0]

origin
         {v1.0.0}
A - B - C - D - E - F [main]


您已经将修复程序分支合并到主分支中。M是一个合并提交,F和G都是其父级。在本地,G(以及v1.1.0)是主分支和修复程序分支的一部分。

# push up hotfix tag (git push --tags)
# delete local hotfix branch (git branch -d hotfix-v1.1.0)

local
         {v1.0.0}
A - B - C - D - E - F - M [main]
         \             /
          G -----------
           {v1.1.0}

origin
         {v1.0.0}
A - B - C - D - E - F [main]
         \
          G {v1.1.0}


这里是它的错误之处。Git push/pull是非常高效的,它只会推送它所需要的内容。因为你只推送了标签,所以它只推送了它需要填充标签历史的提交。这意味着它只推送了提交G。
因此,就Github而言,任何分支都无法到达commit G。这并不一定是件坏事,commit仍然可以通过标记来引用。
如果你是git push --all,Git会推送你所有的标记和分支,以及填充它们的历史记录所需的任何提交。这意味着它会推送现在指向M的main。这意味着它必须推送提交M。然后G会连接到Github上的main。

相关问题