GIT:我可以在挤压合并到 master 的同时维护一个正在进行的开发分支吗?
GIT: can I maintain a ongoing development branch while squash-merging to master?
这看起来应该是一个简单的问题来寻找答案,但我一直在寻找和拉扯我的头发一上午,我就是找不到让我满意的答案。我能找到的最接近的是这个问题,Git merge squash repeatedly,但那个问题是 11 年前的,所以希望“除非创建临时分支,否则你根本无法做到这一点”的共识已经改变.
我正在从事一个长期项目,我基本上是唯一的贡献者。理想情况下,我希望有一个长期持续的 development
分支,我可以继续一点一点地修补和工作,并在我到达时定期对 master
分支进行挤压合并稳定的,可释放的状态。我不想在 master
上获得完整的提交历史记录 available/visible,因为我希望能够轻松地回顾稳定官方版本的历史记录。但是,我确实希望完整的提交历史记录在某个地方可用,以备不时之需。
问题是,如果我尝试按照直觉上感觉应该可行的方式来执行此操作,它就是行不通。 squash-merge-commit 在 master
上创建了一个提交,它与 development
中的任何内容都不匹配,所以下次我尝试做一个 squash-merge 时,它会说存在冲突,我需要从 master
合并到 development
... 随着我越来越多地重复这个过程,这个问题不断增长,我有六个提交在两个分支之间来回跳动实际上并没有更改任何文件,但我似乎无法摆脱它。
我想要制作的图形图片看起来像这样,如果有任何意义的话:
B-------------------G-----------J master
/ / /
a---b---c---d---e---f---g---h---i---j development
到目前为止我一直在使用的解决方案非常丑陋:我用版本号创建了一个新分支,例如 development_601
,然后我从那个分支向 master 发出拉取请求,当我再次稳定并压缩合并提交,然后我在压缩合并后从 master
创建另一个新分支 development_602
。 development_601
被封存。这看起来很混乱,很烦人,而且是错误的,特别是因为 Git 似乎暗示我应该在合并拉取请求后删除我的分支,但就像我说的那样,我想在某个地方记录我完整的混乱历史,我只是不希望它(很容易)从外部可见。
我一直在使用 Github 桌面应用程序和 Github 网站;我一直在努力避免将控制台命令放入我的工作流程中。
想要这种奇怪的行为吗?我觉得“有一个长期 development
分支和一个 master
/release
分支定期但不完全反映它”是一个非常常见的系统,但不知何故我找不到任何解释如何实现它的地方。
此问题已在 Git FAQ 中得到解答,您遇到的问题很常见:
In general, there are a variety of problems that can occur when using squash merges to merge two branches multiple times. These can include seeing extra commits in git log output, with a GUI, or when using the ...
notation to express a range, as well as the possibility of needing to re-resolve conflicts again and again.
When Git does a normal merge between two branches, it considers exactly three points: the two branches and a third commit, called the merge base, which is usually the common ancestor of the commits. The result of the merge is the sum of the changes between the merge base and each head. When you merge two branches with a regular merge commit, this results in a new commit which will end up as a merge base when they’re merged again, because there is now a new common ancestor. Git doesn’t have to consider changes that occurred before the merge base, so you don’t have to re-resolve any conflicts you resolved before.
When you perform a squash merge, a merge commit isn’t created; instead, the changes from one side are applied as a regular commit to the other side. This means that the merge base for these branches won’t have changed, and so when Git goes to perform its next merge, it considers all of the changes that it considered the last time plus the new changes. That means any conflicts may need to be re-resolved. Similarly, anything using the ...
notation in git diff, git log, or a GUI will result in showing all of the changes since the original merge base.
这种方法总是会导致问题。如果你有两个 long-运行 分支,你需要使用常规的合并提交。否则,您可以创建短期分支,然后分别合并到每个 运行 长分支中,或者使用变基策略。如果您花时间创建独立的、合乎逻辑的提交并带有良好的提交消息,如 Git 鼓励您这样做,那么所有这些方法都会更有吸引力。
作为 Git 开发人员,我的个人建议是编写合理的提交,然后使用常规的合并提交。如果您的历史很好,那么就没有理由隐藏它。
然而,Git 和合并工作的基本原理并没有随着时间的推移而改变,所以关于长 运行 分支和压缩合并的答案“不要这样做”一直没有改变' 也改变了..
这看起来应该是一个简单的问题来寻找答案,但我一直在寻找和拉扯我的头发一上午,我就是找不到让我满意的答案。我能找到的最接近的是这个问题,Git merge squash repeatedly,但那个问题是 11 年前的,所以希望“除非创建临时分支,否则你根本无法做到这一点”的共识已经改变.
我正在从事一个长期项目,我基本上是唯一的贡献者。理想情况下,我希望有一个长期持续的 development
分支,我可以继续一点一点地修补和工作,并在我到达时定期对 master
分支进行挤压合并稳定的,可释放的状态。我不想在 master
上获得完整的提交历史记录 available/visible,因为我希望能够轻松地回顾稳定官方版本的历史记录。但是,我确实希望完整的提交历史记录在某个地方可用,以备不时之需。
问题是,如果我尝试按照直觉上感觉应该可行的方式来执行此操作,它就是行不通。 squash-merge-commit 在 master
上创建了一个提交,它与 development
中的任何内容都不匹配,所以下次我尝试做一个 squash-merge 时,它会说存在冲突,我需要从 master
合并到 development
... 随着我越来越多地重复这个过程,这个问题不断增长,我有六个提交在两个分支之间来回跳动实际上并没有更改任何文件,但我似乎无法摆脱它。
我想要制作的图形图片看起来像这样,如果有任何意义的话:
B-------------------G-----------J master
/ / /
a---b---c---d---e---f---g---h---i---j development
到目前为止我一直在使用的解决方案非常丑陋:我用版本号创建了一个新分支,例如 development_601
,然后我从那个分支向 master 发出拉取请求,当我再次稳定并压缩合并提交,然后我在压缩合并后从 master
创建另一个新分支 development_602
。 development_601
被封存。这看起来很混乱,很烦人,而且是错误的,特别是因为 Git 似乎暗示我应该在合并拉取请求后删除我的分支,但就像我说的那样,我想在某个地方记录我完整的混乱历史,我只是不希望它(很容易)从外部可见。
我一直在使用 Github 桌面应用程序和 Github 网站;我一直在努力避免将控制台命令放入我的工作流程中。
想要这种奇怪的行为吗?我觉得“有一个长期 development
分支和一个 master
/release
分支定期但不完全反映它”是一个非常常见的系统,但不知何故我找不到任何解释如何实现它的地方。
此问题已在 Git FAQ 中得到解答,您遇到的问题很常见:
In general, there are a variety of problems that can occur when using squash merges to merge two branches multiple times. These can include seeing extra commits in git log output, with a GUI, or when using the
...
notation to express a range, as well as the possibility of needing to re-resolve conflicts again and again.When Git does a normal merge between two branches, it considers exactly three points: the two branches and a third commit, called the merge base, which is usually the common ancestor of the commits. The result of the merge is the sum of the changes between the merge base and each head. When you merge two branches with a regular merge commit, this results in a new commit which will end up as a merge base when they’re merged again, because there is now a new common ancestor. Git doesn’t have to consider changes that occurred before the merge base, so you don’t have to re-resolve any conflicts you resolved before.
When you perform a squash merge, a merge commit isn’t created; instead, the changes from one side are applied as a regular commit to the other side. This means that the merge base for these branches won’t have changed, and so when Git goes to perform its next merge, it considers all of the changes that it considered the last time plus the new changes. That means any conflicts may need to be re-resolved. Similarly, anything using the
...
notation in git diff, git log, or a GUI will result in showing all of the changes since the original merge base.
这种方法总是会导致问题。如果你有两个 long-运行 分支,你需要使用常规的合并提交。否则,您可以创建短期分支,然后分别合并到每个 运行 长分支中,或者使用变基策略。如果您花时间创建独立的、合乎逻辑的提交并带有良好的提交消息,如 Git 鼓励您这样做,那么所有这些方法都会更有吸引力。
作为 Git 开发人员,我的个人建议是编写合理的提交,然后使用常规的合并提交。如果您的历史很好,那么就没有理由隐藏它。
然而,Git 和合并工作的基本原理并没有随着时间的推移而改变,所以关于长 运行 分支和压缩合并的答案“不要这样做”一直没有改变' 也改变了..