以前 diffコマンドを使ってソースコードのパッチの作ったところ、こんなのLinuxエンジニアじゃないじゃん。と笑われてしまいました。
diffコマンドでのパッチの作り方をググった時、どのオプションを作るべきかわからなかったり、そもそもどのオプションを付けるかさえ考えない人もいるかもしれません。
かっこいいLinuxエンジニアになるためには、適切なオプションを付けましょう!
diffコマンドでのパッチの作り方
Linuxカーネルのドキュメントフォルダ(Documentation/)には、SubmittingPatches
というドキュメントがあります。
このドキュメントの1章には以下のように書かれています。
Use "diff -up" or "diff -uprN" to create patches. git generates patches
in this form by default; if you're using git, you can skip this section
entirely.
パッチを作るためには、diff -up
もしくはdiff -uprN
コマンドを使いましょう。
つまり、
1つのソースコードに対するパッチを作成する
diff -up [オリジナルソース] [修正後ソース]
ディレクトリ以下のソースコードに対するパッチを作成する
diff -uprN [オリジナルソースディレクトリ] [修正後ソースディレクトリ]
とします。
オプションの意味を理解しておく
では、diffコマンドで使うべきオプションu
、p
、r
、N
はどんなオプションでしょうか?
詳細はman diff
などを見ればわかるので、ざっくり記載しておきます。
オプション | 意味 |
---|---|
u | unified形式で出力する |
p | 変更箇所の関数名(C言語)を表示する |
r | サブディレクトリを再帰的に比較する |
N | 比較するファイルが無い場合、同名の空ファイルがあるのと同じ動作をする |
テスト用のソースコードはhello worldのスペルを間違えたもので確認する。
#include <stdio.h>
int main(int argc, char **argv)
{
/* Test for diff patch.
* -4
* -3
* -2
*/
printf("Hello word!!\n");
return 0;
/* +2
* +3
* +4
*/
}
#include <stdio.h>
int main(int argc, char **argv)
{
/* Test for diff patch.
* -4
* -3
* -2
*/
printf("Hello world!!\n");
return 0;
/* +2
* +3
* +4
*/
}
「u」オプション
u
オプションを付加すると、差分ファイルの情報と、修正箇所の前後3行を出力してくれる。
どこが修正されたかわかりやすくなる。
user@debian7:~/$ diff -u source_org/c_lang/hello.c source/c_lang/hello.c
--- source_org/c_lang/hello.c 2015-02-22 15:11:44.218901466 +0900
+++ source/c_lang/hello.c 2015-02-22 20:11:18.528031250 +0900
@@ -7,7 +7,7 @@
* -3
* -2
*/
- printf("Hello word!!\n");
+ printf("Hello world!!\n");
return 0;
/* +2
* +3
「p」オプション
p
オプションを付加すると、差分ファイルの情報と、修正対象箇所の関数名を出力してくれる。
user@debian7:~/$ diff -p source_org/c_lang/hello.c source/c_lang/hello.c
*** source_org/c_lang/hello.c 2015-02-22 15:11:44.218901466 +0900
--- source/c_lang/hello.c 2015-02-22 20:11:18.528031250 +0900
*************** int main(int argc, char **argv)
*** 7,13 ****
* -3
* -2
*/
! printf("Hello word!!\n");
return 0;
/* +2
* +3
--- 7,13 ----
* -3
* -2
*/
! printf("Hello world!!\n");
return 0;
/* +2
* +3
「r」オプション
r
オプションを付加すると、ディレクトリ以下を再帰的に比較してくれる。
このとき、source/qtディレクトリに新たに生成されたhello_qt.cppファイルは差分がある事を知らせてくれている。
user@debian7:~$ diff -r source_org/ source/
diff -r source_org/c_lang/hello.c source/c_lang/hello.c
10c10
< printf("Hello word!!\n");
---
> printf("Hello world!!\n");
source/qtだけに発見: hello_qt.cpp
「N」オプション
N
オプションを付加すると、片側にしか無いファイルは差分がある事だけではなく、全行を差分として表示してくれる。
user@debian7:~$ diff -N source_org/qt/ source/qt
diff -N source_org/qt/hello_qt.cpp source/qt/hello_qt.cpp
0a1,11
> #include <QApplication>
> #include <QLabel>
>
> int main(int argc, char **argv)
> {
> QApplication app(argc, argv);
> QLabel* label = new QLabel("<i>Hello Qt!</i>");
>
> label->show();
> return app.exec();
> }
gitコマンドでのパッチの作り方
SubmittingPatches
にあるようにgit diffのコマンドでは全てオプションがついた状態と同じに出力される
gitコマンドの詳細は、ここには書きません。。。
user@debian7:~/$ git diff c976c2f4f
diff --git a/c_lang/hello.c b/c_lang/hello.c
index bab4f9d..53eafda 100644
--- a/c_lang/hello.c
+++ b/c_lang/hello.c
@@ -7,7 +7,7 @@ int main(int argc, char **argv)
* -3
* -2
*/
- printf("Hello word!!\n");
+ printf("Hello world!!\n");
return 0;
/* +2
* +3
diff --git a/qt/hello_qt.cpp b/qt/hello_qt.cpp
new file mode 100644
index 0000000..aa85988
--- /dev/null
+++ b/qt/hello_qt.cpp
@@ -0,0 +1,11 @@
+#include <QApplication>
+#include <QLabel>
+
+int main(int argc, char **argv)
+{
+ QApplication app(argc, argv);
+ QLabel* label = new QLabel("<i>Hello Qt!</i>");
+
+ label->show();
+ return app.exec();
+}
まとめ
- ファイル単位でパッチを作る場合は
diff -up
コマンドで行う - ディレクトリ単位でパッチを作る場合は
diff -uprN
コマンドで行う - git diffコマンドを使う場合は、diffの
-uprN
オプションと同じ形式で出力される