git format-patchって便利ですね(*゚▽゚)ノ ということでメモ。

git format-patchで時系列に沿った形の一連のパッチ作成。

リポジトリを初期化して、ファイルを追加

[masami@moon:~/build/hello]% git init
Initialized empty Git repository in /home/masami/build/hello/.git/
[masami@moon:~/build/hello]% emacs hello.c
[masami@moon:~/build/hello]% git add hello.c
[masami@moon:~/build/hello]% git commit -a
[master (root-commit) f0e33a4] first commit.
 1 files changed, 6 insertions(+), 0 deletions(-)
 create mode 100644 hello.c

この時点ではこんな感じ

#include <stdio.h>

int main(int argc, char **argv)
{
        return 0;
}

hello-testブランチを作ってそちらで作業する。

[masami@moon:~/build/hello]% git checkout -b hello-test master
Switched to a new branch 'hello-test'
[masami@moon:~/build/hello]% emacs hello.c
[masami@moon:~/build/hello]% git commit -a
[hello-test daa6520] added say_hello().
 1 files changed, 6 insertions(+), 0 deletions(-)

最初に、say_hello()を追加。

#include <stdio.h>

void say_hello(char **argv)
{
}

int main(int argc, char **argv)
{
       say_hello(argv);

       return 0;
}

次にsay_hello()の中身を実装。

[masami@moon:~/build/hello]% emacs hello.c
[masami@moon:~/build/hello]% git commit -a
[hello-test ad2e558] implement say_hello().
 1 files changed, 3 insertions(+), 0 deletions(-)
#include <stdio.h>

void say_hello(char **argv)
{       
        while (*argv)
               printf("%s ", *argv++);
       putchar('\n');
}

int main(int argc, char **argv)
{
       say_hello(argv);

       return 0;
}

ここで、masterブランチで変更を入れる

[masami@moon:~/build/hello]% git checkout master
Switched to branch 'master'
[masami@moon:~/build/hello]% emacs hello.c
[masami@moon:~/build/hello]% git commit -a
[master 3f66a64] added comment.
 1 files changed, 3 insertions(+), 0 deletions(-)

masterブランチはファイルの先頭にコメントを追加。

/**
 * this is a sample code
 */
#include <stdio.h>

int main(int argc, char **argv)
{
        return 0;
}

またhello-testブランチに戻る

[masami@moon:~/build/hello]% git checkout hello-test
Switched to branch 'hello-test'

masterブランチの変更を取り込むのだが、git rebaseを使ってhello-testで行っている一連の変更を保たせる。

[masami@moon:~/build/hello]% git rebase master
First, rewinding head to replay your work on top of it...
Applying: added say_hello().
error: patch failed: hello.c:1
error: hello.c: patch does not apply
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging hello.c
Applying: implement say_hello().
[masami@moon:~/build/hello]% emacs hello.c
[masami@moon:~/build/hello]% git commit -a
[hello-test 9f82d08] say_hello() should be static method.
 1 files changed, 1 insertions(+), 1 deletions(-)

say_hello()をstaticに変更。

/**
 * this is a sample code
 */
#include <stdio.h>

static void say_hello(char **argv)
{
        while (*argv)
                printf("%s ", *argv++);
        putchar('\n');
}

int main(int argc, char **argv)
{
        say_hello(argv);

        return 0;
}

最後に以下のコマンドでmasterとの差分を作成。-sオプションでSigned-off-byの行を追加できます。
fromとSigned-off-byの名前とメアドは変えましたが、メール送信出来る形でパッチが作成できます。

[masami@moon:~/build/hello]% git format-patch -s master
0001-added-say_hello.patch
0002-implement-say_hello.patch
0003-say_hello-should-be-static-method.patch

[masami@moon:~/build/hello]% cat 0001-added-say_hello.patch
From e78f286df1376b2cb01aaf0eb685e798d7e888e2 Mon Sep 17 00:00:00 2001
From: foo <mail address>
Date: Thu, 25 Jun 2009 22:30:10 +0900
Subject: [PATCH 1/3] added say_hello().


Signed-off-by: foo <mail address>
---
 hello.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/hello.c b/hello.c
index b029e64..8535e02 100644
--- a/hello.c
+++ b/hello.c
@@ -3,7 +3,13 @@
  */
 #include <stdio.h>

+void say_hello(char **argv)
+{
+}
+
 int main(int argc, char **argv)
 {
+       say_hello(argv);
+
        return 0;
 }
--
1.6.3.1

[masami@moon:~/build/hello]% cat 0002-implement-say_hello.patch
From 069deb249439ef11c159102cb539a8dd844d308d Mon Sep 17 00:00:00 2001
From: foo <mail address>
Date: Thu, 25 Jun 2009 22:31:05 +0900
Subject: [PATCH 2/3] implement say_hello().


Signed-off-by: foo <mail address>
---
 hello.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

diff --git a/hello.c b/hello.c
index 8535e02..c2788fa 100644
--- a/hello.c
+++ b/hello.c
@@ -5,6 +5,9 @@

 void say_hello(char **argv)
 {
+       while (*argv)
+               printf("%s ", *argv++);
+       putchar('\n');
 }

 int main(int argc, char **argv)
--
1.6.3.1

[masami@moon:~/build/hello]% cat 0003-say_hello-should-be-static-method.patch
From 9f82d0835bf95b0cf6c3ea8ca966e72254734f90 Mon Sep 17 00:00:00 2001
From: foo <mail address>
Date: Thu, 25 Jun 2009 22:32:34 +0900
Subject: [PATCH 3/3] say_hello() should be static method.


Signed-off-by: foo <mail address>
---
 hello.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/hello.c b/hello.c
index c2788fa..cff1bd9 100644
--- a/hello.c
+++ b/hello.c
@@ -3,7 +3,7 @@
  */
 #include <stdio.h>

-void say_hello(char **argv)
+static void say_hello(char **argv)
 {
        while (*argv)
                printf("%s ", *argv++);
--
1.6.3.1

[masami@moon:~/build/hello]%