一段时间以来,我们一直在研究一个工作分支,打算在某个时候将其带回我的主要分支。
与此同时,该工作分支通过与主要分支的频繁合并而保持最新。
现在,我们只想将工作分支的一些更改,而不是全部更改带到主分支。
这里的困难在于,这些更改根本没有被提交或文件很好地分隔开,因为从来没有人期望必须这样做。相反,单独的提交会带来我们想要在我的主分支上的更改,以及我们不想要在我的主分支上的更改。可以在任何给定的单个文件中看到这两种更改的示例。
现在,仍然有一种可能性,最终,我们将希望按照最初的计划,将该工作分支最终合并回主分支。因此,我需要保持这种可能性,它需要提供一个很好的保证,一切确实已按计划合并-或至少是一个很好的方式来检查。
正因为如此,我觉得git cherry-pick
(假设它可以下降到文件中的单个块的级别)不是我想要的选项,因为这样一来,一方面来自工作分支的所有原始提交,另一方面来自主分支的樱桃采摘生成的提交都将是愚蠢的冲突,看起来两个分支都带来了相同的变化。此外,日志将看起来完全丑陋的重复日志评论。
我宁愿有一个单一的提交说:“把所有与X和Y相关的更改,而不是Z从工作分支。然后过了一段时间,如果我们愿意的话,另一个提交说:“从工作分支带来剩余的更改,主要是关于Z的。”“我想最后一个最好有两个父母,但我不知道第一个最理想的是什么:它是否应该在工作分支中有一些提交作为其父分支?所以是merge
而不是cherry-pick
。
同时,如果我决定使用一个实际的merge
来创建第一次提交,我将不得不手动删除主分支上的代码中的内容,以忽略通过这个merge
来自工作分支的关于Z的更改。然而,由于第一次提交将工作分支的顶端作为其父分支之一(这是一个实际的merge
),因此在git看来,第一次提交包含了来自工作分支的所有更改-但这不是真的。
可能是我把自己置于一个git无法干净或原生地解决的情况下,如果是这样的话,我想知道,我会没事的。我仍然会对其他降级的解决方案感兴趣,这将打破我的一些要求。
4条答案
按热度按时间f3temu5u1#
您的最佳选择IMO是:
恢复的更改现在可以在特性分支上存在,直到决定合并它们,或者如果它们仍然不需要,则可以放弃它们。
baubqpgj2#
方法1
main
合并到feature
中main
创建并 checkout 新分支partially-merge-feature-into-main
partially-merge-feature-into-main
上,使用git checkout -p feature -- .
有选择地选择要保留/编辑并提交更改的文件更改块。partially-merge-feature-into-main
合并到feature
中,并在发生冲突时始终采用“--ours”i。feature
版本。因此,合并应该不会改变任何东西。
(But它将允许你以后合并
feature
到分支而不会再次发生这些冲突)partially-merge-feature-into-main
(最好是与--no-ff
合并,这样人们就知道那里发生了什么)方法2
feature
上创建一个提交,删除main
上不需要的所有内容(完全手动或首先合并
main
,然后在提交之前使用git checkout -p main -- .
选择性地丢弃不需要的更改/块)feature
合并到main
svdrlsy43#
这里有一个完全不同的方法。既然你的提交历史已经是一团糟了,那就放弃它并清理它:
git add
,可能与补丁,交互式等。,以形成一个“好”提交的索引基础,该提交由您现在想要合并的内容组成。做出承诺。git status
报告干净。你可以在这一点上停止,与stash保存的东西,你可能会或可能不会合并后。但是如果你打算进一步开发这些材料,那么,仍然在main上,创建一个新的分支并切换到它,弹出隐藏并添加所有内容并提交。现在有一个特性分支在等待,它只包含以后可能会合并到main中的内容。
jdzmm42g4#
一些备选方案:
Rebase
交互式地将特性分支重新定位到main上,检查和修改每个提交。
将交互式变基中的每个提交都设置为“编辑”,除了那些你知道你会完全丢弃的提交(将这些设置为“跳过”)。在每次提交时,
rebase
暂停,让您有机会查看更改(git show
),并可能修改它(git reset HEAD~
可能很方便,使所有更改在diff中可见),然后提交它(git commit --amend
),然后继续使用rebase --continue
。但是如果你的分支历史是一团乱,你可能无论如何都想把它抛在身后。如果你认为有更多的变化要放弃,而不是带来的变化。
丢弃历史,使用补丁文件
保存
git diff main...feature > feature-changes.patch
保存功能分支中发生的全部内容(注意!3个点!)。查看此文件的内容。确保所有更改都在那里。如果您已经将
main
合并回feature
,则可能需要手动查找main
的提交(feature
最初基于该提交),然后运行git diff <that commit> feature > feature-changes.patch
。现在,您将在修补程序文件中对特征分支进行的所有更改。
修改补丁文件,只留下您想要的块,然后将其应用于
main
(git checkout main
然后git apply feature-changes.patch
)。通过文件系统获取更改
checkout 分支,将其重置为main,进行新的提交。
git checkout feature
更新文件系统。git checkout -b migrate-to-main
允许您在新分支上工作,而不会有丢失feature
的风险。git reset main
将当前 checkout 的分支(记住分支只是指向提交的标签)移动到main
,但保持文件系统上的内容不变。您现在位于新分支
migrate-to-main
上,它指向与main
相同的提交,并且您的文件系统具有与feature
相同的内容。您现在可以查看diff,决定要包含哪些内容,不包含哪些内容,还可以解决其中可能存在的冲突。您可以手动执行此操作,或使用
git-gui
等工具选择要包含或不包含的内容。当你完成了,剩下的就是承诺。