224
220

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Linuxエンジニアらしいパッチのつくりかた

Posted at

以前 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コマンドで使うべきオプションuprNはどんなオプションでしょうか?
詳細は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オプションと同じ形式で出力される
224
220
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
224
220

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?