1番目のブランチで削除され、2番目のブランチで名前が変更されたファイルのマージの競合を解決するにはどうすればよいですか?

teupはい

いくつかのフォルダを削除したブランチに取り組んでいます。その間に、マスターブランチでは、すべてのルートフォルダーの名前が変更されたため、すべてのファイル(削除したファイルを含む)のパスの名前が変更されました。

マージしようとすると、(ブランチで)削除され、(マスターで)名前が変更されたすべてのフォルダーのすべてのファイルで競合が発生します。git statusの非マージパスに次のように表示されるこれらの(1000以上の)ファイルのリストを作成しました:

added by them:   FolderRenamed/File1.ext
added by them:   FolderRenamed/File2.ext

この機会に、ブランチでマスターをマージしようとしたときの「それらの」バージョンからそれらを復元したいと思います(ただし、逆のことをしたいと思っていて、ファイルの削除が確認されている可能性があります。 「彼ら」の代わりに「私たち」と同じ概念)。

すべてのファイルに対して次のコマンドを簡単に呼び出すことができると思いました。

git checkout --theirs FolderRenamed/File1.ext

ただし、ファイルに対してこのコマンドを呼び出すと、変更が行われるようには見えません。私のファイルはまだ「マージされたパス」リストにあります。

誰かが私が間違っていることを特定するのを手伝ってもらえますか?ローカルバージョンが削除されたため、git checkoutが期待どおりに機能していませんか?

火曜日

TL; DR:あなたはgit add彼らに必要なだけです

より長いです

マージしようとすると、(ブランチで)削除され、(マスターで)名前が変更されたすべてのフォルダーのすべてのファイルで競合が発生します...

はい:実行すると、例:

git checkout branch
git merge master

ギット:

  • 現在のコミットを識別します(HEAD別名branch:これらはハッシュIDによって特定のコミットを1つ選択します。これは、現在インデックスとワークツリーにもあるコミットです)、ローカルまたは--oursも呼ばれますが、私はこれをLと呼びます(左/地元);
  • 他のコミット(別名masterを識別します。これは、remoteother、およびとも呼ばれます--theirsが、私はこれをR(右/リモート)と呼んでいます。
  • これら2つのコミット間マージベースを見つけます。これが最新の共通コミットです。私はこれをベースのBと呼びます

(チェックアウトしmasterて実行git merge branchすると、プロセスのこの部分でLRが入れ替わるだけであることに注意してください。)

次に、Gitは、事実上、git diff名前変更検出を有効にして2つのを実行します

git diff --find-renames B L > /tmp/b-vs-l.patch
git diff --find-renames B R > /tmp/b-vs-r.patch

結果は、ベースB以降Lで実行したすべてのリストと、同じベースB以降Rで実行したすべてのリストです次に、Gitはこれらの変更を組み合わせます。

ファイルの名前を変更し、(名前変更検出によって検出された)「同じ」ファイルを削除した場合、これは名前変更/削除の競合です。彼らがファイルの名前を変更し、あなたがそれを削除した場合、あなたは同じ衝突を得る。いずれにせよ、Gitには競合があります。

紛争の特殊な場合(ただし、通常の場合)、Gitは、あなたのインデックスに、残してすべてのファイルのすべての3つのバージョン:1からB「ステージ1」として、インデックス内のGitの葉を、。Gitが「ステージ2」または;としてインデックスに残すLからのもの--oursそして、Gitが「ステージ3」またはとしてインデックスに残すRからのもの--theirs

これらの番号の大きいステージファイルは、競合するマージの最中であることをGitが記憶する方法です。通常、インデックス内のすべてのファイルは「ステージゼロ」にあります。Gitがそれ自体で競合を解決できた場合、上位3つのステージが消去され、ステージ0で解決されたファイルだけが残ります。

ワークツリー内のファイルは(ほとんど)インデックス内のファイルから独立しており、もちろんワークツリーにはステージスロット番号がありません。存在できるのは1つだけsomepath/file1.extです。名前の変更と削除が競合する場合は、ベースファイルのステージ1エントリと、--oursまたは--theirsファイルのステージ2またはステージ3エントリがあります。他のステージスロット(それぞれ3または2)は空のままです。git statusコマンドとしてあなたに示している。このadded by us(1及び2占有、3空)またはadded by them(1と3が占有、2空)。

実行するgit checkout --oursと、Gitはstage-slot-2バージョンをワークツリーにコピーするように指示されます。実行するgit checkout --theirsと、Gitはstage-slot-3バージョンをワークツリーにコピーするように指示されます。いずれの場合も、stage-slot-1エントリには何も起こらず、stage-slot-zeroエントリは空のままです。

実行するgit addと、Gitはファイルをワークツリーからステージゼロスロットにコピー、残りのスロットを完全に消去するように指示しますこれでファイルが解決されました。

Gitは名前が変更されたファイルを(新しい名前で)ワークツリーに残すため、この場合に必要なのは名前git addが変更されたファイルだけです。

それはそれを行う唯一の方法ではありません

を実行すると、Gitは指定されたから指定されたものを抽出します。Gitがこれを行うと、パスがインデックスのスロット0にコピーされます。これにより、そのパスのスロット1〜3エントリがすべて消去されるため、特定のコミットからファイルをチェックアウトすると、ファイルが解決されるという副作用があります。git checkout commit-specifier -- pathpathcommit-specifier

これは異なっているgit checkout --ours--theirs、それらのエキスので、既存のインデックスエントリから、彼らはスロットゼロに書いていないので、。

したがって、を使用して、名前を変更したファイルを名前を変更した名前に抽出し、プロセスでのマージの競合を解決することもできます。git checkout MERGE_HEAD -- paths

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

Related 関連記事

ホットタグ

アーカイブ