Git:将一个大的,凌乱的功能分支分成更小的分支

时间:2016-11-29 18:40:49

标签: git

我有一个成长和成长的特征分支,随着特征的发展,有许多曲折。我想把一些可以单独释放的块分解成它们自己的分支。

提交不够干净,不能通过提交选择来构建这样的分支(即一些提交触摸多个文件,只有一些我想要选择)。我是一个灵巧的交互式变形,大块编辑等等,但我想知道是否有更好的方法来做到这一点?

我最初的想法是创建一个分支,它是原始功能分支的副本,将它的所有提交压缩为1,重置为上一次提交(在我的工作树中保留完整的未提交的,未分级的功能分支),然后有选择地添加并提交我想要的作品。

$ git co -b partial-feature
$ git rebase -i HEAD~170

在编辑器中:

pick 234e78fa Begin writing feature
f 7844c437 Add more stuff
f 3523437 And even more
...

然后,

$ git reset HEAD~
$ git add first_good_change.rb
$ git commit -m 'Add a good change'
$ git add second_good_change.rb
$ git commit -m 'Add another good change'
...

有更聪明的方法吗?

2 个答案:

答案 0 :(得分:5)

这基本上很好,但它可以更简单一些。

  

我最初的想法是创建一个分支,它是原始功能分支的副本,将其所有提交压缩为1,重置为上一次提交

这等同于软重置到分支的开头。这是一个单一的命令,而不是一个rebase,然后是一个重置。

git checkout -b partial-feature
git reset start

其中start是您希望分支从哪里开始的SHA1。 这与HEAD~170不同,因为您不需要计算170,只需查看git log并找到合适的SHA1。

在此之后,继续你的行动:

git add first_good_change.rb
git commit -m 'Add a good change'
git add second_good_change.rb
git commit -m 'Add another good change'

等等。在任何时候,如果您愿意,您可以继续使用另一个功能分支,一点一点地释放审阅者的更改,使他们的工作更轻松,例如:

git checkout -b partial-feature-round-2
git add more_good_change.rb
git commit -m 'Add a good change'
git add even_more_good_change.rb
git commit -m 'Add another good change'

等等。只需确保在partial-feature-round-2合并之前不发布partial-feature进行审核。

在提交原始分支的所有内容后, 项目内容与原分支相同, 只是历史会有所不同。 像这样切割和切割你的历史是完全正常的。

并不总是可以通过这种方式将分支拆分为较小的分支, 例如,当更改过于相互关联时,很难将其分离到仍然有效的块。 也就是说,当您发布partial-feature进行代码审核时, 它有更好的编译和充分工作, 如果变化过于复杂,这可能很难实现。

最后提示:在为多阶段代码审核构建部分分支时, 验证部分功能是否仍然有效且处于代码可审查状态的简单方法是隐藏其余更改,并编译和运行测试。如果一切正常,分支已准备好进行代码审查,您可以创建一个拉取请求,然后继续下一个阶段,弹出存储并添加更多提交。

答案 1 :(得分:2)

你的方式相当不错,而且几乎是我在这些案例中采用的确切方法。但是,如果不是逐个文件地提交,而是希望同时提交多个文件中的更改,则可以通过为git add -i保持一个窗口打开以及对git commit交互式更改进行第二次更改来提供更好的服务。

我建议的唯一替代方案,我过去在重写和git add特别讨厌的时候使用过的,就是将最终文件从repo中复制出来,回滚分支(包括工作树),然后有选择地复制东西和git commit -am内容。如:

# starting from branch with messy commit histories
cp file1 file2 file3 [...] ~/final_versions
git reset --hard <good_commit>
vim -p file1 file2 file3 [...] ~/final_versions/*

同时,在另一个窗口git commit -am