パッチ互換の出力をgit-diffから取得できますか?


160

非常に単純な間違いをしています。通常のパッチファイルを準備しようとしているので、いくつかの変更を再適用できます。

$ git diff > before
$ git diff something_here > save.patch
$ git checkout . 
$ patch < save.patch
$ git diff > after
$ diff before after
$

something_here 、ブランクそれはほとんど動作しますが、ファイル名が正しくありません。私はいくつかのオプションが欠けているだけだと思います。

実際には、チェックアウト後にマージを実行するので、パッチが失敗する可能性がありますが、私が何をしているかがわかります。

間違った質問をしたため、ここで私の誤りを編集します。実際の質問は、変更を保存してマージし、可能であれば変更を再適用することです。私は慣れているので間違った方法で尋ねましたパッチをしてこれらの種類の問題を解決するており、git diffそれが私がしたかったように見えた。

チャールズベイリーズ コメントには正しい答えがありました。私にとって、git-applyは正しいことです(git-stashは必要以上に重く見え、リベースとバンドルは間違いなく私の現在のスキルレベルを超えています。)私はチャールズの回答を受け入れます(なぜなら、コメントは受け付けません)。すべての提案をありがとう。

編集、6年後 この話題に詳しい人なら誰でも知っているように、私はの難しさを過大評価しましたgit stash。ほぼ毎日、次のシーケンスを使用します。

$ git stash
$ git merge
$ git stash pop

8
あなたは、特に使用する任意の理由があるpatchのではなく、はgit apply
CBベイリー

3
そしてそれでも、あなたは本当に何かgit stash他のgitツールではなくパッチが必要ですか?
CBベイリー

3
編集後、それgit stashがあなたがやろうとしていることの最も簡単な解決策だと思いますが、機能するアプローチはたくさんあります。
CBベイリー

1
@Malvolio:確かにそれはある、あなたもであなたのパッチを保存するために一時ファイル名を考える必要はありません。
CBベイリー

4
@Charlse、場合によっては、gitリポジトリ全体を持たない誰かにパッチを送信する必要があります。たとえば、を使用する場合git-svn
Elazar Leibovich

回答:


139

パッチを使用したい場合はa/ b/、gitがデフォルトで使用する接頭辞を削除する必要があります。--no-prefixオプションでこれを行うことができます(パッチの-pオプションでもこれを行うことができます):

git diff --no-prefix [<other git-diff arguments>]

ただし、通常はそのままgit diff使用してから、出力を使用してにフィードする方が簡単git applyです。

ほとんどの場合、テキストパッチを使用しないようにします。通常、1つ以上の一時的なコミットとリベースを組み合わせるとgit stash、バンドルの管理が簡単になります。

あなたのユースケースでは、それstashが最も適切だと思います。

# save uncommitted changes
git stash

# do a merge or some other operation
git merge some-branch

# re-apply changes, removing stash if successful
# (you may be asked to resolve conflicts).
git stash pop

7
git diff --no-prefix master > diff.patchその後git checkout master patch -p0 < diff.patch
Natim 2014年

1
@Natim究極の安全のためにpatch --dry-run < diff.patch、最後のコマンドを発行する前に使用することをお勧めします。
ᴠɪɴᴄᴇɴᴛ

1
@ᴠɪɴᴄᴇɴᴛそうすることの利点は何でしょうか?私たちはgitを使用しているので、何も失う可能性は低いですね。
Natim

1
@Natim言ったように、究極の安全のために、エラーが発生した場合に何も元に戻す必要はありません。これを読んで、より一般的なユースケースpatchでgitの外で(おそらくで生成されたパッチファイルを使用して)使用したい人についても考えていdiffました。
ᴠɪɴᴄᴇɴᴛ

パッチに新しいファイルを含めるには、パッチに「git diff --no-prefix --cached」含める必要があります。多分もっと良い方法がありますか?
jamshid 2017年

219

ただ、使用-p1:あなたが使用する必要があります-p0--no-prefixあなたがちょうど残すことができますので、とにかくケース--no-prefixと使用を-p1

$ git diff > save.patch
$ patch -p1 < save.patch

$ git diff --no-prefix > save.patch
$ patch -p0 < save.patch

1
なぜだろうと思っているなら、man docsがそれをうまくまとめています- ソース
tutuDajuju 2016

3
これは名前変更では機能しません。無視git diffする行を出力patchします。git apply行く方法です。
hraban

17

git diffには、ファイルパスの前に追加のパスセグメントが追加されています。次のように、patchで-p1を指定することにより、パスのこのエントリを削除できます。

patch -p1 < save.patch

10
  1. 現在のHEADに対する現在のディレクトリ(コミットされていないファイルを含む)の差分を保存します。
  2. 次に、save.patchファイルをどこにでも転送できます(バイナリファイルを含む)。
  3. ターゲットマシンで、次を使用してパッチを適用します git apply <file>

注:現在のステージングファイルもdiffです。

$ git diff --binary --staged HEAD > save.patch
$ git reset --hard
$ <transport it>
$ git apply save.patch

ははは。それは面白い。ほぼ4年前にこの質問をしましたが、これまでのやり方は進化しましたが、昨日それを行う方法を尋ねられたなら、私はあなたの答えを与え、この質問の答えから得たと述べました。(実際、私はおそらくリセットではなくベアgit diff > save.patchを使用しますgit checkout .が、そうです...
Malvolio

ああ、その4歳に気づかなかった:P。ところで、リセットはそれが機能することを示すためだけのものです。またgit apply、あなたの状態に関連するdiff を使用または作成している人や、利用可能な最後のコミットへのポインタも見ていません。git diff何もしなかっただけです
Matej '

うん、今私は私が知ったか疑問git apply。使用しているのgit diffは(私が思うに)git reset、リポジトリ、インデックス、および作業領域の間の関係が問題です。
Malvolio

8

一時的なパッチファイルの作成を回避するための便利なトリック:

git diff | patch -p1 -d [dst-dir]

まさに私が欲しかったもの。スタッシュとの相性も抜群!git stash show -p stash@{3} | patch -p1 -d [dst-dir]
dtmland
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.