リベース後に分岐したGitブランチ


112

すでにプッシュされたブランチをローカルでリベースしました。

Gitは、私のブランチとリモートが分岐し、次のことをアドバイスしています。

「それぞれ109と73の異なるコミットがあります」

私のブランチをプッシュすることでこれは解決されます-つまり、これはリベース後に予期されることですか?


同じ問題があります。「正しい方法」とは、ローカルブランチをリベースしてプッシュすることだと言えるでしょうか。
Mher Didaryan

回答:


154

ブランチをリベースするとき、リベースしているブランチのコミットより上のコミットのコミットを書き直す必要があります。これは、コミットのプロパティの1つがその親(複数可)であるためです。リベースすると、ブランチ上の最も古いローカルコミットの親が変更されます。つまり、ローカルコミットのすべてのコミットハッシュが変更されます。これは、変更がコミットを通じて推移的に増加するためです。

すでにブランチをプッシュしているので、ベースをリベースするのではなく、ソースブランチにマージする必要があります。(-fフラグを使用して)新しいブランチを「強制的にプッシュ」することは可能ですが、ブランチの履歴の整合性が損なわれるため、通常のプッシュは機能しません。このブランチで他のユーザーと共同作業している場合、強制プッシュはお勧めできません。他の共同作業者の履歴が突然一致しなくなると、他の共同作業者は非常に混乱するからです。

TL; DR-コラボレーションしていない場合は、push -fを使用してブランチをプッシュします。もしそうなら、代わりにブランチを以前の状態にリセットし、代わりにソースブランチにマージします。


1
「すでにブランチをプッシュしているので、ソースブランチにマージする必要がありました」-なぜですか?
hammett 2014年

1
@HamiltonVerissimo Jasonの最初の文:「ブランチをリベースするときは、リベースしているブランチのコミットの上にあるコミットのコミットを書き直す必要があります。」「上記」のコミットでキャプチャされた変更は同じ論理コンテンツを持っていますが、それらは異なるベースに適用されているため、異なるハッシュの異なるコミットです。他の開発者がリベース前のブランチから作業している場合、git push -fを実行すると、ワークフローが非常に混乱します。したがって、このブランチは公開ソースにプッシュされているため、マージする必要がありました。
awolf

4
他の誰かがすでに何かを押したかどうかわからない場合は、push --force-with-leaseを使用することもできます。
コンソール

1
@ jason-lebrun警告なしに自分の作業を上書きできる上流の変更をマージすることの欠点はありませんか?マージの競合は、リベース時と同じ方法で検出されますか?たとえば、不要になったためにセクションをブランチ内のファイルから削除したが、他の誰かが上流の同じセクションに些細な変更を加えた場合、空白やグローバルな検索/置換アクションの削除など、それを私の枝の上にマージして、私の削除を簡単に変更されたバージョンに置き換えますか?
Chris Bloom

1
他のブランチをあなたのブランチにマージすることは悪い考えではありませんか?たとえば、マスターを機能ブランチにマージする-それはそのための新しいコミットを作成しませんか?後でマスターにマージする場合、この機能ブランチで一度追加のコミットが発生しませんか?
ロス

55

すべてのコミットでIDが変更されたため、宛先変更は本当に分岐点ではありません。

問題を解決するには、リモートブランチを上書きする必要があります。

git push -f origin experiment

http://git-scm.com/book/ch3-6.html

説明:

この画像では、C3がリベース後にC3としてではなく、C3 'として配置されている方法を確認してください。これは正確にC3ではないためですが、コードがすべて変更されています。

リベース

この別の画像では、リモートが関与しているときにリベースがどのように見えるか、そして迂回が存在する理由の図を取得します。

分岐してgit push

いずれの場合でも、強制プッシュを実行した後、(強制更新)を実行したことが通知されますが、その時点で問題ありません。

上部のリンクをチェックアウトして、「git push --force」を検索してください。より詳細な説明が表示されます。


3
うん。これで問題は解決したと思います。ただし、チームで作業しているときに、他のユーザーによってプッシュされた最近の作業がプッシュによって上書きされる可能性がある場合、強制プッシュは機能しない可能性があります。私は正しいですか?
Hari Krishna Ganji 2014年

望ましい効果が得られない可能性があります。リベースを行う前に、変更を「早送り」でマージしてください。
ミモレラ2014年

1

私は以下を実行することにより、プッシュのためのリベース分岐で成功しました:

git checkout mybranch
git pull
git push origin mybranch

プルは発散を解決しました。

引っ張る前に

Your branch and 'origin/mybranch' have diverged,
and have 2 and 1 different commit(s) each, respectively.

プル出力

再帰的なマージ。mypath / myfile.py | 12 +++++++++++-1ファイルが変更され、11挿入(+)、1削除(-)

プル後

あなたのブランチは、3つのコミットで 'origin / mybranch'よりも進んでいます。

プッシュ後

mybranchはブランチの3つ前にありますが、オープンプルリクエストのマージメッセージがコミット履歴に追加されています。リモートのmybranchをmybranchにマージします。

これはおそらくフォースプッシュが行うことであると想定していますが、検証していません。

他の人が言ったように、すでにオープンプルリクエストがある場合はリベースを避けてください。私はこの例を私のために働いたものとして提供しています。


1

これは、ターゲットブランチを現在のローカルブランチにリベースし、ターゲットブランチに切り替えてから、ローカルブランチをターゲットにリベースすることにより、強制プッシュなしで修正できます。欠落している可能性があるコミットが追加され、作成する必要がないため、これは分岐しません。簡単な説明の例:

  1. 本店は開発中
  2. あなたは新しいブランチ機能/ doing_stuffをチェックアウトします
  3. チームメンバーが新しいコミットを推進して開発する

開発ブランチを更新していない場合、「git checkout develop」&&「git rebase feature / doing_stuff」は、チェックアウト以降にコミットが追加されていないため、正しく機能します。ただし、開発をチェックアウトして新しいコミットをプルダウンした場合、新しいコミットが表示されているためにリベースしようとすると、この相違がわかります。強制的にプッシュしない簡単な修正(通常、チーム環境ではお勧めしません)は次のとおりです。

  1. git checkout feature / doing_stuff
  2. git rebase 開発
  3. git checkout 開発
  4. git rebase feature / doing_stuff

ステップ2からのリベースにより、不足しているコミットがfeature / doing_stuffに取り込まれるため、ステップ4が実行されたときは最新であり、変更のために新しいコミットを作成する必要はありません。

私はこれに遭遇し、強制せずに開発を成功させるために上記の手順を実行したため、これは私が機能することがわかっているソリューションです。私は50人を超える開発者のチームで働いているため、自分のテスト用ブランチ以外のものを強制的にプッシュすることは禁止されているため、解決策を見つける必要がありました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.