在我决定将其转换为实际提交之前,我正在使用StGit来使用补丁来管理我的代码。 (旁注:是的,我知道,StGit补丁实际上只是在引擎盖下提交)
然后我将大量代码添加到单个StGit补丁中,但现在我想将其拆分为更小的补丁(以及稍后的较小提交)。我怎么能这样做?
$ vim foobar.ext
Then I modify both functionA and functionB inside this file.
This might require changes in other files as well.
$ stg new large-patch
$ stg refresh
$ stg series
> large-patch
$ [insert here the answer to this question]
$ stg series
+ functionA-changes
> functionB-changes
$
答案 0 :(得分:6)
有几种方法可以做到这一点。您可以选择以较小的平安度打破补丁本身,或从底部或从顶部挑选部分补丁。
选项1:拆分补丁本身:
$ stg delete large-patch --spill
### for each patch i in 0..N-1:
$ stg new sub-patch-$i
$ git add -p .
$ stg refresh --index
选项2:从底部选择:
$ stg pop large-patch
### for each patch i in 0..N-1:
$ stg new sub-patch-$i
$ git checkout -p $(stg id large-path)
$ stg refresh
$ stg push large-patch
选项3:从顶部选择:
$ stg refresh
$ git reset HEAD~1 -p
$ stg refresh -i
$ stg new new-top-patch
$ stg refresh
这第三个选项(从顶部开始)非常方便,但它要复杂得多。您将反向选择更改。完成git reset后,索引中的更改将恢复修补程序中的更改,而工作树中的更改将恢复还原的更改,从而有效地创建包含这些更改的新修补程序。
答案 1 :(得分:2)
到目前为止我的解决方案:
$ stg pop
Popped large-patch
No patch applied
$ stg show large-patch | patch -p1
$ git add -p
Here I interactively select which portions are going to be staged.
$ stg new functionA-changes
$ stg refresh --index
$ stg new functionB-changes
$ stg refresh
$ stg push
Pushing patch "large-patch" ... done (empty)
Now at patch "large-patch"
$ stg delete large-patch
Deleted large-patch (empty)
Now at patch "functionB-changes"
还有另一种方法:
$ stg pop
Popped large-patch
No patch applied
$ stg show large-patch > foobar.patch
$ vim foobar.patch
Manually edit the patch
$ patch -p1 < foobar.patch
Now the files only have the changes from functionA.
$ stg new functionA-changes
$ stg refresh
$ stg rename large-patch functionB-changes
$ stg push
Pushing patch "functionB-chages" ... done
Now at patch "functionB-chages"
它有效,但仍然有点麻烦。我不知道是否有更好的解决方案。
答案 2 :(得分:2)
请记住只有一个命令可以使补丁重排安全:std push --set-tree
。它会推送下一个补丁,但会避免合并。相反,它会保留与修补程序关联的原始文件树。换句话说,即使编辑了各个补丁,也会保留补丁的叠加。
要拆分补丁,请使用stg pick --unapplied
复制原始补丁。编辑原始修补程序后,复制的修补程序将自动获取从原始修补程序中删除的更改。
整个过程看起来像这样。
# Make sure the patch to be split is on top
# Copy the current patch
stg pick --unapplied $(stg top)
# Make the first patch: remove hunks that go to the
# second patch, edit the description
stg edit --diff
# Some changes may be on the finer level than hunks, so let's
# do the fine tuning, test the patch, and make sure to run
# this after editing:
stg refresh
# Done with the first patch, now we go to the second patch,
# --set-tree does all the magic
stg push --set-tree
# All that's left is to edit the description of the second patch
stg edit --diff