ウェブサイト検索

異なるファイルにGitコミットの差分を適用する方法


Gitは、プロジェクトの複数のブランチバージョンを自動的にマージすることを可能にする強力なバージョン管理システムです。それは素晴らしいですが、ファイルがリネームされたり、正しい場所にない場合は、時々壊れることがあります。幸いなことに、異なるファイルに手動でパッチを適用することができます。

問題

Gitのブランチを使用する際には、あるブランチから別のブランチに変更を適用する必要があることがよくあります。これの一般的な使用例は、バージョン管理されたブランチです---古いLTSリリースがある場合、古いバージョンに時折パッチを適用したいと思うかもしれません。あるいは、異なるツールチェーンや環境を対象とした2つのソフトウェアビルドを提供していて、それらを同期させる必要があるかもしれません。

もしあなたの支店が同じレイアウトを持っているなら、あなたは使用できます

git cherry-pick

別のブランチに個々のコミットをコピーできる。たとえば、フィーチャーブランチからコミットを引っ張ってくる場合など。

master

全てが統合される前に:

しかし、ソフトウェアは常に整理されているわけではなく、リファクタリングの過程で、ファイルが移動または名前の変更が行われた場合に遭遇することがあります。Gitはディレクトリパスで動作するため、これは完全に壊れます。

git cherry-pick

Gitは存在しないファイルに変更を適用できないため、

ただし、Gitにはこれを修正するためのツールがあるため、通常のマージがうまくいかないときは、手動で更新を含んだファイルをパッチすることができます。

git patch

Gitの差分とパッチの使用

これを示すために、単一のファイルを持つ空のリポジトリを作成します:

Old.java

新しいブランチ、old-versionがこのファイルといくつかの変更を加えて作成されます。このファイルは後の変更によって名前が変更されます。

master

支店へ

New.java

, ブランチ間の互換性が壊れる。

これは、GUI GitプログラムForkで表示されるブランチの履歴の見た目です:

この例では、「Add more code」コミットをold-versionブランチに移動する必要があります。それを行うには、そのコミットのIDをリファレンスログから取得する必要があります。

git reflog

次に、ID と -1 フラグを指定して format-patch を実行すると、パッチファイルが作成されます:

git format-patch 82176b5 -1

これにより、現在のディレクトリにパッチファイルが生成されます。これを、.gitignoreの設定に含まれる別のフォルダーに移動した方が良いでしょう。そうすれば、ブランチを切り替えても影響を受けません。

次に、old-versionブランチをチェックアウトし、Linuxのpatchユーティリティを使用してパッチ変更を適用します。Gitには、git applyおよびgit amという独自のツールがありますが、それらはリネームまたは移動の場合にターゲットファイルを変更するオプションがありません。パッチファイルを手動で編集する以外に。

ファイル名は-p1パラメータで渡し、パッチファイルは-iで渡すことができます。

patch -l -p1 old -i Patches/0001-Add-more-code.patch

これによりファイルが編集され、変更が追加されます。あなたはそれをコミットする必要があります。git am と比較した場合のpatchの一つの欠点は、コミット情報が保持されないことです。ただし、元のメッセージを保持しておきたい場合は、.patch ファイル内でそれを見つけることができます。

ただし、対象のブランチがその間に編集されると、マージコンフリクトが発生する可能性があります。その場合、git merge では解決できないため、手動で編集を行う必要があります。patch は差分を含むファイルを出力しますので、手動で修正する必要があります。

また、ターゲットファイルをGitが期待するターゲットディレクトリに移動させ、Gitがcherry-pickして変更を適用できるようにする方法もあります。その後、ファイルを元の場所にコピーし、一時ファイルを削除します。

パッチは、Windows 編集によって発生する可能性のある行末の改行 (LF) とキャリッジリターンの改行 (CRLF) に問題を抱えることもあります。パッチを正しく適用するには、テキストエディタで LF に切り替える必要があるかもしれません。

関連記事: