![](/img/trans.png)
[英]When git rebasing two branches with some shared history, is there an easy way to have the common history remain common?
[英]How to make two git branches (with common history) coherent with each other after rebasing one of them?
我認為我的標題不夠清楚,所以我將描述問題:
在我的 git 項目中,我有 3 個分支: master
、 b1
和b2
。 這是歷史樹:
A---B---C master
\
D---E---F b1
\
G---H---I b2
假設我想重新設置b1
分支並編輯E
提交。 在 rebase 之后,提交E
和F
將被具有不同提交 SHA 的新提交E'
和F'
替換。 因此, b1
中的歷史將與b2
中的歷史不同:
A---B---C master
\
D---E'---F' b1
A---B---C---D---E---F---G---H---I b2
所以我的問題是:如何確保b2
在重新設置b1
之后遵循b1
(自動獲得與b1
相同的新提交),以便它們各自的歷史保持一致。
在你第一次變基之后,它不是這樣的:
A---B---C master
\
D---E'---F' b1
A---B---C---D---E---F---G---H---I b2
而是這個:
A---B---C master
\
D---Ea---F' b1
\
E---F---G---H---I b2
這里, Ea
表示修改后的E
提交。 如果我理解正確,你想要這個:
A---B---C master
\
D---Ea---F' b1
\
G'---H'---I' b2
您可以使用交互式變基來實現此目的:
git checkout b2
git rebase -i b1
在 rebase 編輯中,您注釋掉提交 E 的行:
# pick df8efe6 E
pick a7fcbed G
pick 936b51a H
pick c77ca69 I
# ...
# Commands:
# p, pick = use commit
# ...
# If you remove a line here THAT COMMIT WILL BE LOST.
回應您的評論,如果您想 go 從起始 position (ABCDEFGHI) 一直到所需的結束位置:
git checkout b2
git rebase -i master
在編輯器中:
pick 1234567 D
edit a7fcbed E
pick 936b51a F
pick c77ca69 G
pick 1e8d614 H
pick 8daafa7 I
# ...
# p, pick = use commit
# e, edit = use commit, but stop for amending
# ...
完成后,更正b1
分支:
git checkout b1
git reset --hard 936b51a
您還可以查看其他答案以獲取靈感。 我不確定你為什么要在一個命令中實現所有這些; 您仍然必須在過程中的某處修改提交 E。 它為您節省了一個交互式 rebase 來做到這一點。
如果您只有兩個分支,並且具有如圖所示的線性歷史記錄:
我會變基b2
而不是b1
:
A---B---C master
\
D---E'---F'
\
G'---H'---I' b2
然后更新b1
:
git branch -f b1 F'
@Han-KwangNienhuys 的答案是完全有效的,如果您需要在b1
已經被重寫時更新b2
,您可以應用它。
所以我的問題是:如何確保 b2 遵循 b1(自動獲得與 b1 相同的新提交)。
您還需要重寫 b2 的歷史記錄,您正在重新定位所有master..b2
提交並重新掛起b1
和b2
標簽。
交互式變基可讓您在每一步之后執行任意命令,特別是包括git branch
。 也一樣
git rebase -i master b2
在當前 b1 提交之后的選擇列表中說exec git branch -f b1
。
你可以自動化這個,pipe 選擇列表緩沖區通過
while read command commit rest; do case $command in
*) printf %s\\n "$command${commit:+ $commit${rest:+ $rest}}" ;;&
pick) git for-each-ref refs/heads --points-at $commit \
--format='exec git branch -f %(refname:short)' ;;
esac; done
它會在每次選擇分支提示后添加exec git branch -f
。 我剛剛構建並嘗試了這個。 調味,當然。
如果您要深入到分支歷史中,最好只構建您想要的確切的櫻桃挑選和分支序列; rebase 是一個方便的命令,旨在簡化常見任務。 像所有好的工具一樣,它可以比你想象的更進一步,但它有它的局限性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.