diff: Fix rename pretty-print when suffix and prefix overlap
[gitweb.git] / diff.c
diff --git a/diff.c b/diff.c
index 8f4815bfd7d798f2a99131cd2e79155e933c7876..e1d82c9672599072fb946d157d54bd72aa0fa7db 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1177,7 +1177,16 @@ static char *pprint_rename(const char *a, const char *b)
        old = a + len_a;
        new = b + len_b;
        sfx_length = 0;
-       while (a <= old && b <= new && *old == *new) {
+       /*
+        * Note:
+        * if pfx_length is 0, old/new will never reach a - 1 because it
+        * would mean the whole string is common suffix. But then, the
+        * whole string would also be a common prefix, and we would not
+        * have pfx_length equals 0.
+        */
+       while (a + pfx_length - 1 <= old &&
+              b + pfx_length - 1 <= new &&
+              *old == *new) {
                if (*old == '/')
                        sfx_length = len_a - (old - a);
                old--;
@@ -1839,20 +1848,20 @@ static unsigned char *deflate_it(char *data,
 {
        int bound;
        unsigned char *deflated;
-       z_stream stream;
+       git_zstream stream;
 
        memset(&stream, 0, sizeof(stream));
-       deflateInit(&stream, zlib_compression_level);
-       bound = deflateBound(&stream, size);
+       git_deflate_init(&stream, zlib_compression_level);
+       bound = git_deflate_bound(&stream, size);
        deflated = xmalloc(bound);
        stream.next_out = deflated;
        stream.avail_out = bound;
 
        stream.next_in = (unsigned char *)data;
        stream.avail_in = size;
-       while (deflate(&stream, Z_FINISH) == Z_OK)
+       while (git_deflate(&stream, Z_FINISH) == Z_OK)
                ; /* nothing */
-       deflateEnd(&stream);
+       git_deflate_end(&stream);
        *result_size = stream.total_out;
        return deflated;
 }
@@ -1984,19 +1993,7 @@ struct userdiff_driver *get_textconv(struct diff_filespec *one)
                return NULL;
 
        diff_filespec_load_driver(one);
-       if (!one->driver->textconv)
-               return NULL;
-
-       if (one->driver->textconv_want_cache && !one->driver->textconv_cache) {
-               struct notes_cache *c = xmalloc(sizeof(*c));
-               struct strbuf name = STRBUF_INIT;
-
-               strbuf_addf(&name, "textconv/%s", one->driver->name);
-               notes_cache_init(c, name.buf, one->driver->textconv);
-               one->driver->textconv_cache = c;
-       }
-
-       return one->driver;
+       return userdiff_get_textconv(one->driver);
 }
 
 static void builtin_diff(const char *name_a,
@@ -4456,6 +4453,13 @@ int diff_result_code(struct diff_options *opt, int status)
        return result;
 }
 
+int diff_can_quit_early(struct diff_options *opt)
+{
+       return (DIFF_OPT_TST(opt, QUICK) &&
+               !opt->filter &&
+               DIFF_OPT_TST(opt, HAS_CHANGES));
+}
+
 /*
  * Shall changes to this submodule be ignored?
  *