2つのリポジトリがあります。1つはライブラリのメインリポジトリで、もう1つはそのライブラリを使用するプロジェクトです。
下位のプロジェクトで修正を行う場合、そのパッチを上流に簡単に適用したいのですが。
ファイルの場所は、リポジトリごとに異なります。
www.playdar.org/static/playdar.js
playlick.com/lib/playdar.js
Playlickプロジェクトでgit format-patch -- lib/playdar.js
を使用してから、メインのplaydarリポジトリでgit am
を使用しようとしましたが、パッチファイル内のファイルの場所が異なるとエラーが発生しました。
特定のファイルの特定のコミットから別の任意のファイルにパッチを簡単に適用する方法はありますか?
ボーナスポイントについては、パッチを適用するファイルが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
_によって生成されるパッチは単なるテキストファイルです。差分ヘッダーを編集して、異なるパスを変更できます。
たとえば、次のようなものが生成されます。
_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"
_を介してパッチを実行するだけです。
パッチは、標準のGNUパッチユーティリティでgit
を持たないが、_format-patch
_を_-M
_、_-C
_などのオプションは、その場合に名前変更パッチを生成します。これらのサポートはユニバーサルではないためです。
両方のプロジェクトがgitプロジェクトであると仮定すると、 submodules が最適だと思われます。これにより、gitプロジェクトは別のgitプロジェクトに動的にリンクし、本質的に別のgitリポジトリ内にgitリポジトリを作成します。両方とも独自のライフを持ちます。
つまり、「プロジェクト」のサブモジュールとして「メインリポジトリ」を追加します。 「メインリポジトリ」に新しいものをコミット/プッシュするたびに、あなたはただgit pull
それらを「プロジェクト」に戻します。
Henrik's answer を完了し、ボーナスポイントを獲得するには
パッチを適用するファイルがgitリポジトリにない場合はどうなりますか?
Gitリポジトリからのパッチの候補ファイルのディレクトリにアクセスできる場合、最初にそのディレクトリ/ファイルのツリーをgitリポジトリ自体に変換できます! ( 'git init
':gitリポジトリは、結局のところ、ルートディレクトリ内の単なる.gitです)。
次に、そのレポをメインプロジェクトのサブモジュールとして設定します。
新しいリモートを追加して、そこからプルできます。 詳細が記載された記事
$ cd <path-to-repoB>
$ git remote add repoA <git-URL-for-repoA>
$ git pull repoA
_--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以降)。
メインリポジトリを一時的に削除(名前変更)するだけです。
cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git