これはあまりにも基本的な質問のように思えるかもしれませんが、私は答えを探しました、そして今私は以前より混乱しています。
私のブランチを他のブランチにマージするとき、 "ours"と "theirs"はgitで何を意味しますか?両方の枝は "私たちのもの"です。
マージコンフリクトでは、 "ours"が常に表示されている2つのバージョンのうちの上位になっていますか?
"ours"は、マージが始まったときにHEADが指していたブランチを常に指していますか?もしそうなら、(両ブランチとも技術的には私たちのものなので) "ours"のような所有代名詞を使うのではなく、 "current branch's"のような明確な所有参照を使わないでください。
または単に支店名を使用する(「私たちの」と言うのではなく「ローカルマスターの」などと言うのではなく)?
私にとって最も分かりにくいのは、特定のブランチの.gitattributesファイルで指定した場合です。で言うことができますテストブランチ私は次の.gitattributesファイルがあります:
config.xml merge=ours
チェックアウトしてHEADをmasterにポイントしてからtestにマージします。 masterは私たちのもので、testの.gitattributesはチェックアウトされていないので、それは効果さえありますか?もしそれが効果があるのなら、masterは "our's"になっているので、どうなるでしょう?
基本的に混乱しているので、ここで混乱していると思います。さらに悪いことに、リベースを行っているときに、私たち/スタッフ全員が役割を切り替えます(逆になります)。
最終的に、git merge
の間、「ours」ブランチは、マージするブランチを指しますinto:
git checkout merge-into-ours
「theirs」ブランチは、マージする(単一の)ブランチを指します。
git merge from-theirs
とにかく「彼ら」がおそらくあなたのものであるとしても、「彼ら」はあなたがいたものではないので、ここで「私たち」と「彼ら」はいくらか理にかなっていますongit merge
を実行したとき。
実際のブランチ名を使用するのはかなりクールかもしれませんが、より複雑な場合にはバラバラになります。たとえば、上記の代わりに、次のことを実行できます。
git checkout ours
git merge 1234567
生のcommit-IDでマージする場所。さらに悪いことに、これを行うことさえできます:
git checkout 7777777 # detach HEAD
git merge 1234567 # do a test merge
その場合、noブランチ名が含まれます!
ここではほとんど役に立たないと思いますが、実際には gitrevisions
構文 では、競合するマージ中にインデックス内の個々のパスを番号で参照できます
git show :1:README
git show :2:README
git show :3:README
ステージ#1はファイルの共通の祖先、ステージ#2はターゲットブランチバージョン、ステージ#3はマージ元のバージョンです。
「私たち」と「彼ら」の概念がrebase
の間に入れ替わる理由は、リベースが一連のチェリーピッキングを行うことにより、匿名ブランチ(分離されたHEADモード)で動作するためです。ターゲットブランチは匿名ブランチであり、merge-fromブランチは元の(リベース前)ブランチです。したがって、「-ours」はリベースする匿名の1つを意味し、「-theirs」は「リベースされるブランチ」を意味します。 。
Gitattributesエントリに関して:itcouldは効果があります: "ours"は実際には "use stage#2"を内部的に意味します。しかし、あなたが注意しているように、それは実際にはその時点では適切ではありませんので、は、ここでは効果がありません...まあ、あなたがそれをコピーしない限り開始する前に作業ツリーに移動します。
また、これはourとtheirsのすべての使用に適用されますが、一部はファイルレベル全体(マージ戦略の場合は-s ours
;マージ競合中のgit checkout --ours
)であり、一部はピースごと(-X ours
または-X theirs
マージ中の-s recursive
)。おそらくこれは混乱の助けにはなりません。
しかし、私はこれらのより良い名前を思いつきませんでした。そして: VonCの答え を参照してください。別の質問では、git mergetool
がこれらの名前をさらに紹介し、「ローカル」および「リモート」と呼んでいます。
Gitの「ours」は、git履歴の信頼できる/正規の部分を持つ元の作業ブランチを指します。
「theirs」は、 rebased (現在に再生される変更のために、作業を保持するバージョンを指しますブランチ)。
これは、リベース(例えばgit rebase
)が実際にあなたの作業を保留していることに気付いていない人(つまりtheirs)に交換されて、正規にリプレイするように見えるかもしれません/ main履歴はoursです。これは、変更をサードパーティの作業としてリベースしているためです。
git-checkout
のドキュメントは、Git> = 2.5.1で f303016
commit に従ってさらに明確になりました。
--ours
--theirs
インデックスからパスをチェックアウトするとき、マージされていないパスのステージ#2(「私たち」)または#3(「彼ら」)をチェックアウトします。
git rebase
およびgit pull --rebase
中に、「ours」と「theirs」が入れ替わっているように見えることに注意してください。--ours
は、変更がリベースされるブランチのバージョンを提供し、--theirs
は、リベースされる作業を保持するブランチのバージョンを提供します。これは、
rebase
が、リモートでの履歴を共有標準ワークフローとして扱い、リベースするブランチで行われた作業をサードパーティの作業として統合するワークフローで使用されるためです。リベース中に一時的に標準履歴のキーパーの役割を引き受けます。正規の履歴のキーパーとして、リモートからの履歴をours
(つまり、「共有された正規の履歴」)として表示する必要がありますが、サイドブランチで行ったことはtheirs
として(つまり、その上での貢献者の仕事」)。
git-merge
の場合、次のように説明されます。
ours
このオプションは、バージョンを優先することで、競合するハンクを強制的にきれいに自動解決します。私たちの側と競合しない他のツリーからの変更は、マージ結果に反映されます。バイナリファイルの場合、コンテンツ全体が当社側から取得されます。
これは、他のツリーに含まれる内容をまったく考慮しないマージ戦略と混同しないでください。それは他のツリーが行ったすべてを破棄し、その中に起こったすべてが私たちの歴史に含まれていると宣言します。
彼ら
これは私たちの反対です。
さらに、ここでそれらの使用方法を説明します。
マージメカニズム(
git merge
およびgit pull
コマンド)を使用すると、-s
オプションでバックエンドマージ戦略を選択できます。一部の戦略は独自のオプションを取ることもできます。これは、-X<option>
および/またはgit merge
にgit pull
引数を与えることで渡すことができます。
そのため、時には混乱を招く場合があります。例えば:
git pull Origin master
ここで-Xours
はローカル、-Xtheirs
は彼らの(リモート)ブランチですgit pull Origin master -r
ここで-Xours
は自分のもの(リモート)、-Xtheirs
は私たちのものですしたがって、2番目の例は1番目の例とは逆になります。これは、ブランチをリモートベースにリベースするため、開始点がリモートブランチであり、変更が外部として扱われるためです。
git merge
戦略(-X ours
および-X theirs
)でも同様です。
私はこれが答えられたことを知っています、しかしこの問題は私が覚えておくのを助けるために私が小さい参照ウェブサイトを立ち上げたことを何度も私を混乱させました: https://nitaym.github.io/ourstheirs/
これが基本です。
$ git checkout master
$ git merge feature
master
でバージョンを選択したい場合:
$ git checkout --ours codefile.js
feature
でバージョンを選択したい場合:
$ git checkout --theirs codefile.js
$ git checkout feature
$ git rebase master
master
でバージョンを選択したい場合:
$ git checkout --ours codefile.js
feature
でバージョンを選択したい場合:
$ git checkout --theirs codefile.js
(もちろんこれは完全なファイル用です)
git checkout
の使い方から:
-2, --ours checkout our version for unmerged files
-3, --theirs checkout their version for unmerged files
-m, --merge perform a 3-way merge with the new branch
マージの競合を解決するときは、git checkout --theirs some_file
とgit checkout --ours some_file
を実行して、それぞれファイルを現在のバージョンと着信バージョンにリセットします。
git checkout --ours some_file
またはgit checkout --theirs some_file
を実行し、ファイルを3-wayマージバージョンのファイルにリセットしたい場合は、git checkout --merge some_file
を実行できます。
あなたがbranch release/2.5 にいて、branch feature/new-buttons をマージしている場合、 release/2.5 にある内容がwhat ours を参照します。 /に含まれている内容と 機能/新しいボタン は何の 彼らのもの を指します。マージアクションの間、これはかなり簡単です。
ほとんどの人が陥る唯一の問題はリベースの場合です。通常のマージではなく再ベースを実行すると、役割が入れ替わります。どのようだ?まあ、それはもっぱらリベースが機能する方法によって引き起こされます。そのように動作するようにリベースを考える:
もちろん、それは実際に起こっていることではありませんが、それは私にとっては素晴らしいマインドモデルです。そして2と3を見れば、役割が今交換される理由がわかります。 2の時点で、あなたの現在のブランチは変更されていないサーバからのブランチになったので、これは ours (あなたがいるブランチ)になります。行った変更は現在のものではない別のブランチ( BranchX )になります。したがって、これらの変更は(あなたが行った変更であるにもかかわらず) theirs (あなたのアクションで使用される他のブランチ)です。 。
つまり、マージして変更を常に優先させる場合は、gitに常に "ours"を選択するように指示しますが、リベースしてすべての変更を常に優先させたい場合はgitに常に "theirs"を選択するように指示します。