dest[3] = 0xff & (n >> 030);
}
-static void *zlib_deflate(void *data, unsigned long size,
- int compression_level, unsigned long *compressed_size)
+static void *zlib_deflate_raw(void *data, unsigned long size,
+ int compression_level,
+ unsigned long *compressed_size)
{
git_zstream stream;
unsigned long maxsize;
int result;
memset(&stream, 0, sizeof(stream));
- git_deflate_init(&stream, compression_level);
+ git_deflate_init_raw(&stream, compression_level);
maxsize = git_deflate_bound(&stream, size);
buffer = xmalloc(maxsize);
}
if (buffer && method == 8) {
- deflated = zlib_deflate(buffer, size, args->compression_level,
- &compressed_size);
- if (deflated && compressed_size - 6 < size) {
- /* ZLIB --> raw compressed data (see RFC 1950) */
- /* CMF and FLG ... */
- out = (unsigned char *)deflated + 2;
- compressed_size -= 6; /* ... and ADLER32 */
- } else {
+ out = deflated = zlib_deflate_raw(buffer, size,
+ args->compression_level,
+ &compressed_size);
+ if (!out || compressed_size >= size) {
+ out = buffer;
method = 0;
compressed_size = size;
}
unsigned char compressed[STREAM_BUFFER_SIZE * 2];
memset(&zstream, 0, sizeof(zstream));
- git_deflate_init(&zstream, args->compression_level);
+ git_deflate_init_raw(&zstream, args->compression_level);
compressed_size = 0;
zstream.next_out = compressed;
result = git_deflate(&zstream, 0);
if (result != Z_OK)
die("deflate error (%d)", result);
- out = compressed;
- if (!compressed_size)
- out += 2;
- out_len = zstream.next_out - out;
+ out_len = zstream.next_out - compressed;
if (out_len > 0) {
- write_or_die(1, out, out_len);
+ write_or_die(1, compressed, out_len);
compressed_size += out_len;
zstream.next_out = compressed;
zstream.avail_out = sizeof(compressed);
die("deflate error (%d)", result);
git_deflate_end(&zstream);
- out = compressed;
- if (!compressed_size)
- out += 2;
- out_len = zstream.next_out - out - 4;
- write_or_die(1, out, out_len);
+ out_len = zstream.next_out - compressed;
+ write_or_die(1, compressed, out_len);
compressed_size += out_len;
zip_offset += compressed_size;
void git_deflate_init(git_zstream *, int level);
void git_deflate_init_gzip(git_zstream *, int level);
+void git_deflate_init_raw(git_zstream *, int level);
void git_deflate_end(git_zstream *);
int git_deflate_abort(git_zstream *);
int git_deflate_end_gently(git_zstream *);
#include "diffcore.h"
#include "quote.h"
#include "xdiff-interface.h"
+#include "xdiff/xmacros.h"
#include "log-tree.h"
#include "refs.h"
#include "userdiff.h"
return blob;
}
-static void append_lost(struct sline *sline, int n, const char *line, int len)
+static int match_string_spaces(const char *line1, int len1,
+ const char *line2, int len2,
+ long flags)
+{
+ if (flags & XDF_WHITESPACE_FLAGS) {
+ for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
+ for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
+ }
+
+ if (!(flags & (XDF_IGNORE_WHITESPACE | XDF_IGNORE_WHITESPACE_CHANGE)))
+ return (len1 == len2 && !memcmp(line1, line2, len1));
+
+ while (len1 > 0 && len2 > 0) {
+ len1--;
+ len2--;
+ if (XDL_ISSPACE(line1[len1]) || XDL_ISSPACE(line2[len2])) {
+ if ((flags & XDF_IGNORE_WHITESPACE_CHANGE) &&
+ (!XDL_ISSPACE(line1[len1]) || !XDL_ISSPACE(line2[len2])))
+ return 0;
+
+ for (; len1 > 0 && XDL_ISSPACE(line1[len1]); len1--);
+ for (; len2 > 0 && XDL_ISSPACE(line2[len2]); len2--);
+ }
+ if (line1[len1] != line2[len2])
+ return 0;
+ }
+
+ if (flags & XDF_IGNORE_WHITESPACE) {
+ /* Consume remaining spaces */
+ for (; len1 > 0 && XDL_ISSPACE(line1[len1 - 1]); len1--);
+ for (; len2 > 0 && XDL_ISSPACE(line2[len2 - 1]); len2--);
+ }
+
+ /* We matched full line1 and line2 */
+ if (!len1 && !len2)
+ return 1;
+
+ return 0;
+}
+
+static void append_lost(struct sline *sline, int n, const char *line, int len, long flags)
{
struct lline *lline;
unsigned long this_mask = (1UL<<n);
if (sline->lost_head) {
lline = sline->next_lost;
while (lline) {
- if (lline->len == len &&
- !memcmp(lline->line, line, len)) {
+ if (match_string_spaces(lline->line, lline->len,
+ line, len, flags)) {
lline->parent_map |= this_mask;
sline->next_lost = lline->next;
return;
int n;
struct sline *sline;
struct sline *lost_bucket;
+ long flags;
};
static void consume_line(void *state_, char *line, unsigned long len)
return; /* not in any hunk yet */
switch (line[0]) {
case '-':
- append_lost(state->lost_bucket, state->n, line+1, len-1);
+ append_lost(state->lost_bucket, state->n, line+1, len-1, state->flags);
break;
case '+':
state->sline[state->lno-1].flag |= state->nmask;
struct sline *sline, unsigned int cnt, int n,
int num_parent, int result_deleted,
struct userdiff_driver *textconv,
- const char *path)
+ const char *path, long flags)
{
unsigned int p_lno, lno;
unsigned long nmask = (1UL << n);
parent_file.ptr = grab_blob(parent, mode, &sz, textconv, path);
parent_file.size = sz;
memset(&xpp, 0, sizeof(xpp));
- xpp.flags = 0;
+ xpp.flags = flags;
memset(&xecfg, 0, sizeof(xecfg));
memset(&state, 0, sizeof(state));
+ state.flags = flags;
state.nmask = nmask;
state.sline = sline;
state.lno = 1;
elem->parent[i].mode,
&result_file, sline,
cnt, i, num_parent, result_deleted,
- textconv, elem->path);
+ textconv, elem->path, opt->xdl_opts);
}
show_hunks = make_hunks(sline, cnt, num_parent, dense);
test_description='combined diff'
. ./test-lib.sh
+. "$TEST_DIRECTORY"/diff-lib.sh
setup_helper () {
one=$1 branch=$2 side=$3 &&
grep "^::::::::::::::::::::::::::::::::::::::::[^:]" out
'
+test_expect_success 'setup combined ignore spaces' '
+ git checkout master &&
+ >test &&
+ git add test &&
+ git commit -m initial &&
+
+ tr -d Q <<-\EOF >test &&
+ always coalesce
+ eol space coalesce Q
+ space change coalesce
+ all spa ces coalesce
+ eol spaces Q
+ space change
+ all spa ces
+ EOF
+ git commit -m "test space change" -a &&
+
+ git checkout -b side HEAD^ &&
+ tr -d Q <<-\EOF >test &&
+ always coalesce
+ eol space coalesce
+ space change coalesce
+ all spaces coalesce
+ eol spaces
+ space change
+ all spaces
+ EOF
+ git commit -m "test other space changes" -a &&
+
+ test_must_fail git merge master &&
+ tr -d Q <<-\EOF >test &&
+ eol spaces Q
+ space change
+ all spa ces
+ EOF
+ git commit -m merged -a
+'
+
+test_expect_success 'check combined output (no ignore space)' '
+ git show >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ - eol space coalesce
+ - space change coalesce
+ - all spaces coalesce
+ - eol spaces
+ - space change
+ - all spaces
+ -eol space coalesce Q
+ -space change coalesce
+ -all spa ces coalesce
+ + eol spaces Q
+ + space change
+ + all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore space at eol)' '
+ git show --ignore-space-at-eol >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ --eol space coalesce
+ - space change coalesce
+ - all spaces coalesce
+ -space change coalesce
+ -all spa ces coalesce
+ eol spaces Q
+ - space change
+ - all spaces
+ + space change
+ + all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore space change)' '
+ git show -b >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ --eol space coalesce
+ --space change coalesce
+ - all spaces coalesce
+ -all spa ces coalesce
+ eol spaces Q
+ space change
+ - all spaces
+ + all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
+test_expect_success 'check combined output (ignore all spaces)' '
+ git show -w >actual.tmp &&
+ sed -e "1,/^@@@/d" < actual.tmp >actual &&
+ tr -d Q <<-\EOF >expected &&
+ --always coalesce
+ --eol space coalesce
+ --space change coalesce
+ --all spaces coalesce
+ eol spaces Q
+ space change
+ all spa ces
+ EOF
+ compare_diff_patch expected actual
+'
+
test_done
strm->z.msg ? strm->z.msg : "no message");
}
-void git_deflate_init_gzip(git_zstream *strm, int level)
+static void do_git_deflate_init(git_zstream *strm, int level, int windowBits)
{
- /*
- * Use default 15 bits, +16 is to generate gzip header/trailer
- * instead of the zlib wrapper.
- */
- const int windowBits = 15 + 16;
int status;
zlib_pre_call(strm);
strm->z.msg ? strm->z.msg : "no message");
}
+void git_deflate_init_gzip(git_zstream *strm, int level)
+{
+ /*
+ * Use default 15 bits, +16 is to generate gzip header/trailer
+ * instead of the zlib wrapper.
+ */
+ return do_git_deflate_init(strm, level, 15 + 16);
+}
+
+void git_deflate_init_raw(git_zstream *strm, int level)
+{
+ /*
+ * Use default 15 bits, negate the value to get raw compressed
+ * data without zlib header and trailer.
+ */
+ return do_git_deflate_init(strm, level, -15);
+}
+
int git_deflate_abort(git_zstream *strm)
{
int status;