簡體   English   中英

如何使兩個 git 分支(具有共同歷史)在其中一個變基后彼此一致?

[英]How to make two git branches (with common history) coherent with each other after rebasing one of them?

我認為我的標題不夠清楚,所以我將描述問題:

在我的 git 項目中,我有 3 個分支: masterb1b2 這是歷史樹:

 A---B---C  master
          \
           D---E---F  b1
                    \
                     G---H---I  b2

假設我想重新設置b1分支並編輯E提交。 在 rebase 之后,提交EF將被具有不同提交 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提交並重新掛起b1b2標簽。

交互式變基可讓您在每一步之后執行任意命令,特別是包括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.

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