いくつかのフォルダを削除したブランチに取り組んでいます。その間に、マスターブランチでは、すべてのルートフォルダーの名前が変更されたため、すべてのファイル(削除したファイルを含む)のパスの名前が変更されました。
マージしようとすると、(ブランチで)削除され、(マスターで)名前が変更されたすべてのフォルダーのすべてのファイルで競合が発生します。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
)を識別します。これは、remote、other、およびとも呼ばれます--theirs
が、私はこれをR(右/リモート)と呼んでいます。(チェックアウトしmaster
て実行git merge branch
すると、プロセスのこの部分でLとRが入れ替わるだけであることに注意してください。)
次に、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 -- path
path
commit-specifier
これは異なっているgit checkout --ours
と--theirs
、それらのエキスので、既存のインデックスエントリから、彼らはスロットゼロに書いていないので、。
したがって、を使用して、名前を変更したファイルを名前を変更した名前に抽出し、プロセスでのマージの競合を解決することもできます。git checkout MERGE_HEAD -- paths
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加