似ているがコミット履歴が異なる2つのリポジトリAとBがあるとしましょう。
例としては、2つのPython Flaskアプリケーションや、多くの類似したファイルを共有しているが完全に同一ではない2つのRuby onRailsアプリケーションがあります。
リポジトリAに変更を加え、リポジトリBにも適用したいと思います。Bに適用する際にいくつかの競合が発生する可能性がありますが、それは問題ありません。それらが何であるかを確認し、それらを処理したいと思います。
リポジトリAからパッチを生成するために次のことを試みました
> cd ~/git/repoA/
> git format-patch HEAD~
0001-My-Example-Commit.patch
> mv 0001-My-Example-Commit.patch ~/git/repoB
そして、レポBにパッチを適用してみました
> cd ~/git/repoB
> git am 0001-My-Example-Commit.patch
Applying: My Example Commit
error: patch failed: Gemfile:20
error: Gemfile: patch does not apply
error: patch failed: Gemfile.lock:125
error: Gemfile.lock: patch does not apply
error: patch failed: app/assets/stylesheets/application.scss:29
error: app/assets/stylesheets/application.scss: patch does not apply
....
....
error: patch failed: spec/views/application/_mobile_navigation.html.erb_spec.rb:44
error: spec/views/application/_mobile_navigation.html.erb_spec.rb: patch does not apply
Patch failed at 0001 Using Devise for authentication
hint: Use 'git am --show-current-patch' to see the failed patch
When you have resolved this problem, run "git am --continue".
If you prefer to skip this patch, run "git am --skip" instead.
To restore the original branch and stop patching, run "git am --abort".
示されているように、いくつかのエラー/競合が発生します。それは問題ありません。通常のマージで行うように、競合が何であるかを確認して修正しようとします。
git status
On branch test-git-apply
You are in the middle of an am session.
(fix conflicts and then run "git am --continue")
(use "git am --skip" to skip this patch)
(use "git am --abort" to restore the original branch)
nothing to commit, working tree clean
Gitは変更を差分として適用することすらしないので、差分/変更されたファイルはなく、競合が何であるかを確認したり、それらを修正しようとしたりすることさえできません
gitに競合を表示させる方法はありますか?
ありがとう!
編集:
--directory
オプションが存在することは知っていますが、パッチファイルは同じルートに対してすでに生成されているため、ここでは適用されないと思います。例えば
diff --git a/Gemfile b/Gemfile
index c970c34..ffc812d 100644
--- a/Gemfile
+++ b/Gemfile
@@ -20,12 +20,17 @@ gem "webpacker", "~> 3.5", ">= 3.5.5"
#
gem "bcrypt", "~> 3.1", ">= 3.1.10"
gem "cancancan", "~> 3.0"
....
競合はありません。1パッチの適用に失敗しただけです。たとえば、パッチは次のように言うかもしれません:87行目は「foo」と読みます。次の行88で、「bar」を「baz」に変更します。89行目は「quux」と書かれています。しかし、87行目から89行目は、「foo」、「bar」、「quux」を読み取っていません。また、そのシーケンスを含む近くの行もありません。パッチをどうするかを理解するのはプログラマーのあなた次第です。
hint: Use 'git am --show-current-patch' to see the failed patch
だから、それを使用してください。パッチを読んでください。ファイルを調べて、このパッチの処理方法を決定します。
1パッチ自体は、同じ行に対する2つの異なる変更セットを表していないため、ここで競合が発生することはありません。2つの差分がある場合に競合が発生します。1つは88行目でバーをbazに変更するように指示し(これは可能です)、もう1つは88行目でバーをrabに変更するように指示します(これも可能です)。2つの変更は競合します。
パッチは1つの変更のみを提供します。適用されるか、適用されないかのどちらかです。
ここには2つの代替オプションがあります。効果の低い注文から効果の高い注文へ:
リポジトリAからのパッチがによって生成されたことを確認してくださいgit format-patch --full-index
。をgit am
使用する場合は、を使用しますgit am -3
(またはに構成am.threeWay
しますtrue
)。そうA
すれば、差分にはファイルの親バージョンの完全なblobハッシュが含まれます。そのblob(ファイルの親バージョン)がリポジトリBで利用できる場合、Gitはblob-hash-and-patchを使用して、実際のマージに必要な3つの入力(共通ベースバージョンと両方の変更)を再構築できます。 from-baseバージョン。
または、git remote add
リポジトリBで使用して、リポジトリAへの直接アクセスを追加します。後でこれが何であるかを思い出させるリモート名を選択します(または直後にリモートを削除します)。次に実行するgit fetch
ので、コミットのすべての代わりに、B.今すぐ内で局所的に利用可能であることを、レポBにレポAからコミットをもたらすために、このリモート名にgit format-patch
してgit am
、あなただけ実行することができます:
git cherry-pick <hash>
問題のコミットに対して。Gitは、リポジトリAからの2つのコミットをmerge-baseおよびtheir-changeとして使用して、完全な3方向マージを実行します。
git diff <parent of hash> <hash> # what they changed
そしてあなたの現在のコミットはあなたの変化です:
git diff <parent of hash> HEAD # what we changed
必要に応じて競合を加えて、それらを組み合わせます。ここでの2番目のdiffコマンドは、「変更した内容」または--ours
マージの一部です。ここでの最初のdiffコマンドは「変更内容」であり、したがって--theirs
マージの一部です。
git am -3
、または設定am.threeWay
は、次のことを期待して完全なマージを試行する方法にすぎないことに注意してください。
index a1539a7ce682f10a5aff3d1fee4e86530e058c89..98f88a28d3227c436ecf1765f75b7f4e8e336834 100755
リポジトリに表示されるハッシュIDを提供します。まだ持っていない場合は、git fetch
実際に実行すると、そのハッシュIDを持つblobが取得されるため、単なる希望や希望は必要ありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加