Merge branch 'jk/pager-swap'
[gitweb.git] / diff.c
diff --git a/diff.c b/diff.c
index a07812c5c75f1f579295df392efed27f6a5f6fc1..fe43407b78150fd7fffe0d1fdff3456346ea27a6 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -20,6 +20,7 @@
 
 static int diff_detect_rename_default;
 static int diff_rename_limit_default = 200;
+static int diff_suppress_blank_empty;
 int diff_use_color_default = -1;
 static const char *external_diff_cmd_cfg;
 int diff_auto_refresh_index = 1;
@@ -131,10 +132,6 @@ static int parse_funcname_pattern(const char *var, const char *ep, const char *v
  */
 int git_diff_ui_config(const char *var, const char *value, void *cb)
 {
-       if (!strcmp(var, "diff.renamelimit")) {
-               diff_rename_limit_default = git_config_int(var, value);
-               return 0;
-       }
        if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff")) {
                diff_use_color_default = git_config_colorbool(var, value, -1);
                return 0;
@@ -167,6 +164,11 @@ int git_diff_ui_config(const char *var, const char *value, void *cb)
 
 int git_diff_basic_config(const char *var, const char *value, void *cb)
 {
+       if (!strcmp(var, "diff.renamelimit")) {
+               diff_rename_limit_default = git_config_int(var, value);
+               return 0;
+       }
+
        if (!prefixcmp(var, "diff.color.") || !prefixcmp(var, "color.diff.")) {
                int slot = parse_diff_color_slot(var, 11);
                if (!value)
@@ -175,6 +177,12 @@ int git_diff_basic_config(const char *var, const char *value, void *cb)
                return 0;
        }
 
+       /* like GNU diff's --suppress-blank-empty option  */
+       if (!strcmp(var, "diff.suppress-blank-empty")) {
+               diff_suppress_blank_empty = git_config_bool(var, value);
+               return 0;
+       }
+
        if (!prefixcmp(var, "diff.")) {
                const char *ep = strrchr(var, '.');
                if (ep != var + 4) {
@@ -579,6 +587,12 @@ static void fn_out_consume(void *priv, char *line, unsigned long len)
                ecbdata->label_path[0] = ecbdata->label_path[1] = NULL;
        }
 
+       if (diff_suppress_blank_empty
+           && len == 2 && line[0] == ' ' && line[1] == '\n') {
+               line[0] = '\n';
+               len = 1;
+       }
+
        /* This is not really necessary for now because
         * this codepath only deals with two-way diffs.
         */
@@ -1380,7 +1394,15 @@ static struct builtin_funcname_pattern {
                        "^[     ]*\\(\\([       ]*"
                        "[A-Za-z_][A-Za-z_0-9]*\\)\\{2,\\}"
                        "[      ]*([^;]*\\)$" },
-       { "tex", "^\\(\\\\\\(sub\\)*section{.*\\)$" },
+       { "pascal", "^\\(\\(procedure\\|function\\|constructor\\|"
+                       "destructor\\|interface\\|implementation\\|"
+                       "initialization\\|finalization\\)[ \t]*.*\\)$"
+                       "\\|"
+                       "^\\(.*=[ \t]*\\(class\\|record\\).*\\)$"
+                       },
+       { "bibtex", "\\(@[a-zA-Z]\\{1,\\}[ \t]*{\\{0,1\\}[ \t]*[^ \t\"@',\\#}{~%]*\\).*$" },
+       { "tex", "^\\(\\\\\\(\\(sub\\)*section\\|chapter\\|part\\)\\*\\{0,1\\}{.*\\)$" },
+       { "ruby", "^\\s*\\(\\(class\\|module\\|def\\)\\s.*\\)$" },
 };
 
 static const char *diff_funcname_pattern(struct diff_filespec *one)
@@ -1623,7 +1645,8 @@ static void builtin_checkdiff(const char *name_a, const char *name_b,
                ecb.priv = &data;
                xdi_diff(&mf1, &mf2, &xpp, &xecfg, &ecb);
 
-               if (data.trailing_blanks_start) {
+               if ((data.ws_rule & WS_TRAILING_SPACE) &&
+                   data.trailing_blanks_start) {
                        fprintf(o->file, "%s:%d: ends with blank lines.\n",
                                data.filename, data.trailing_blanks_start);
                        data.status = 1; /* report errors */
@@ -3223,11 +3246,10 @@ void diff_flush(struct diff_options *options)
 
        if (output_format & DIFF_FORMAT_PATCH) {
                if (separator) {
+                       putc(options->line_termination, options->file);
                        if (options->stat_sep) {
                                /* attach patch instead of inline */
                                fputs(options->stat_sep, options->file);
-                       } else {
-                               putc(options->line_termination, options->file);
                        }
                }