[解決済み] Git Rebaseの衝突。誰がHEADなのか?
質問
私はこのプロジェクトを持っており、リモートリポにはメインの開発ブランチがあり、私は実験的なブランチを含むフォークを持っています。私は以下のことを要求されています。
rebase
は、フォークにプッシュする前に開発ブランチから実験ブランチに変更します。つまり、次のようになります。
git checkout experimentalbranch
git fetch remoterepo
git rebase remoterepo/developmentbranch
この頃になると、コンフリクトにぶつかる。しかし
私はこれらの変更についてよく知らないのですが
(私の変更をすぐにマージしてくれなかったので、数週間分の変更をリベースしているのです)。また、私は初めて
rebase
. 私はどちらかというと
merge
.
meldでは、通常、次のようになります。
<<LOCAL||REMOTE>>
に対して
merge
というのは、とても直感的な響きです。しかし
rebase
である。
<<HEAD||COMMIT MESSAGE>>
. 誰が
HEAD
? のことでしょうか?
HEAD
開発ブランチの?開発ブランチの最新コードなのか、それとも別の場所なのか?
解決方法は?
TL;DR(2018年5月追記)
Gitはその内部構造をあなたに見せるので、全体は基本的に少なくとも少しは混乱します。
ここで懸念しているケースは、実行時に発生することに注意してください。
git checkout somebranch; git rebase origin/their-branch
などがあります。 リベースはマージの競合を解決するために一時的に停止しています。
git add
を実行すると、コンフリクトが解消され
git rebase --continue
. (何らかのマージツールを使って
git mergetool
や派手なGUIインターフェースでは、そのインターフェースがこの一部または全部を他の方法でやってくれるかもしれませんが、その根底にあるのは
git add
を実行し、解決したファイルを
git rebase --continue
.)
一番最初に
HEAD
コミットは
その
ブランチを使用すると
git checkout --ours
または
git checkout --theirs
,
--ours
というのは
その
-の最終コミットです。
origin/their-branch
-一方
--theirs
というのは
あなたの
は、リベースの対象となる最初のコミットです。 これは、通常の日常的な Git の混乱です (
git における "ours" と "theirs" の正確な意味は何ですか?
)であり、本来の質問とは異なるものです。
しかし、その後
HEAD
のコミットは、実は
一種の混合物
. それは
自分のコミットを最新のコミットの上に何回かコピーした結果
. あなたは今、自分自身の一部が構築された
新しい
の一連のコミット、そして自分の
オリジナル
のコミットです。 この衝突の原因は
通常
何か "彼ら"がしたこと(の途中で変更された何か)。
origin/their-branch
). このコンフリクトを解決する必要があります。 解決したところで、後のコミットでまったく同じ衝突が繰り返されるかもしれません。
もう一度
HEAD
または
local
または
--ours
は
rebase があなたの変更と彼らの変更を組み合わせて作成したコミットです。
であり、もう一方のコミット(
remote
または
>>>>>>>
または
--theirs
) はあなた自身のコミットで、rebase はそのコミットを atop でコピーしようとしています。
HEAD
.
長い
マージ(内部的に "merging"を繰り返す特殊なケースであるリベースも含む)を行う場合、2つの "head"(特定の2つの枝先)が関与します。 これらを
your-branch
と
origin/their-branch
:
G - H -------- <-- HEAD=your-branch
/ \
... - E - F M <-- desired merge commit [requires manual merge]
\ /
I - J - K - L <-- origin/their-branch
この点は、一般的に(そして当然のことながら)混乱しやすいのですが、このようにラベル付けすると、十分に明確になります。
しかし、さらに悪いことに、git は
--ours
と
--theirs
は、マージ中のふたつの先頭コミットを指すものです。
H
を実行したとき
git merge
であり、quot;theirs" は、まあ、彼らのものである(コミット
L
). しかし、リベースを行うときは、2つの頭が逆になります。つまり、"ours" はあなたがリベースしている頭、つまり彼らの更新したコード、そして "theirs" はあなたが現在リベース中のコミット、つまりあなた自身のコードということになります。
これは、rebaseが実際には一連のチェリーピック操作を使用しているためです。 あなたはほとんど同じ絵から始めます。
G - H <-- HEAD=your-branch
/
... - E - F
\
I - J - K - L <-- origin/their-branch
ここでgitが行うべきことは
コピー
コミットの効果
G
と
H
は、すなわち
git cherry-pick
コミット
G
を実行した後、commit で再度実行します。
H
. しかし、そのためには、git は
スイッチ
をコミットする
L
まず、内部的に("detached HEAD"モードを使って)。
G - H <-- your-branch
/
... - E - F
\
I - J - K - L <-- HEAD, origin/their-branch
これで、コミットのツリーを比較することで、リベース操作を開始できるようになりました。
F
と
G
(何を変更したかを確認するため)、次に
F
対
L
(作品の一部がすでに
L
にない変更は
L
を追加します。 これは、内部的には "merge" 操作です。
G - H <-- your-branch
/
... - E - F G' <-- HEAD
\ /
I - J - K - L <-- origin/their-branch
マージがうまくいかなかった場合
HEAD
はコミット時にまだ残っています
L
(コミット
G'
はまだ存在しない)。 したがって、はい。
HEAD
は、その開発ブランチの先頭です。
をコピーしたら
G
が存在しますが。
HEAD
に移動します。
G'
からの変更をコピーしようとします。
H
は、同じように(diff
G
対
H
であれば、diff
F
対
G'
とし、その結果をマージする)。
G - H <-- your-branch
/
... - E - F G' - H' <-- HEAD
\ /
I - J - K - L <-- origin/their-branch
繰り返しになりますが、マージに失敗して助けが必要な場合、残されたのは
HEAD
を指しています。
G'
ではなく
H'
として
H'
はまだ存在しない。
マージがすべて成功し、コミットすると
G'
と
H'
する
が存在する場合、git はラベルを削除します。
your-branch
コミットから
H
をコミットすることを意味します。
H'
の代わりに
G - H
/
... - E - F G' - H' <-- HEAD=your-branch
\ /
I - J - K - L <-- origin/their-branch
で、リベースされ
HEAD
が再び期待通りになりました。 しかし、リベースの際に
HEAD
は、そのブランチチップ(コミット
L
) 、あるいは新しいコミットのひとつをコピーしてそのブランチチップの後ろに追加したもの、そして
--ours
の末尾にある成長中のブランチを意味します。
L
一方
--theirs
はコピー元のコミットを意味します (
G
または
H
上記)。
(これは基本的に、gitが生のメカニズムである いかに これはgitではよくあることです)。
関連
-
[解決済み] Git で直近のローカルコミットを取り消すには?
-
[解決済み] Gitブランチをローカルやリモートで削除するには?
-
[解決済み] git pull」と「git fetch」の違いは何ですか?
-
[解決済み] コミット前に 'git add' を取り消すにはどうすればよいですか?
-
[解決済み] リモートのGitブランチをチェックアウトするには?
-
[解決済み] 現在のGit作業ツリーからローカル(未追跡)ファイルを削除する方法
-
[解決済み] git rebase の取り消し
-
[解決済み] detached HEADとmaster/originの連携はどうすればいいですか?
-
[解決済み】"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 revert <hash> not allowed due to a merge but no -m option was given.
-
[解決済み】git rev-parseは何をするのですか?
-
git push reports an error ! [リモート拒否] master -> master (受信前のフックが拒否されました)
-
git commit リモートエラー [rejected] master -> master (フェッチファースト)
-
[解決済み] 複数のコミットをチェリーピックする方法
-
[解決済み] Git pull - マージする前に移動または削除してください。
-
[解決済み] "fatal: This operation must be run in work tree." というメッセージが表示されるのはなぜですか?
-
[解決済み] エラーです。リベースを使用してプルできません。あなたはステージングされていない変更を持っています
-
[解決済み] gitの「ours」「theirs」の正確な意味を教えてください。