diff.c: flush stdout before printing rename warnings
[gitweb.git] / diff.c
diff --git a/diff.c b/diff.c
index 7a4309397cb7fd6819d6f643b259c2bc3abe202f..bfd1bd2410f9d0b920fda58cb0caae33a94111e7 100644 (file)
--- a/diff.c
+++ b/diff.c
@@ -1954,7 +1954,7 @@ static void show_dirstat(struct diff_options *options)
                if (DIFF_FILE_VALID(p->one) && DIFF_FILE_VALID(p->two)) {
                        diff_populate_filespec(p->one, 0);
                        diff_populate_filespec(p->two, 0);
-                       diffcore_count_changes(p->one, p->two, NULL, NULL, 0,
+                       diffcore_count_changes(p->one, p->two, NULL, NULL,
                                               &copied, &added);
                        diff_free_filespec_data(p->one);
                        diff_free_filespec_data(p->two);
@@ -3076,7 +3076,7 @@ static void fill_metainfo(struct strbuf *msg,
                }
                strbuf_addf(msg, "%s%sindex %s..", line_prefix, set,
                            find_unique_abbrev(one->oid.hash, abbrev));
-               strbuf_addstr(msg, find_unique_abbrev(two->oid.hash, abbrev));
+               strbuf_add_unique_abbrev(msg, two->oid.hash, abbrev);
                if (one->mode == two->mode)
                        strbuf_addf(msg, " %06o", one->mode);
                strbuf_addf(msg, "%s\n", reset);
@@ -4089,7 +4089,8 @@ void diff_free_filepair(struct diff_filepair *p)
        free(p);
 }
 
-/* This is different from find_unique_abbrev() in that
+/*
+ * This is different from find_unique_abbrev() in that
  * it stuffs the result with dots for alignment.
  */
 const char *diff_unique_abbrev(const unsigned char *sha1, int len)
@@ -4101,6 +4102,26 @@ const char *diff_unique_abbrev(const unsigned char *sha1, int len)
 
        abbrev = find_unique_abbrev(sha1, len);
        abblen = strlen(abbrev);
+
+       /*
+        * In well-behaved cases, where the abbbreviated result is the
+        * same as the requested length, append three dots after the
+        * abbreviation (hence the whole logic is limited to the case
+        * where abblen < 37); when the actual abbreviated result is a
+        * bit longer than the requested length, we reduce the number
+        * of dots so that they match the well-behaved ones.  However,
+        * if the actual abbreviation is longer than the requested
+        * length by more than three, we give up on aligning, and add
+        * three dots anyway, to indicate that the output is not the
+        * full object name.  Yes, this may be suboptimal, but this
+        * appears only in "diff --raw --abbrev" output and it is not
+        * worth the effort to change it now.  Note that this would
+        * likely to work fine when the automatic sizing of default
+        * abbreviation length is used--we would be fed -1 in "len" in
+        * that case, and will end up always appending three-dots, but
+        * the automatic sizing is supposed to give abblen that ensures
+        * uniqueness across all objects (statistically speaking).
+        */
        if (abblen < 37) {
                static char hex[41];
                if (len < abblen && abblen <= len + 2)
@@ -4602,6 +4623,7 @@ static const char rename_limit_advice[] =
 
 void diff_warn_rename_limit(const char *varname, int needed, int degraded_cc)
 {
+       fflush(stdout);
        if (degraded_cc)
                warning(degrade_cc_to_c_warning);
        else if (needed)