57745


git で管理されているソースコードをデプロイして動かしている環境があります。デプロイ後のその環境上では、ソースは git 管理されていません。

今、手元で作成した git の差分(`git diff` の出力物)があるのですが、それを、このサーバー上に直接適用したくなりました。

# 質問

git 上で、`git diff` で得られるような差分を、直接ファイルシステムに適用するにはどうしたら良いですか？

# 環境

  * centos 7


CC BY-SA 4.0
2019-08-30T01:52:59.860
57705
2019-09-01T03:17:17.960
754
question
git
git の差分を直接対象ディレクトリに適用したい


`git diff`に`--output`オプションがあります。

[code]

    $ man git-diff
    
       --output=<file>
           Output to a specific file instead of stdout.
    
[/code]

**実行例**

[code]

    $ git diff --output=OUTPUT.diff HEAD~ /path/to/file
    
[/code]

複数ファイルの場合は試していません。


CC BY-SA 4.0
2019-08-30T02:03:24.500
57707
2019-08-30T02:03:24.500
3060
57705
answer


ソースコード管理ツールが普及する以前は `diff` と `patch` で差分を管理していました。今でもできます。

`diff` でとったソースコードの差分をパッチファイルと呼びます。  
パッチファイルをそのまま `patch` に入力すると差分が適用されます。

[code]

    branch_a$ diff -u old_source_dir new_source_dir > /var/tmp/brancha_patch
    branch_a$ cd ../branch_b
    branch_b$ patch < /var/tmp/brancha_patch
    
[/code]

`patch`
はかなり賢くて、差分元と適用先で、行番号が違うとか、ファジー論理が許す範囲でちょっとだけソース内容が違うとかの場合でも、差分ファイルを適用してくれます。機械的に適用できなかった差分は
`.rej` ファイルに残るなどいたせりつくせりです。

元ファイルが `git` で管理できているのなら、最初の `diff` の代わりに `git diff` が使えます。 `patch`
のための情報を最大限に供給できるよう `unified` 形式を使うとよいでしょう。 `man git` においても `-p`
オプションを指定することが推奨されています（自動的に `unified diff` 形式で出力されます）

まあデプロイ先に `patch` が無いとなると無理っすけど。


CC BY-SA 4.0
2019-08-30T02:51:37.920
57709
2019-08-30T02:51:37.920
8589
57705
answer


  1. (レポジトリにて) `git diff 引数forDiff > foo.patch` して、これをサーバーに持っていく
  2. (ソースのベースディレクトリにて) `patch -p 1 < path/to/foo.patch` することで、適用できることを確認しました。

`-p 1` の引数は、 git diff の出力は、 diff 引数ファイルパス情報として、仮想的な `a` と `b` を付与しているらしく、それを
strip して適用するために、必要となる様子です。

以下が、 diff の中の、その仮想的なパスの例。

[code]

    --- a/app/models/foo.rb
    +++ b/app/models/foo.rb
    
[/code]


CC BY-SA 4.0
2019-08-30T07:10:57.250
57718
2019-08-30T07:10:57.250
754
57705
answer


> git 上で、git diff で得られるような差分を、直接ファイルシステムに適用するにはどうしたら良いですか？

git 管理されていない状態でも **git apply** でできると思います。手元ではできました。

[code]

    $ git diff --color=never > diff.txt
    
[/code]

[code]

    $ git apply diff.txt
    
[/code]


CC BY-SA 4.0
2019-09-01T03:17:17.960
57745
2019-09-01T03:17:17.960
35180
57705
answer