Help us understand the problem. What is going on with this article?

git diff, svn diff でヘッダにラベルを避けて関数名を出したい

More than 3 years have passed since last update.

対象

  • Subversion : 1.9.3
  • Git : 2.7.4
  • C言語のソースファイル

問題

git diffsvn diff で各差分のヘッダ (hunk-header?) に以下のように関数名も出せる。

@@ -2,7 +2,7 @@ void func1() {

しかし、以下のようにラベルが出てしまうことがある。

@@ -21,5 +21,5 @@ ERROR:

ラベルは避けて関数名を出したい。

サンプルファイル

以下の sample.c の差分で試す。

sample.c(変更前)
void func1() {
    //
    //
    //
    printf("bar\n");
}

void func2(char *s) {
    //
    //
    //
    if (s == NULL) {
        goto ERROR;
    }
    printf("'%s'\n", s);
    return;
    //
    //
    //
ERROR:
    //
    //
    //
    printf("Error!\n");
}
sample.c(変更後)
void func1() {
    //
    //
    //
    printf("BAR\n");
}

void func2(char *s) {
    //
    //
    //
    if (s == NULL) {
        goto ERROR;
    }
    printf("%s\n", s);
    return;
    //
    //
    //
ERROR:
    //
    //
    //
    printf("error!\n");
}

Subversion

内蔵の diff だとラベルが出てしまう。

svn diff -x -p
Index: sample.c
===================================================================
--- sample.c    (リビジョン 3)
+++ sample.c    (作業コピー)
@@ -2,7 +2,7 @@ void func1() {
     //
     //
     //
-    printf("bar\n");
+    printf("BAR\n");
 }

 void func2(char *s) {
@@ -12,7 +12,7 @@ void func2(char *s) {
     if (s == NULL) {
         goto ERROR;
     }
-    printf("'%s'\n", s);
+    printf("%s\n", s);
     return;
     //
     //
@@ -21,5 +21,5 @@ ERROR:
     //
     //
     //
-    printf("Error!\n");
+    printf("error!\n");
 }

以下のように実装されていてラベルもヒットすると思われる。private:, public:, protected: は除外していると思われる。

http://svn.apache.org/viewvc/subversion/tags/1.9.3/subversion/libsvn_diff/diff_file.c?view=markup#l1483
http://svn.apache.org/viewvc/subversion/tags/1.9.3/subversion/libsvn_diff/diff_file.c?view=markup#l1856

ということで --diff-cmd/usr/bin/diff を指定して、そちらの -F でラベルがヒットしない正規表現を指定する。

svn diff --diff-cmd /usr/bin/diff -x "-u -F ^[[:alpha:]\$_][^:/]*\(/\|\$\)"
Index: sample.c
===================================================================
--- sample.c    (リビジョン 3)
+++ sample.c    (作業コピー)
@@ -2,7 +2,7 @@ void func1() {
     //
     //
     //
-    printf("bar\n");
+    printf("BAR\n");
 }

 void func2(char *s) {
@@ -12,7 +12,7 @@ void func2(char *s) {
     if (s == NULL) {
         goto ERROR;
     }
-    printf("'%s'\n", s);
+    printf("%s\n", s);
     return;
     //
     //
@@ -21,5 +21,5 @@ void func2(char *s) {
     //
     //
     //
-    printf("Error!\n");
+    printf("error!\n");
 }

Git

以下のように実装されている。

https://github.com/git/git/blob/937978e0f3e750d917768c77665d5f8cfbd802b6/userdiff.c#L127
https://github.com/git/git/blob/21f862b498925194f8f1ebe8203b7a7df756555b/xdiff-interface.c#L251

デフォルトだとラベルが出てしまう。

diff --git a/sample.c b/sample.c
index 6f04375..95b2e05 100644
--- a/sample.c
+++ b/sample.c
@@ -2,7 +2,7 @@ void func1() {
     //
     //
     //
-    printf("bar\n");
+    printf("BAR\n");
 }

 void func2(char *s) {
@@ -12,7 +12,7 @@ void func2(char *s) {
     if (s == NULL) {
         goto ERROR;
     }
-    printf("'%s'\n", s);
+    printf("%s\n", s);
     return;
     //
     //
@@ -21,5 +21,5 @@ ERROR:
     //
     //
     //
-    printf("Error!\n");
+    printf("error!\n");
 }

以下を参考に設定を追加して、もう一度試すと関数名が出る。

https://git-scm.com/docs/gitattributes#_defining_a_custom_hunk_header

.git/info/attributes
*.c diff=cpp
diff --git a/sample.c b/sample.c
index 6f04375..95b2e05 100644
--- a/sample.c
+++ b/sample.c
@@ -2,7 +2,7 @@ void func1() {
     //
     //
     //
-    printf("bar\n");
+    printf("BAR\n");
 }

 void func2(char *s) {
@@ -12,7 +12,7 @@ void func2(char *s) {
     if (s == NULL) {
         goto ERROR;
     }
-    printf("'%s'\n", s);
+    printf("%s\n", s);
     return;
     //
     //
@@ -21,5 +21,5 @@ void func2(char *s) {
     //
     //
     //
-    printf("Error!\n");
+    printf("error!\n");
 }
ayweak
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away