GIT 工作流程:将大部分功能分支合并到 master 中,省略一个特定的提交?
Posted
技术标签:
【中文标题】GIT 工作流程:将大部分功能分支合并到 master 中,省略一个特定的提交?【英文标题】:GIT Workflow: Merge most of a feature branch into master, omitting one specific commit? 【发布时间】:2019-12-28 14:01:17 【问题描述】:上下文:
两个独立的特性被提交到同一个分支。最旧的提交代表一个内聚特性(“特性 1”)。所有后续提交都代表第二个独立的内聚特征(“特征 2”)。
回想起来,这些应该是单独的功能分支,但它们都提交给同一个分支。
问题:
现在:发生了可预测的问题。要求开发人员将功能 2 合并到 Master,而不是功能 1。
他们做了什么:
#0 他们从 MASTER 分支,打算将分支用于功能 2 - 将他们的新分支称为“Feature_2”。
#1 他们忘记了他们所在的分支(功能 2),并在一次提交中为“功能 1”制作/测试/提交/推送大量文件更改。
#2、3、4 然后他们继续为功能 2 进行所有必要的更改,提交并推送到同一个分支。
现在 - 有人要求他们在没有功能 1(提交 #1)的情况下提交功能 2(提交 #2、#3、#4)。
#4 他们创建了一个新分支并将其命名为“BEFORE_REVERTING_#1”
#5 他们 Git Revert commit#1(通过 sourcetree 的“反向更改...”选项。)
#6 他们将 commit#5 合并到 master 中。
最终状态:
所以现在他们已经成功地将 #2,3,4 合并到 master 中,而无需使用 #1 中的代码。
问题:
现在或以后,我们如何将 Feature 1 / Commit #1 拉入 Master? (这样特征 1 和 2 都在 Master 中,并且历史在某种程度上是可破译的,如果不是完全精简的话)
我说得对吗,我们不能仅仅通过合并来做到这一点,因为 BEFORE_REVERTING_#1 只是指向稍后恢复的同一节点的指针,并且将被快速转发,并且需要使用其他一些 .git 功能?
如果您有幸了解 SourceTree 用户界面 - 有没有使用 SourceTree 的简单方法来做到这一点?
假设 #1-3 已经发生,开发人员应该做什么,而不是步骤 4/5 中的方法?
感谢您提供的任何帮助或澄清!
【问题讨论】:
【参考方案1】:现在或以后,我们如何将 Feature 1 / Commit #1 拉入 Master?
Cherry pick它。本质上,这复制了提交。
git checkout master
git cherry-pick <commit id of feature 1>
假设 #1-3 已经发生,开发人员应该做什么,而不是步骤 4/5 中的方法?
还原提交很好。但他们也可以将功能分支分成两个分支。
你有这个。
A - B [master]
\
1A - 2A - 2B [feature]
你想要这个。
2A - 2B [feature]
/
A - B [master]
\
1A [feature1]
首先,在 1A 上粘贴一个新分支。
git branch feature1 1A
A - B [master]
\
1A [feature1]
\
2A - 2B [feature]
然后在 master 之上 rebase 2A 和 2B。
git rebase --onto master 1A 2B
2A1 - 2B1 [feature]
/
A - B [master]
\
1A [feature1]
你已经完成了。
对于更复杂的解开,使用interactive rebase 选择性地删除 提交。例如,如果您有...
A - B [master]
\
1A - 2A - 1B - 2B [feature]
而你想要...
2A - 2B [feature]
/
A - B [master]
\
1A - 1B [feature1]
在feature
建立一个新分支。
git checkout feature
git branch feature1
A - B [master]
\
1A - 2A - 1B - 2B [feature]
[feature1]
然后对它们中的每一个进行交互式变基。删除有问题的提交。从 feature
删除 1A 和 1B。从 feature1
删除 2A 和 2B。
git checkout feature
git rebase -i master
# delete 1A and 1B
2A - 2B [feature]
/
A - B [master]
\
1A - 2A - 1B - 2B [feature1]
git checkout feature1
git rebase -i master
# delete 2A and 2B
2A - 2B [feature]
/
A - B [master]
\
1A - 1B [feature1]
【讨论】:
【参考方案2】:摘樱桃(根据 Schwern 的回答)可能是最简单的解决方案;但请考虑您的团队/项目的分支策略。您可能希望选择新的 feature 1
分支并将其合并到 master 中,而不是直接选择到 master 中。
还有多种其他方法可以复制由于还原而从master
(或其他分支)中排除的提交,具体取决于具体情况。如果整个分支已被排除(因为它已合并并且合并已恢复),检查分支和rebase -f
通常是有意义的。主要区别在于,如果您这样做,您将使用新提交重写分支历史记录(除非您专门使用不这样做的过程);在挽救整个分支的情况下,这可能是您想要的,但您需要了解如果分支已共享,则重写该分支的含义。
我不同意另一个答案的地方是,开发人员所做的可能或可能不会“很好”。这取决于您的团队关于如何使用 git 的协议。这可能看起来很挑剔,但我真的厌倦了 slashdot 上的“专家”告诉团队他们的工作协议应该是什么样子,只是因为这是他们习惯做事的方式。
一般来说,开发者有两个选择:他们可以从feature 2
分支恢复提交——他们可能是最直接的变体——代价是必须稍后复制恢复的提交并拥有“奇怪”的历史记录.或者他们可以重写历史以分离分支,但代价可能是对所有开发人员进行一些分支清理,因为这意味着重写已经共享的分支的历史(参见git rebase
文档,他们在其中谈论“上游变基")
【讨论】:
以上是关于GIT 工作流程:将大部分功能分支合并到 master 中,省略一个特定的提交?的主要内容,如果未能解决你的问题,请参考以下文章