簡體   English   中英

將提交從一個分支移動到另一個分支,然后將它們合並回來

[英]Move commits from one branch to another and then merge them back in

我有一棵樹:

       /--b1---b2 <-- topic b
      /    
a1---a2 <-- topic a

其中'b'取決於'a'。 然后我意識到我需要做一些與主題'a'相關的更改以繼續'b',但我想在'b'上做它們作為'b'的正常開發過程:

       /--b1---b2---a3---a4---b3---b4---a5---b5 <-- topic b
      /    
a1---a2 <-- topic a

然后,當我想在'b'上完成的事情完成時,我希望我的樹看起來像這樣:

       /--b1---b2--------m---b3'---b4'---b5' <-- topic b
      /                 /
a1---a2---a3'---a4'---a5' <-- topic a

好像我實際上對'a'進行了所有更改,然后將它們合並在'b'上,然后繼續'b'。

我知道我可以手動執行此操作:

1- rebase / cherry-pick'a'從分支'b'提交到'a'
2-在'b'上創建一個時間分支'b-tmp'。
3-將分支'b'重置為'b2'。
4-將'a'合並到'b'上。
5- rebase / cherry-pick'b'從'b-tmp'提交到'b'。
6-刪除分支'b-tmp'。

我可以創建一些腳本來執行此操作,我只想知道是否有更好的方法/想法來執行此操作,除了這6個步驟。

讓我先說我寧願經常整合主題分支(早期整合,經常構建......敲響鍾聲?)。 所以,事實上,當有應該去到最終的變化,我會回去,做一個的變化,變基B關於頂部。

如果需要其他一些目的是穩定的,我會成為一個一個換乙支路包含的工作暫時和變基B關於最重要的是。

如果你真的必須使用分支' b '內的'topic- a '變化,那就是我要做的。

注意: 包括截屏視頻


到達起點

這是一個簡單的工作樹,其中包含以下問題的布局:

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 

在這里截屏


將提交重新組織到其主題分支上

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

再次, 請參閱截屏視頻


檢查結果

我們現在可以進行前/后樹比較:

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

筆記

我故意選擇對演示進行非沖突的更改。 當然,在現實生活中,你會遇到合並沖突。 使用git mergetoolgit rebase --continue

如果您的更改是衛生的並且確實屬於各自的主題分支,那么沖突可能很少並且很容易解決。 否則,是時候修改你的分支方案了 (參見Martin Fowler ea)

討論

回應

你還說“當最終會有'a'的變化時,我會回去,對'a'進行更改,然后在'a'之上'b''。 我也不確定我是否理解這一點。 你能解釋一下嗎?

我的意思是,我會盡量讓A3,A4,A5的一個分支版本,無論如何,和變基b到這一點,所以

  • 進行合並的人是進行提交的同一個人
  • 你連續進行提交和合並(這意味着你不會因為短期內存丟失而搞亂) <-- this is the Merge Early/Soon/Frequently mantra
  • 你避免不必要的合並沖突
  • 你不必在以后“回到過去”並重寫原始提交:a3,a4,a5將被合並,而不是被復制(參見Git Cherry-pick vs Merge Workflow

這是“走向起點”,但適應了我理想化的工作流程。 請注意,這個替代結果的最終結果已經完全是您在上面的“重組提交到他們的主題分支”下顯示的所有雜耍之后結束的!

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

請注意 ,實際上回到a分支提交a3 / a4 / a5提交並不困難:

  • 如果您只是意識到觸摸了屬於該分支的內容,您可以切換具有待定本地更改 分支2
  • 你再選擇 (!!)第一階段是需要去到一個分支部分( git add -i或Git的圖形用戶界面相似或如vim fugitive
  • 提交
  • 切換回b分支( git checkout b
  • 提交其余的位
  • 變基b最新修訂版

2只要它們不與a..b的其他變化發生沖突; 在這種情況下你git stash第一和git stash apply一個分支時

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM