Git rebaseを実行するとき、競合を解決するときに「ローカル」と「リモート」で何が起こっているのかを理解するのが難しいことがよくあります。私は時々、あるコミットから次のコミットにサイドを交換するという印象を持っています。
私はまだ適切に理解していないため、これはおそらく(間違いなく)です。
リベースする場合、誰が「ローカル」で誰が「リモート」ですか?
(競合を解決するためにP4Mergeを使用しています)
要約すると(As Benubirdcomments )、次の場合:
git checkout A
git rebase B # rebase A on top of B
local
はB
(rebaseonto)、remote
はA
ですそして:
git checkout A
git merge B # merge B into A
local
はA
(mergeinto)、remote
はB
ですリベースは、ours
(リベースを開始する前の現在のブランチ)とtheirs
(リベースする最上位のブランチ)を切り替えます。
kutschkem が指摘しているのは、GUI mergetoolコンテキストで:
ours
"(上流ブランチ)theirs
"-リベース前の現在のブランチ。この回答の最後の部分の図を参照してください。
混乱は リベース中のours
とtheirs
の反転 に関連している可能性があります。
(関連抽出)
リベースマージは、
<upstream>
ブランチの上にある作業ブランチから各コミットを再生することで機能することに注意してください。
このため、マージの競合が発生した場合:
ours
」として報告される側は、<upstream>
で始まるこれまでのリベースシリーズです。theirs
'は作業ブランチです。つまり、側面が交換されます。x--x--x--x--x(*) <- current branch B ('*'=HEAD)
\
\
\--y--y--y <- other branch to merge
、現在のブランチ「B」は変更しません。したがって、まだ作業しているものが残っています(そして別のブランチからマージします)
x--x--x--x--x---------o(*) MERGE, still on branch B
\ ^ /
\ ours /
\ /
--y--y--y--/
^
their
しかし、リベースでは、リベースが最初に行うことは上流ブランチをチェックアウトすることなので、サイドを切り替えます! (その上で現在のコミットを再生するため)
x--x--x--x--x(*) <- current branch B
\
\
\--y--y--y <- upstream branch
A git rebase upstream
will first change HEAD
of B to the upstream branch HEAD
(hence the switch of 'ours' and 'theirs' compared to the previous "current" working branch.)
x--x--x--x--x <- former "current" branch, new "theirs"
\
\
\--y--y--y(*) <- upstream branch with B reset on it,
new "ours", to replay x's on it
、そしてリベースは新しい「私たちの」Bブランチで「彼らの」コミットを再生します:
x--x..x..x..x <- old "theirs" commits, now "ghosts", available through reflogs
\
\
\--y--y--y--x'--x'--x'(*) <- branch B with HEAD updated ("ours")
^
|
upstream branch
注: "upstream"の概念 は、データの参照セット(すべてのレポまたはここのようなブランチlocalブランチ)読み取るか、新しいデータが追加/作成されます。
local
」と「remote
」対「mine
」と「theirs
」私にとっては、「ローカル」で誰が「リモート」であるかという疑問が残っています(gitでリベースするときに「私たち」と「彼ら」という用語は使用されないため、それらを参照すると答えが混乱するようです) 。
kutschkem が追加されます。
競合を解決するとき、gitは次のように言います。
local: modified file and remote: modified file.
この時点での質問はローカルとリモートの定義を目的としていると確信しています。その時点で、私の経験から次のように思えます。
ours
"(上流ブランチ)theirs
"-リベース前の現在のブランチ。git mergetool
は実際に「ローカル」と「リモート」に言及しています:
Merging:
f.txt
Normal merge conflict for 'f.txt':
{local}: modified file
{remote}: modified file
Hit return to start merge resolution tool (kdiff3):
たとえば、 KDiff は マージ解像度をそのように表示します :
Git mergetool -t gvimdiffでVimdiffをmergetoolとして呼び出します。 Gitの最新バージョンは、次のウィンドウレイアウトでVimdiffを呼び出します。
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
LOCAL
:
現在のブランチ上のファイルの内容を含む一時ファイル。BASE
:
マージの共通ベースを含む一時ファイル。REMOTE
:
マージするファイルの内容を含む一時ファイル。MERGED
:
競合マーカーを含むファイル。Gitはできるだけ多くの自動競合解決を実行しました。このファイルの状態は、
LOCAL
とREMOTE
の両方の組み合わせで、Git自身が解決できなかったものを囲む競合マーカーがあります。mergetool
は、解決の結果をこのファイルに書き込む必要があります。
一番下の行
git rebase
git merge
つまり、[〜#〜] local [〜#〜]は常にオリジナルであり、[〜#〜] remote [〜#〜]は常にガイですコミットがトップにマージまたはリベースされているため、以前にコミットがなかった
証明してください!
確かに。私の言葉を信じないでください!以下は、自分で確認できる簡単な実験です。
まず、git mergetoolが適切に構成されていることを確認してください。 (そうしなければ、おそらくこの質問を読んでいないでしょう。)次に、作業するディレクトリを見つけます。
リポジトリをセットアップします。
md LocalRemoteTest
cd LocalRemoteTest
最初のコミットを作成します(空のファイルを使用):
git init
notepad file.txt (use the text editor of your choice)
(save the file as an empty file)
git add -A
git commit -m "Initial commit."
マスターではないブランチでコミットを作成します。
git checkout -b notmaster
notepad file.txt
(add the text: notmaster)
(save and exit)
git commit -a -m "Add notmaster text."
Masterブランチでコミットを作成します。
git checkout master
notepad file.txt
(add the text: master)
(save and exit)
git commit -a -m "Add master text."
gitk --all
この時点で、リポジトリは次のようになります。
リベーステストの場合:
git checkout notmaster
git rebase master
(you'll get a conflict message)
git mergetool
LOCAL: master
REMOTE: notmaster
マージテスト。変更を保存せずにmergetoolを閉じてから、リベースをキャンセルします。
git rebase --abort
次に:
git checkout master
git merge notmaster
git mergetool
LOCAL: master
REMOTE: notmaster
git reset --hard (cancels the merge)
結果は、上部に表示されるものと同じである必要があります。
私はあなたの問題を正確に把握できませんでしたが、次の図はあなたの問題を解決すると思います。 (リベース:リモートリポジトリ--->ワークスペース)
ソース: マイGitワークフロー