あるリポジトリから別のリポジトリに git パッチを適用するにはどうすればよいですか?
-
06-09-2019 - |
質問
私には 2 つのリポジトリがあり、1 つはライブラリのメイン リポジトリで、もう 1 つはそのライブラリを使用するプロジェクトです。
従属プロジェクトで修正を行った場合、そのパッチを上流に適用する簡単な方法が必要です。
ファイルの場所はリポジトリごとに異なります。
- メインリポジトリ:
www.playdar.org/static/playdar.js
- プロジェクト:
playlick.com/lib/playdar.js
使ってみた git format-patch -- lib/playdar.js
プレイリックプロジェクトで、そして git am
メインの playdar リポジトリ上にありましたが、パッチ ファイル内のファイルの場所が異なるため、エラーが発生しました。
特定のファイルの特定のコミットから、別の場所にある別の任意のファイルにパッチを適用する簡単な方法はありますか?
おまけに、パッチを適用したいファイルが git リポジトリにない場合はどうすればよいでしょうか?
解決
パッチ ファイルを手動で編集することが問題外または実行不可能な場合は、標準オプション ( git apply
, git format-patch
とGNU patch
).
-p<n>
削除しますn
パッチ内のパスの先頭のディレクトリ。加工後
-p
,--directory=<root>
先頭に追加しますroot
適用する前にパッチ内の各パスに追加します。
例
たとえば、元々あったパッチを取得するには、 static/playdar.js
そしてそれを適用する lib/playdar.js
, 、次を実行します:
$ cat patch_file | git am \
-p1 \ # remove 1 leading directory ('static/')
--directory='lib/' # prepend 'lib/'
他のヒント
git format-patch
によって生成パッチは、単にそれが別のパスを変更するように、あなたは差分ヘッダを編集することができますfile--テキストです。
例えば、それはこのような何かを生産しているだろうだからます:
diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js
あなたがしなければならないのはlib/playdar.js
し、
static/playdar.js
を通じてパッチを実行するために変更git am"
です
パッチがサポートするので、生成するオプションが、その場合にはパッチの名前を変更git
を持っていない人のための標準的なGNUパッチユーティリティによって読取り可能でなければならない---しかしformat-patch
など、-M
で-C
を実行しないでください彼らのために普遍的ではありません。
と仮定すると、両方のプロジェクトがgitのプロジェクトがあり、それはそのサブモジュールになりますように聞こえますあなたのための完璧なフィット感。これは、Gitプロジェクトを動的に基本的に右の別のGitのレポ内のGitのレポを焼き付け、両方の自分自身の明確な命を持つ、別のGitプロジェクトにリンクできます。
つまり、「プロジェクト」のサブモジュールとして「メインレポ」を追加します。あなたが/「メインレポ」で新しいものをプッシュするコミットするたびに、あなただけ戻って、「プロジェクト」にそれらをgit pull
ます。
を完了するために、ヘンリックさんに答えると、ボーナスポイントのために行く。
あなたがにパッチを適用したいファイルはgitリポジトリにない場合は?
あなたはgitリポジトリからパッチの候補ファイルのディレクトリへのアクセスを持っている場合は、あなたが最初のgitリポジトリ自体にディレクトリ/ファイルのツリーを変換することができます! (「git init
」:gitリポジトリは、すべての後に、ルートディレクトリ内だけで.gitである)
。
次に、あなたの主なプロジェクトのためのサブモジュールとして、そのレポを設定します。
あなたは新しいリモートを追加し、そこから引き出すことができます。詳細は条。に
$ cd <path-to-repoB>
$ git remote add repoA <git-URL-for-repoA>
$ git pull repoA
あなただけの(名前の変更)一時的にメインリポジトリを削除することができます。
cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git
の使用 --relative
というオプション format-patch
抽象化を改善できます (パッチの生成元のリポジトリに関する無関係な詳細を非表示にします)。
[repository-with-changes]
git format-patch --relative=(path-to-library) (base-commit-for-patch) ## 'HEAD~1'
私が見つけたのは、 --3way
パッチを適用するときに必要なオプション (回避するため) does not exist in index
エラー) -- 走行距離は異なる場合があります。使用する --directory=(...)
おそらく、ターゲット パスがリポジトリのルートではない場合にのみ必要となります。
[repository-to-update]
git am --3way --directory=(path-to-library) (patch-file)
format-patch
「base」以降、現在のブランチへのコミットごとに 1 つのパッチ ファイルが作成されます。のドキュメント
--relative
オプションがあるようです 場合によっては欠落している, 、しかし、とにかく動作するようです(バージョン2.7.4現在)。