合并修补程序分支以开发重新引入旧更改
Merging hotfix branch to develop re-introduces old changes
我们一直在尝试 git 团队中的流程。我们基于 develop
分支创建发布分支。然后我们在release之后合并release分支到develop
和master
。到目前为止,我们已经发布了几个没有修补程序的版本。
现在,我们刚刚遇到了一个需要修补程序的事件(第一个修补程序)。所以我们基于 master
创建了修补程序分支。我们将 hotfix 分支合并到 master,一切都很好。然后我们尝试将修补程序分支合并到 develop
,diff 显示旧的更改被重新引入到 develop
。例如,有些文件本应删除,但在合并后重新添加到 develop 中。在合并之前,staging 和 master 是相同的(没有任何差异)。
知道是什么原因造成的吗?我想展示示例 history/graph,但由于合并,我们的历史非常混乱。
Any idea what is causing this?
当然是合并基础提交的选择。这个选择不是 你的: Git 根据提交图自动做出选择。这就是为什么 这个 步骤:
so we created hotfix branch based off of master
可能是创建错误(或者“根本原因”,如果你愿意的话)。
您可以查看 Git 认为哪些提交是 develop
和 master
的合并基础,使用:
git merge-base --all develop master
这将打印出一个或多个提交哈希 ID。1 如果它只打印 一个 哈希 ID——这是通常的情况——那么那个哈希 ID 就是合并基础提交的哈希 ID。如果它打印两个或更多,Git 将通过合并列出的提交来 构建 合并基础(无论如何 git-merge-recursive
);这些情况很棘手。
请记住,git merge
完全是关于 组合更改 ,但 Git 根本不会 存储 更改. Git 存储 快照: 每个提交都保存每个文件的完整快照,作为一种时间冻结的存档,说这就是项目在这 (快照)时间。将快照变成变化的唯一方法是至少拍摄 两张 快照并进行比较,就像玩 Spot the Difference.
游戏一样
发现两个分支提示(master
和 develop
)之间的差异是没有用的,因为将这些差异应用到一个分支提示只会产生另一个快照。 (在这种情况下,我们为什么还要为分支而烦恼?)所以这不是合并的工作方式。
相反,合并会找到 过去某处 的快照,回到 master
和 develop
分歧 [=85] 之前=].通过将 that 快照与 master
末尾的快照进行比较,Git 可以看到 master
中发生了什么变化。通过将 相同的 快照与 develop
末尾的快照进行比较,Git 可以看到 develop
中发生了什么变化。然后,Git可以合并这两组更改,以保留您的更改,但也添加他们的更改。
这个过程在算法上很简单——嗯,相对简单(尽管在实践中需要做很多工作,这就是为什么我们让 计算机 来做)。在某些情况下,它 太 简单,并且会产生错误的结果。你的情况似乎就是其中之一。
如果您找到引入 bug 本身的提交(过去的某个时间点,也许是遥远的过去)并创建一个分支,您可以在它之后立即修复该 bug简介,然后你可以将 this 分支合并到 master
和 develop
中。从该分支的合并基础(使用 master
或 develop
)到该分支的提示的更改将 只是修正 。从这个合并基础到 master
的尖端或 develop
的尖端的变化将是 发生的所有其他事情 。因此,将 this 分支合并到 master
和 develop
中通常会产生正确的结果,而不会引入其他不需要的更改。但这通常比为 master
制作一个修补程序分支更困难——有时 多 。所以选择权在你。
您可以考虑使用 git cherry-pick
将修补程序复制到 develop
分支。挑选樱桃有其自身的危险——例如,如果修补程序被证明有它自己的错误,现在你需要修复它两次——但它是商店里的另一种工具。 Git 是一家拥有大量工具的大商店。选择正确的锯子、锉刀、锤子、刨子、螺丝刀、钻头等,你会完成很多好事。选错了……好吧……
1如果历史不相关,它可能会打印 none,但在那种情况下,您会看到有关不相关历史的错误。
我们一直在尝试 git 团队中的流程。我们基于 develop
分支创建发布分支。然后我们在release之后合并release分支到develop
和master
。到目前为止,我们已经发布了几个没有修补程序的版本。
现在,我们刚刚遇到了一个需要修补程序的事件(第一个修补程序)。所以我们基于 master
创建了修补程序分支。我们将 hotfix 分支合并到 master,一切都很好。然后我们尝试将修补程序分支合并到 develop
,diff 显示旧的更改被重新引入到 develop
。例如,有些文件本应删除,但在合并后重新添加到 develop 中。在合并之前,staging 和 master 是相同的(没有任何差异)。
知道是什么原因造成的吗?我想展示示例 history/graph,但由于合并,我们的历史非常混乱。
Any idea what is causing this?
当然是合并基础提交的选择。这个选择不是 你的: Git 根据提交图自动做出选择。这就是为什么 这个 步骤:
so we created hotfix branch based off of
master
可能是创建错误(或者“根本原因”,如果你愿意的话)。
您可以查看 Git 认为哪些提交是 develop
和 master
的合并基础,使用:
git merge-base --all develop master
这将打印出一个或多个提交哈希 ID。1 如果它只打印 一个 哈希 ID——这是通常的情况——那么那个哈希 ID 就是合并基础提交的哈希 ID。如果它打印两个或更多,Git 将通过合并列出的提交来 构建 合并基础(无论如何 git-merge-recursive
);这些情况很棘手。
请记住,git merge
完全是关于 组合更改 ,但 Git 根本不会 存储 更改. Git 存储 快照: 每个提交都保存每个文件的完整快照,作为一种时间冻结的存档,说这就是项目在这 (快照)时间。将快照变成变化的唯一方法是至少拍摄 两张 快照并进行比较,就像玩 Spot the Difference.
发现两个分支提示(master
和 develop
)之间的差异是没有用的,因为将这些差异应用到一个分支提示只会产生另一个快照。 (在这种情况下,我们为什么还要为分支而烦恼?)所以这不是合并的工作方式。
相反,合并会找到 过去某处 的快照,回到 master
和 develop
分歧 [=85] 之前=].通过将 that 快照与 master
末尾的快照进行比较,Git 可以看到 master
中发生了什么变化。通过将 相同的 快照与 develop
末尾的快照进行比较,Git 可以看到 develop
中发生了什么变化。然后,Git可以合并这两组更改,以保留您的更改,但也添加他们的更改。
这个过程在算法上很简单——嗯,相对简单(尽管在实践中需要做很多工作,这就是为什么我们让 计算机 来做)。在某些情况下,它 太 简单,并且会产生错误的结果。你的情况似乎就是其中之一。
如果您找到引入 bug 本身的提交(过去的某个时间点,也许是遥远的过去)并创建一个分支,您可以在它之后立即修复该 bug简介,然后你可以将 this 分支合并到 master
和 develop
中。从该分支的合并基础(使用 master
或 develop
)到该分支的提示的更改将 只是修正 。从这个合并基础到 master
的尖端或 develop
的尖端的变化将是 发生的所有其他事情 。因此,将 this 分支合并到 master
和 develop
中通常会产生正确的结果,而不会引入其他不需要的更改。但这通常比为 master
制作一个修补程序分支更困难——有时 多 。所以选择权在你。
您可以考虑使用 git cherry-pick
将修补程序复制到 develop
分支。挑选樱桃有其自身的危险——例如,如果修补程序被证明有它自己的错误,现在你需要修复它两次——但它是商店里的另一种工具。 Git 是一家拥有大量工具的大商店。选择正确的锯子、锉刀、锤子、刨子、螺丝刀、钻头等,你会完成很多好事。选错了……好吧……
1如果历史不相关,它可能会打印 none,但在那种情况下,您会看到有关不相关历史的错误。