@@ -4081,6 +4081,7 @@ int diff_populate_filespec(struct repository *r,
{
int size_only = options ? options->check_size_only : 0;
int check_binary = options ? options->check_binary : 0;
+ int ignore_whitespace = options ? options->ignore_whitespace : 0;
int err = 0;
int conv_flags = global_conv_flags_eol;
/*
@@ -4090,6 +4091,9 @@ int diff_populate_filespec(struct repository *r,
if (conv_flags & CONV_EOL_RNDTRP_DIE)
conv_flags = CONV_EOL_RNDTRP_WARN;
+ if (ignore_whitespace)
+ s->ignore_whitespace = 1;
+
if (!DIFF_FILE_VALID(s))
die("internal error: asking to populate invalid file.");
if (S_ISDIR(s->mode))
@@ -130,6 +130,7 @@ static struct spanhash_top *hash_chars(struct repository *r,
unsigned char *buf = one->data;
unsigned int sz = one->size;
int is_text = !diff_filespec_is_binary(r, one);
+ int ignore_whitespace = one->ignore_whitespace;
i = INITIAL_HASH_SIZE;
hash = xmalloc(st_add(sizeof(*hash),
@@ -149,6 +150,19 @@ static struct spanhash_top *hash_chars(struct repository *r,
if (is_text && c == '\r' && sz && *buf == '\n')
continue;
+ if (is_text && ignore_whitespace && isspace(c)) {
+ if (sz) {
+ char next = *buf;
+ if ( c == '\n' && next == '\n')
+ continue;
+ else if ( c != '\n' && isspace(next))
+ continue;
+ }
+ if ( c != '\n')
+ /* Normalize whitespace to space*/
+ c = ' ';
+ }
+
accum1 = (accum1 << 7) ^ (accum2 >> 25);
accum2 = (accum2 << 7) ^ (old_1 >> 25);
accum1 += c;
@@ -14,6 +14,7 @@
#include "string-list.h"
#include "strmap.h"
#include "trace2.h"
+#include "xdiff-interface.h"
/* Table of rename/copy destinations */
@@ -950,6 +951,10 @@ static int find_basename_matches(struct diff_options *options,
.info = info
};
+ dpf_options.ignore_whitespace =
+ DIFF_XDL_TST(options, IGNORE_WHITESPACE_CHANGE)
+ || DIFF_XDL_TST(options, IGNORE_WHITESPACE);
+
/*
* Create maps of basename -> fullname(s) for remaining sources and
* dests.
@@ -1402,6 +1407,10 @@ void diffcore_rename_extended(struct diff_options *options,
.repo = options->repo
};
+ dpf_options.ignore_whitespace =
+ DIFF_XDL_TST(options, IGNORE_WHITESPACE_CHANGE)
+ || DIFF_XDL_TST(options, IGNORE_WHITESPACE);
+
trace2_region_enter("diff", "setup", options->repo);
info.setup = 0;
assert(!dir_rename_count || strmap_empty(dir_rename_count));
@@ -61,6 +61,7 @@ struct diff_filespec {
unsigned has_more_entries : 1; /* only appear in combined diff */
/* data should be considered "binary"; -1 means "don't know yet" */
signed int is_binary : 2;
+ unsigned ignore_whitespace : 1;
struct userdiff_driver *driver;
};
@@ -78,6 +79,7 @@ void diff_queued_diff_prefetch(void *repository);
struct diff_populate_filespec_options {
unsigned check_size_only : 1;
unsigned check_binary : 1;
+ unsigned ignore_whitespace : 1;
/*
* If an object is missing, diff_populate_filespec() will invoke this
@@ -1894,6 +1894,7 @@ static struct diff_queue_struct *get_diffpairs(struct merge_options *opt,
repo_diff_setup(opt->repo, &opts);
opts.flags.recursive = 1;
opts.flags.rename_empty = 0;
+ opts.xdl_opts = opt->xdl_opts;
opts.detect_rename = merge_detect_rename(opt);
/*
* We do not have logic to handle the detection of copies. In