Gitの2つのブランチをマージして、ブランチからnecessaryファイルを保持するにはどうすればよいですか?
2つのブランチをマージするときに、あるブランチでファイルが削除され、別のブランチでは削除されなかった場合、ファイルは最終的に削除されます。
例えば:
再現方法:
1つのファイルでgitリポジトリを作成します。
git init
echo "test" > test.txt
git add .
git commit -m "initial commit"
ブランチを作成する
git branch branchA
マスターのファイルを削除します
git rm test.txt
git commit -m "removed file from master"
削除されたファイルに触れないようにbranchAで変更を行います(競合を避けるために変更しないでください)
git checkout branchA
touch something.txt
git add .
git commit -m "some branch changes"
ここから、これら2つのブランチをマージすることがわかった場合、test.txtファイルは削除されます。 ファイルに依存がbranchA
の場合、これは大きな問題です。
失敗例:
マージ1
git checkout branchA
git merge master
ls test.txt
マージ2
git checkout master
git merge branchA
ls test.txt
リベース1
git checkout branchA
git rebase master
ls test.txt
これは興味深い問題です。 BranchA
の作成後にファイルを削除し、master
をBranchA
にマージしているため、Gitが競合の存在をどのように認識できるかわかりません。
不正なマージの後、元に戻し、再マージできますが、ファイルを追加し直します。
git checkout HEAD@{1} .
git merge --no-commit master
git checkout master test.txt
git add test.txt
git commit
この場合の簡単な修正方法として、ファイルを削除したコミットを「git revert」します。
将来この状況が発生した場合、それを処理するより良い方法は、新しいファイルの作成がブランチで確実に行われるようにすることです。その後、マージするとマスターに追加されますが、その間にマスター内にファイルが存在しません。
Caseyの例は私のケースでは機能しませんでした-チェックアウトできませんでしたtest.txt
from master
。これは、そのブランチにはもうないためです。
$ git checkout master test.txt
error: pathspec 'test.txt' did not match any file(s) known to git.
幸いなことに、branchA
自身のHEAD
からファイルを引き出すことができました。
$ git checkout branchA
$ git merge --no-commit master
$ git checkout HEAD test.txt
$ git add test.txt
$ git commit
これに対する私の解決策は、保持する必要のあるファイルを単に変更し(とにかく必要なコメントを追加し)、ターゲットブランチでそれらの変更をコミットすることでした。したがって、git add
および通常のコミット。
私の歴史はこんな感じでした。無実の人を保護するために、支店名が変更されました。
git merge master
feature_branchで、元のファイルが削除されます(もちろん)、git reset --hard
マージ前トランク内の削除とマージ競合が発生するように、ブランチ内のファイルを変更する必要があります。
たとえば、トランクのヘッダーファイルにあるものの宣言を削除し(必要がないため)、その宣言に対する依存関係をブランチの非ヘッダーファイルに追加した場合も、まったく同じことが起こります。マージすると、ブランチはヘッダー(の一部)に触れないため、宣言が削除されるだけで問題が発生します。
相互に依存し、同期を保つ必要があるものが複数の場所にある場合はいつでも、マージが静かに問題を引き起こすことが非常に簡単です。これは、マージ時に知って確認する必要があるものの1つです。理想的には、コンパイル時のアサートまたはその他のビルド時チェックを使用して、障害をすぐに明らかにします。