[英]Move commits from one branch to another and then merge them back in
I have a tree: 我有一棵树:
/--b1---b2 <-- topic b
/
a1---a2 <-- topic a
where 'b' depends on 'a'. 其中'b'取决于'a'。 Then I realize I need to do some changes related to topic 'a' in order to continue with 'b', but i'd like to do them on 'b' as a normal development course of 'b':
然后我意识到我需要做一些与主题'a'相关的更改以继续'b',但我想在'b'上做它们作为'b'的正常开发过程:
/--b1---b2---a3---a4---b3---b4---a5---b5 <-- topic b
/
a1---a2 <-- topic a
Then, when the thing I want to accomplish on 'b' is done, I'd like my tree to look like this: 然后,当我想在'b'上完成的事情完成时,我希望我的树看起来像这样:
/--b1---b2--------m---b3'---b4'---b5' <-- topic b
/ /
a1---a2---a3'---a4'---a5' <-- topic a
as if I actually did all the changes on 'a', then merged them on 'b' and then continued on 'b'. 好像我实际上对'a'进行了所有更改,然后将它们合并在'b'上,然后继续'b'。
I know I can do this manually doing: 我知道我可以手动执行此操作:
1- rebase/cherry-pick 'a' commits from branch 'b' to 'a' 1- rebase / cherry-pick'a'从分支'b'提交到'a'
2- create a temporal branch 'b-tmp' on 'b'. 2-在'b'上创建一个时间分支'b-tmp'。
3- reset branch 'b' to 'b2'. 3-将分支'b'重置为'b2'。
4- merge 'a' onto 'b'. 4-将'a'合并到'b'上。
5- rebase/cherry-pick 'b' commits from 'b-tmp' onto 'b'. 5- rebase / cherry-pick'b'从'b-tmp'提交到'b'。
6- delete branch 'b-tmp'. 6-删除分支'b-tmp'。
I can create some script to do this, I'd just like to know if there are better ways/ideas to do this, other than this 6 steps. 我可以创建一些脚本来执行此操作,我只想知道是否有更好的方法/想法来执行此操作,除了这6个步骤。
Let me start out with saying that I'd rather integrate the topic branches often (Integrate Early, Build Often ... rings a bell?). 让我先说我宁愿经常整合主题分支(早期整合,经常构建......敲响钟声?)。 So in fact, when there are changes that should go onto a eventually, I'd go back, do the changes on a , and rebase b on top of a .
所以,事实上,当有应该去到最终的变化,我会回去,做一个的变化,变基B关于的顶部。
If a needs to be stable for some other purpose, I'd make a a-for-b branch to contain the work temporarily, and rebase b on top of that. 如果需要其他一些目的是稳定的,我会成为一个一个换乙支路包含的工作暂时和变基B关于最重要的是。
If you really must work with 'topic- a ' changes inside branch ' b ', Here's what i'd do. 如果你真的必须使用分支' b '内的'topic- a '变化,那就是我要做的。
Note: screencasts included 注意: 包括截屏视频
This is a simple working tree with the layout from the question: 这是一个简单的工作树,其中包含以下问题的布局:
mkdir /tmp/q
cd /tmp/q
git init .
touch f
git add f
git commit -am initial
git checkout -b a; for a in a{1,2}; do echo $a>$a; git add $a; git commit -am $a; git tag $a; done
git checkout -b b; for a in b{1,2} a{3,4} b{3,4} a5 b5; do echo $a>$a; git add $a; git commit -am $a; git tag $a; done
git show-branch
See screencast here 在这里看截屏
git checkout -b a_new a # for safety, work on a clone of branch a
git reset --hard b # start by moving it to the end of the b branch
git status # (just show where we are)
git log --oneline
git rebase -i a # rebase it on top of the original branch a
# not shown: delete every line with non-branch-a commits (b1-b5)
# see screencast
git log --oneline # (just show where we are again)
git checkout -b b_new b # for safety, work on a clone of branch b
git log --oneline # (just show where we are again: the end of branch b)
git rebase -i a_new # this time, rebase it on top of the new branch a_new
git log --oneline # (check results)
git show-branch b_new a_new
Again, see screencast 再次, 请参阅截屏视频
We can now do a before/after tree comparison: 我们现在可以进行前/后树比较:
sehe@natty:/tmp/q$ git show-branch a b
! [a] a2
! [b] b5
--
+ [b] b5
+ [b^] a5
+ [b~2] b4
+ [b~3] b3
+ [b~4] a4
+ [b~5] a3
+ [b~6] b2
+ [b~7] b1
++ [a] a2
sehe@natty:/tmp/q$ git show-branch a_new b_new
! [a_new] a5
* [b_new] b5
--
* [b_new] b5
* [b_new^] b4
* [b_new~2] b3
* [b_new~3] b2
* [b_new~4] b1
+* [a_new] a5
for name in a b;
do
git branch -m $name ${name}_old &&
git branch -m ${name}_new $name
done
git branch -D a_old b_old # when sure
I have deliberately chosen to make non-conflicting changes for the demo. 我故意选择对演示进行非冲突的更改。 Of course in real life you'll get merge conflicts.
当然,在现实生活中,你会遇到合并冲突。 Use
git mergetool
and git rebase --continue
. 使用
git mergetool
和git rebase --continue
。
If your changes are hygienic and really belong on their respective topic branches, chances are that conflicts should be few and easily resolved. 如果您的更改是卫生的并且确实属于各自的主题分支,那么冲突可能很少并且很容易解决。 Otherwise, it is time to revise your branching scheme (see Martin Fowler ea)
否则,是时候修改你的分支方案了 (参见Martin Fowler ea)
In response to 回应
You also say that "when there are changes that should go onto 'a' eventually, I'd go back, do the changes on 'a', and rebase 'b' on top of 'a'".
你还说“当最终会有'a'的变化时,我会回去,对'a'进行更改,然后在'a'之上'b''。 I'm not sure I understand this also.
我也不确定我是否理解这一点。 Could you explain?
你能解释一下吗?
I mean that I would try to make the a3,a4,a5 revisions on the a branch anyway, and rebase b onto that, so 我的意思是,我会尽量让A3,A4,A5的一个分支版本,无论如何,和变基b到这一点,所以
<-- this is the
Merge Early/Soon/Frequently
mantra
<-- this is the
Merge Early/Soon/Frequently
mantra
Here is the 'Getting to the starting' point, but adapted to my idealized workflow. 这是“走向起点”,但适应了我理想化的工作流程。 Note that the end-result of this alternative result is already exactly what you end up after all the juggling shown under 'Reorganizing commits onto their topic branches' above!
请注意,这个替代结果的最终结果已经完全是您在上面的“重组提交到他们的主题分支”下显示的所有杂耍之后结束的!
mkdir /tmp/q
cd /tmp/q
git init .
touch f
git add f
git commit -am initial
git checkout -b a; # no change
echo a1>a1; git add a1; git commit -am a1
echo a2>a2; git add a2; git commit -am a2
git checkout -b b; # start off the a branch
echo b1>b1; git add b1; git commit -am b1
echo b2>b2; git add b2; git commit -am b2
git checkout a # go back to the a branch for a3 and a4
echo a3>a3; git add a3; git commit -am a3
echo a4>a4; git add a4; git commit -am a4
git checkout b
git rebase a # here is the magic: rebase early
echo b3>b3; git add b3; git commit -am b3
echo b4>b4; git add b4; git commit -am b4
git checkout a # go back to the a branch for a5
echo a5>a5; git add a5; git commit -am a5
git checkout b
git rebase a # again: rebase early
echo b5>b5; git add b5; git commit -am b5
git show-branch
Note that it is in practice not hard to go back to the a branch to commit your a3/a4/a5 commits: 请注意 ,实际上回到a分支提交a3 / a4 / a5提交并不困难:
git add -i
or similar in git guis or eg vim fugitive
) git add -i
或Git的图形用户界面相似或如vim fugitive
) git checkout b
) git checkout b
) 2 as long as they don't conflict with other changes from a..b ; 2只要它们不与a..b的其他变化发生冲突; in that case you'd
git stash
first and git stash apply
when on the a branch 在这种情况下你
git stash
第一和git stash apply
的一个分支时
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.