web-dev-qa-db-ja.com

git merge:保持したいファイルを削除します!

Gitの2つのブランチをマージして、ブランチからnecessaryファイルを保持するにはどうすればよいですか?

2つのブランチをマージするときに、あるブランチでファイルが削除され、別のブランチでは削除されなかった場合、ファイルは最終的に削除されます。

例えば:

  • 新しいブランチを作成すると、マスターにファイルが存在します
  • (まだ)必要ないので、マスターからファイルを削除します。
  • ブランチに変更を加えて機能を追加します既存のファイルに依存します
  • マスターでバグ修正を行う(破棄できません)
  • いつかマージすると、ファイルはなくなります!

再現方法:

  1. 1つのファイルでgitリポジトリを作成します。

    git init
    echo "test" > test.txt
    git add .
    git commit -m "initial commit"
    
  2. ブランチを作成する

    git branch branchA
    
  3. マスターのファイルを削除します

    git rm test.txt
    git commit -m "removed file from master"
    
  4. 削除されたファイルに触れないように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
53
drfloob

これは興味深い問題です。 BranchAの作成後にファイルを削除し、masterBranchAにマージしているため、Gitが競合の存在をどのように認識できるかわかりません。

不正なマージの後、元に戻し、再マージできますが、ファイルを追加し直します。

git checkout HEAD@{1} .
git merge --no-commit master
git checkout master test.txt
git add test.txt
git commit
27
cmcginty

この場合の簡単な修正方法として、ファイルを削除したコミットを「git revert」します。

将来この状況が発生した場合、それを処理するより良い方法は、新しいファイルの作成がブランチで確実に行われるようにすることです。その後、マージするとマスターに追加されますが、その間にマスター内にファイルが存在しません。

6
Phil

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
5
Alex Dean

これに対する私の解決策は、保持する必要のあるファイルを単に変更し(とにかく必要なコメントを追加し)、ターゲットブランチでそれらの変更をコミットすることでした。したがって、git addおよび通常のコミット。

私の歴史はこんな感じでした。無実の人を保護するために、支店名が変更されました。

  1. 新しい機能をマスターするためのファイルを作成してコミットする
  2. この追加が当初の計画よりも複雑になるため、feature_branchに分岐することを理解してください
  3. RBなどの通常のワークフローを妨げないように、マスターからファイルを削除しました
  4. 時間が経過し、マスターでさらにコミットされ、feature_branchでコミットされない
  5. 機能の作業を再開します、git merge master feature_branchで、元のファイルが削除されます(もちろん)、git reset --hardマージ前
  6. 上記のソリューションを適用しました
2
Alex S

トランク内の削除とマージ競合が発生するように、ブランチ内のファイルを変更する必要があります。

たとえば、トランクのヘッダーファイルにあるものの宣言を削除し(必要がないため)、その宣言に対する依存関係をブランチの非ヘッダーファイルに追加した場合も、まったく同じことが起こります。マージすると、ブランチはヘッダー(の一部)に触れないため、宣言が削除されるだけで問題が発生します。

相互に依存し、同期を保つ必要があるものが複数の場所にある場合はいつでも、マージが静かに問題を引き起こすことが非常に簡単です。これは、マージ時に知って確認する必要があるものの1つです。理想的には、コンパイル時のアサートまたはその他のビルド時チェックを使用して、障害をすぐに明らかにします。

2
Chris Dodd