だから私の歴史は次のようになります:
o---o---o---o master \ o---o---o A \ o B
だから、説明する:
A
から始まったブランチmaster
がありますB
から開始したブランチA
(1つのコミットのみ)があります私が欲しいのはこれです:
o---o---o---o master \ o---o---o A \ o B
私がしたことは:
1)。
git checkout A git rebase master
これにより多くの競合が発生し、修正にかなりの時間を費やした後、次の履歴が浮上しました。
o---o---o---o master \ o---o---o A
まさに私が欲しかったものです。
(B
が今どこにあるのかわかりません)
2)。
この後、私はたくさんの押しつぶしを行い、A
のコミットの順序を変更して、履歴を希望どおりに見せました。
3)。
さて、私もやりたいことは:
git checkout B git rebase A
しかし、これは機能していないようで、理由はわかりません。 git log
を実行すると、手順1を実行する前にあったコミットが表示されます。
また、ステップ1ですでに解決したのと同じ膨大な数の競合が発生します。私はそれを実行するのにかなりの時間を費やしました。もう一度実行したくありません。
この例--onto
の使用を提案しました。
git checkout B git rebase --onto A
しかし、これによりB
のコミットが完全に削除され、A
とB
が同じコミット、つまりA
の最後のコミットを指すようになります。
私の質問は:BがAから始まったように見えるように、AからBを効果的にリベースするにはどうすればよいですか? (これは実際には最初は真実でした)。
私の推測では、--onto
を間違って使用しています。または、他の何かを使用する必要があること(cherry-pick
など)。
短い回答BがAから始まったように見えるように、AからBを効果的にリベースするにはどうすればよいですか? 移動したい場合1つだけcommit:
git rebase --onto A B~ B
移動したい場合は1つコミットを使用します。
git rebase --onto A old_A B
答えの残り。
Bのブランチはまだ存在しています(チェックアウトできます)が、その親はA
が以前にあった正確なコミットオブジェクトです。
これをグラフィカルに表示するには、以下を使用します。
git log --graph --decorate --all
すべてのブランチと、それらが互いに対してどこにあるかを確認します。
最初に持っていたもの:
o---o---o---o master
\
o---o---o A
\
o B
あなたが今持っているもの:
o---o---o-----------o master
\ \
o---o---o(B~) o---o---o A
\
o B
--onto
を使用するには、開始点と終了点が必要です。使用する:
git rebase --onto [target] [rebasing stops] [rebasing head]
git rebase --onto A B~ B
そしてあなたが得るもの:
o---o---o----------o master
\ \
o---o---o o---o---o A
(old_A) \
o B
[branch_name]~
は、ブランチの親コミットを示します。
B~
は、変更したくないブランチです。 (たまたま古いA
)
または、BがAを親として持つ唯一のコミットである場合(つまり、Bはマスターから分岐するコミットのチェーンの終わりです)
git checkout B
git rebase master
git checkout B~ # this is the commit before B (the A commit)
git branch -d A # remove the old A branch (it was rebased, and so is now invalid
git branch A # recreate the A branch on the commit that is based on the original A
私のgitフローにも同じ問題があり、それを行うための最善かつ迅速な方法を見つけました。
(1)最初のプロジェクト履歴:
master ---A---B---C
\
D---E---F feature1
\
G---H feature2
(2)feature1をマスターにリベースし、強制的にプッシュします。
master ---A---B------------------------C
\ \
D---E---F feature1(old) D---E---F feature1
\
G---H feature2
(3)feature2をfeatrue1(新しいもの)にリベースします
master ---A---B------------------------C
\
D---E---F feature1
\
G---H feature2
最も混乱している部分は、どのように行うかです(3)..しかし、誰もそれを行う明確な答えはありません。
多くの人が私と同じ問題に遭遇したと思います。「rebase --onto」を実行しようとしたときに、feature1(old)が見つかりました実際には存在しません!
git rebase --onto feature1 feature1(old) feature2
解決策は、代わりに以下を使用することです:
git rebase --onto feature1 feature1@{1} feature2
構文feature1 @ {1}は「リベース前のfeature1の最後の既知の状態」を意味し、回答は から参照されます-ギット
すでにAをリベースしている場合。Bがそのままになっているはずです。 Aであったブランチ(ポインタ)は、新しい場所に移動しただけです。
あなたが提案したように、BをAに効果的にリベースするために私が推奨するのは、「チェリーピック」を使用することです。このコマンドは、コミットで行われた変更を、それを実行するブランチに適用しようとします。
したがって、Bが最初にポイントしたコミットのコミットIDが「123456」である場合、現在の「B」をgit branch -f B A
を使用して新しい「A」と同じ場所に移動し、git cherry-pick 123456
を実行することをお勧めします変更をAに適用します。
--onto
フラグは、コミットを適用するターゲットの場所を設定するために使用されていると思います。デフォルトは "upstream"です(ソース: http://git-scm.com/docs/git- rebase )。
Rebaseコマンドの考え方は次のとおりです。
git rebase --onto <Starting here> <Apply all commits from HERE> <TO HERE>
これを使用すると、Bをマスターにリベースしてから、AをBの前のコミットにポイントする方がおそらく簡単でした。
git rebase master B
(開始点(--onto)は暗黙的に「マスター」であるため)
次に、git branch -f A B^
を使用します(^は「の親」を意味します)