[解決済み] Git リベースされたブランチをプルする
質問
私の状況を説明させてください。
ブロンドさんとオレンジさんは、コミット M1 で master ブランチから分岐したブランチ A で作業しています。ブランチ A には 2 つのコミットがあります。A1 と A2 です。
M1
\
\
A1 - A2
一方、Orange 氏は master ブランチにさらに 2 つのコミット、M2 と M3 をコミットしてプッシュしました。
M1 - M2 - M3
\
\
A1 - A2
ブロンド氏はリモートからプルし、しばらくしてから master ブランチにリベースすることにしました。
M1 - M2 - M3
\ \
\ \
A1 - A2 A1` - A2`
A1` と A2` はリベースされたコミットで、ブロンドさんのローカルに存在し、A1 と A2 はリモートに存在します。ブロンドさんは自分のコミットをプッシュします。 -f を使って変更を強制し、履歴を書き換えます。これで、リモートリポジトリは以下のようになります。
M1 - M2 - M3
\
\
A1` - A2`
しかし、オレンジ氏は A ブランチでも作業をしていました。彼のローカルリポジトリはまだこのような状態です。
M1 - M2 - M3
\
\
A1 - A2
オレンジさんがリモートリポジトリのAブランチと同期するために必要なことは何ですか?
通常のpullではうまくいきません。ウィル プル -f はリモートからの変更をローカルに強制するのでしょうか?Aのローカルバージョンを削除し、リモートリポジトリから再び持ってくることでトリックを行うことを知っていますが、それはそれを達成するための良い方法ではないように思えます。
どのように解決すればよいでしょうか。
私のお勧めは(私がオレンジさんだったらどうするか、ですが)、次のように始めることです。
git fetch
. これはブロンド氏がリベース後に "git push -f" を実行する直前まで持っていたものです。
M1 - M2 - M3
\ \
\ \
A1 - A2 A1' - A2'
一つ重要な違いは、自分のローカルラベルを
A
が rev A2 を指していることと、リモートラベル
remotes/origin/A
が A2' を指しています (ブロンド氏はその逆で、ローカルラベル
A
がA2'を指していて
remotes/origin/A
はA2を指している)。
もし私が "A" という名前のブランチのコピーで作業していた場合、代わりにこのようになります。
M1 ---- M2 ---- M3
\ \
\ \
A1 - A2 - A3 A1' - A2'
(私のローカルラベルは、A2 ではなく A3 を指しています。) 今私がしなければならないことは、A3 (と必要なら A4 など) を A2' にリベースすることです。 1 つの明白な直接の方法です。
$ git branch -a
master
* A
remotes/origin/master
remotes/origin/A
$ git branch new_A remotes/origin/A
$ git rebase -i new_A
を実行し、修正されたものが new_A に A1' と A2' として入っているので、rev A1 と A2 を完全に削除します。 あるいは
$ git checkout -b new_A remotes/origin/A
$ git format-patch -k --stdout A3..A | git am -3 -k
(この
git am -3 -k
メソッドに記述されています。
git-format-patch
のマニュアルページで説明されています)。
これらは、ブロンド氏が自分の
rebase
つまり、A1, A2, A3, などを特定する必要があります。
2番目のアプローチが成功した場合、私は以下のように終わります。
M1 ---- M2 ---- M3
\ \
\ \
A1 - A2 - A3 A1' - A2' - A3'
私のブランチ名
new_A
は A3' を指します (私の既存の
A
ブランチはまだ古い A3 を指しています)。 最初の方法で成功しても、結局は同じことなのですが、既存のブランチ名
A
は A3' を指すようになります (そして、A1-A2-A3 の古いブランチの名前は、私のレポに残っているにもかかわらず、ありません; それを見つけるには reflogs または同様のものを通過する必要があります)。
(私の A3 が A3' になるように修正する必要がある場合、対話型リベースと "git am" の両方の方法が、もちろん私による作業を必要とします)。
もちろん、単に
git merge
(を使用することもできますが、その場合マージコミット ("M" 番号なし、以下同様) が作成され、rev A1 と A2 は表示したままになります。
M1 ---- M2 ---- M3
\ \
\ \
A1 - A2 - A3 A1' - A2' -- M
\_______________/
もしあなたが元のA1とA2を保存したいのであれば、これは良いことで、もしあなたがそれらを取り除きたいのであれば、それは悪いことです。 つまり、"何をすべきか"は、"結果をどうしたいのか"によります。
編集から追加: format-patch 方式は、すべてがうまくいくことを確認する間、古い A ブランチ名を残しておけるので、より気に入っています。 すべてがうまくいっていると仮定して は が良好であると仮定して、最後の数ステップを説明します。
$ git branch -m A old_A
$ git branch -m new_A A
で、old_Aを完全に捨てられるかどうか。
$ git branch -D old_A
または、同等に、ブランチ削除から始めて、new_A を A にリネームします。
(編集: 以下も参照してください。
git rebase --onto
ドキュメントを参照してください。)
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] リモート Git リポジトリの URI (URL) を変更するには?
-
[解決済み] 新しいローカルブランチをリモートの Git リポジトリにプッシュし、それを追跡するにはどうすればよいのでしょうか?
-
[解決済み] まだプッシュされていない Git マージを元に戻す
-
[解決済み] git rebase の取り消し
-
[解決済み] Git のリモートブランチを作成する方法を教えてください。
-
[解決済み】"git pull" でローカルファイルを強制的に上書きするには?
-
[解決済み】ローカルのGitブランチの名前を変更するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
エラーが発生しました。マージされていないファイルがあるため、プリングはできません
-
Git はファイル名の大文字と小文字を無視し、修正する
-
ファイル名が長すぎるため、作業ツリーをチェックアウトできない警告が表示されました。クローンには成功しましたが、チェックアウトに失敗しました。
-
[解決済み] Jenkins Pipeline Git SCM を認証情報でチェックアウトする?
-
[解決済み] 単一のgitコミットに対して設定されたユーザーを上書きする
-
[解決済み] なぜGitでコミットする前にステージが必要なのですか?
-
[解決済み] Git: リモートブランチの情報を更新する
-
[解決済み] GitHub: フォークを "自分のプロジェクト "にする
-
[解決済み] VSCodeからgitの統合を削除する
-
[解決済み] Git Repo から既存のファイルを削除する