git diff でpatchファイルを作ってみる

git管理下の開発環境での修正をまとめて、git管理してない本番環境へ適用したかったのでpatchファイルを作って見ました

サンプルとしてこんなディレクトリ構成として

$ tree
.
├── 1
│   ├── 1-1
│   │   └── 1.1.text
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
└── 2
    ├── 1-1
    │   └── 1.1.text
    ├── 1.txt
    └── 2.txt

ちょこっとファイルを修正してcommitして

$ git diff -u HEAD^ > diff.patch
$ cat diff.patch
diff --git a/1/1-1/1.1.text b/1/1-1/1.1.text
index d7cd238..f4cb53a 100644
--- a/1/1-1/1.1.text
+++ b/1/1-1/1.1.text
@@ -1 +1,2 @@
+1-1
 2-1
diff --git a/1/1.txt b/1/1.txt
index 5f2f16b..092362d 100644
--- a/1/1.txt
+++ b/1/1.txt
@@ -1 +1 @@
-1111
+this is 1.

と、git diffの結果を出力してあげます
注意するのは、実際のディレクトリの前にa、bがついています(差の比較のための印)

本番環境へgit diffを出力したのと同じ階層のディレクトリにdiff.patchを移動させて、patchコマンドで取り込みます
そのままpatchコマンドであてると、ディレクトリがないと怒られます

$ patch < diff.patch
can't find file to patch at input line 5
Perhaps you should have used the -p or --strip option?
The text leading up to this was:
--------------------------
|diff --git a/1/1-1/1.1.text b/1/1-1/1.1.text
|index d7cd238..f4cb53a 100644
|--- a/1/1-1/1.1.text
|+++ b/1/1-1/1.1.text
--------------------------
File to patch: 

a、bディレクトリ分の1階層を無視してあてます

$ patch -p1 < diff.patch
patching file 1/1-1/1.1.text
patching file 1/1.txt

これで差分があたりました
実際はあてる前に、patch –dry-run -p1 < diff.patch として確かめてからあてたほうがいいです
(これだと、結果は出してくれるが、実際は更新されない)

また、git diffのときに–no-prefixをつけると

$ git diff -u --no-prefix HEAD^ > diff.patch
$ cat diff.patch
diff --git 1/1-1/1.1.text 1/1-1/1.1.text
index d7cd238..f4cb53a 100644
--- 1/1-1/1.1.text
+++ 1/1-1/1.1.text
@@ -1 +1,2 @@
+1-1
 2-1
diff --git 1/1.txt 1/1.txt
index 5f2f16b..092362d 100644
--- 1/1.txt
+++ 1/1.txt
@@ -1 +1 @@
-1111
+this is 1.

と、a、bがつかなくなるので、patchコマンド時にそのままあてられます

git diff でbranch間の差をみてみる

branch1とbranch2があるとして

branch1とbranch2のすべてのファイルの差が見るなら
$ git diff (branch1) (branch2)

特定の同じ名前ファイルだけなら
$ git diff (branch1) (branch2) (ファイル名)

違う名前のファイルの差をみるなら
$ git diff (branch1):(ファイル名) (branch2):(ファイル名2)

git diff の使い方を整理

$ git init
でディレクトリ以下をgitの管理対象にして

$ git add file
でworking treeからindexに登録

$ git commit
でindexのファイルをHEADへ登録

git-basic
という感じです

$ git diff
working treeとindexの差を表示

$ git diff –cached
indexとHEADの差を表示

$ git diff HEAD
working treeとHEADの差を表示

git-diff
といった感じです

diffコマンドの使い方

ファイルの差分をみるdiffコマンドを整理してみました
Ubuntu 12.04で試しています

フォルダ構成がこんな感じ時


$ tree
.
├── 1
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
└── 2
    ├── 1.txt
    └── 2.txt

差分を見たい時、


$ diff 1 2
diff 1 2
diff 1/2.txt 2/2.txt
1c1
< 1111
---
> 2222
1 のみに存在: 3.txt

unified形式だと


$ diff -u 1 2
diff -u 1/2.txt 2/2.txt
--- 1/2.txt     2014-10-16 17:11:17.925405481 +0900
+++ 2/2.txt     2014-10-16 17:17:43.965416847 +0900
@@ -1 +1 @@
-1111
+2222
1 のみに存在: 3.txt

で最初の3行がまとめで、それ以降が差です
– が1つ目のディレクトリ、+ が2つ目のディレクトリ

さらにフォルダを追加して


$ tree
.
├── 1
│   ├── 1-1
│   │   └── 1.1.text
│   ├── 1.txt
│   ├── 2.txt
│   └── 3.txt
└── 2
    ├── 1-1
    │   └── 1.1.text
    ├── 1.txt
    └── 2.txt

差分をみます、サブディレクトリも比較するには-rが必要です


$ diff -u -r 1 2
共通のサブディレクトリー: 1/1-1 と 2/1-1
diff -u 1/2.txt 2/2.txt
--- 1/2.txt     2014-10-16 17:41:37.781459066 +0900
+++ 2/2.txt     2014-10-16 17:41:54.381459554 +0900
@@ -1 +1 @@
-1111
+22222
1 のみに存在: 3.txt
user@user-ThinkPad-X120e:~/workspace/diff$ diff -u -r 1 2
diff -u -r 1/1-1/1.1.text 2/1-1/1.1.text
--- 1/1-1/1.1.text      2014-10-16 17:36:31.969450061 +0900
+++ 2/1-1/1.1.text      2014-10-16 17:42:11.921460071 +0900
@@ -1 +1 @@
-1-1
+2-1
diff -u -r 1/2.txt 2/2.txt
--- 1/2.txt     2014-10-16 17:41:37.781459066 +0900
+++ 2/2.txt     2014-10-16 17:41:54.381459554 +0900
@@ -1 +1 @@
-1111
+22222
1 のみに存在: 3.txt

差分をとってあてるには


$ diff -u -r 1 2 > patch.txt
$ mv patch.txt 1/
$ cd 1
$ patch -p1 < patch.txt
patching file 1-1/1.1.text
patching file 2.txt

と、diffの結果をファイルにして、あてたいフォルダへ移動、patchコマンドの-p1が1階層無視するオプションです
差分を適用したいフォルダを1つ目に指定します(今回は1ディレクトリ)