git rebaseを実行するとき、競合を解決するときに「ローカル」と「リモート」で何が起こっているのかを理解するのが難しいことがよくあります。あるコミットから次のコミットにサイドを入れ替えるような印象を受けることがあります。
これはおそらく(間違いなく)まだ適切に理解していないためです。
リベースするとき、誰が「ローカル」で誰が「リモート」ですか?
(私は競合の解決にP4Mergeを使用しています)
git rebaseを実行するとき、競合を解決するときに「ローカル」と「リモート」で何が起こっているのかを理解するのが難しいことがよくあります。あるコミットから次のコミットにサイドを入れ替えるような印象を受けることがあります。
これはおそらく(間違いなく)まだ適切に理解していないためです。
リベースするとき、誰が「ローカル」で誰が「リモート」ですか?
(私は競合の解決にP4Mergeを使用しています)
回答:
git checkout A
git rebase B # rebase A on top of B
local
されているB
(リベースに)、remote
です A
そして:
git checkout A
git merge B # merge B into A
local
であるA
(マージに、)remote
です B
rebaseはours
(rebaseが開始する前の現在のブランチ)と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
は最初HEAD
にBを上流のブランチに変更しますHEAD
(したがって、以前の「現在の」作業ブランチと比較して、「ours」と「theirs」が切り替わります。
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
注:「上流」の概念は、データの読み取り元または新しいデータの追加/作成先となる参照データセット(すべてのリポジトリ、またはこのようにローカルブランチにすることができるブランチ)です。
local
」と「remote
」対「mine
」と「theirs
」私にとっては、「ローカル」で誰が「リモート」であるかという質問がまだ残っています(gitでリベースするときに「ours」と「theirs」という用語は使用されないため、それらを参照すると答えが混乱するようです) 。
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):
たとえば、KDiff3は次のようにマージ解像度を表示します。
git mergetool -t gvimdiffを使用して、Vimdiffをmergetoolとして起動します。Gitの最近のバージョンは、次のウィンドウレイアウトでVimdiffを呼び出します。
+--------------------------------+
| LOCAL | BASE | REMOTE |
+--------------------------------+
| MERGED |
+--------------------------------+
LOCAL
:
現在のブランチ上のファイルのコンテンツを含む一時ファイル。BASE
:
マージの共通ベースを含む一時ファイル。REMOTE
:
マージするファイルの内容を含む一時ファイル。MERGED
:
競合マーカーを含むファイル。Gitは可能な限り多くの自動競合解決を実行しており、このファイルの状態は両方の組み合わせと、Gitがそれ自体で解決できなかったものを囲む競合マーカー
LOCAL
との組み合わせですREMOTE
。このファイルへの解決の結果を記述する必要があります。mergetool
git checkout A; git rebase B
ローカルがBの場合、リモートはAです。知っておくべきことはすべて...
git checkout A; git rebase B
ローカルがBの場合、リモートはAです。私がした場合checkout A
、私は午前彼らが存在するとして、現在のファイルを見てA
、どのようにどのような方法であることをリモート?(私はBenubirdが間違っていると言っているのではありません。gitには愚かなUXがあると言っています)
{branch A}
および{branch B}
または類似。
肝心なこと
git rebase
gitマージ
言い換えると、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)
結果は、上に表示されているものと同じになります。
local
/ remote
側面を明らかにします(とにかくours
vs の逆転についてtheirs
です)
問題を正確に理解できませんでしたが、次の図で問題が解決したと思います。(リベース:リモートリポジトリ--->ワークスペース)
出典:My Gitワークフロー