git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Linus Torvalds <torvalds@linux-foundation.org>
To: Junio C Hamano <gitster@pobox.com>
Cc: Git Mailing List <git@vger.kernel.org>
Subject: Fix '--dirstat' with cross-directory renaming
Date: Thu, 28 Aug 2008 16:19:08 -0700 (PDT)	[thread overview]
Message-ID: <alpine.LFD.1.10.0808281608580.3300@nehalem.linux-foundation.org> (raw)


The dirstat code depends on the fact that we always generate diffs with 
the names sorted, since it then just does a single-pass walk-over of the 
sorted list of names and how many changes there were. The sorting means 
that all files are nicely grouped by directory.

That all works fine.

Except when we have rename detection, and suddenly the nicely sorted list 
of pathnames isn't all that sorted at all. And now the single-pass dirstat 
walk gets all confused, and you can get results like this:

  [torvalds@nehalem linux]$ git diff --dirstat=2 -M v2.6.27-rc4..v2.6.27-rc5
     3.0% arch/powerpc/configs/
     6.8% arch/arm/configs/
     2.7% arch/powerpc/configs/
     4.2% arch/arm/configs/
     5.6% arch/powerpc/configs/
     8.4% arch/arm/configs/
     5.5% arch/powerpc/configs/
    23.3% arch/arm/configs/
     8.6% arch/powerpc/configs/
     4.0% arch/
     4.4% drivers/usb/musb/
     4.0% drivers/watchdog/
     7.6% drivers/
     3.5% fs/

The trivial fix is to add a sorting pass, fixing it to:

  [torvalds@nehalem linux]$ git diff --dirstat=2 -M v2.6.27-rc4..v2.6.27-rc5
    43.0% arch/arm/configs/
    25.5% arch/powerpc/configs/
     5.3% arch/
     4.4% drivers/usb/musb/
     4.0% drivers/watchdog/
     7.6% drivers/
     3.5% fs/

Spot the difference. In case anybody wonders: it's because of a ton of 
renames from {include/asm-blackfin => arch/blackfin/include/asm} that just 
totally messed up the file ordering in between arch/arm and arch/powerpc.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 diff.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/diff.c b/diff.c
index 18fa7a7..135dec4 100644
--- a/diff.c
+++ b/diff.c
@@ -1060,6 +1060,13 @@ static long gather_dirstat(FILE *file, struct dirstat_dir *dir, unsigned long ch
 	return this_dir;
 }
 
+static int dirstat_compare(const void *_a, const void *_b)
+{
+	const struct dirstat_file *a = _a;
+	const struct dirstat_file *b = _b;
+	return strcmp(a->name, b->name);
+}
+
 static void show_dirstat(struct diff_options *options)
 {
 	int i;
@@ -1119,6 +1126,7 @@ static void show_dirstat(struct diff_options *options)
 		return;
 
 	/* Show all directories with more than x% of the changes */
+	qsort(dir.files, dir.nr, sizeof(dir.files[0]), dirstat_compare);
 	gather_dirstat(options->file, &dir, changed, "", 0);
 }
 

                 reply	other threads:[~2008-08-28 23:20 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alpine.LFD.1.10.0808281608580.3300@nehalem.linux-foundation.org \
    --to=torvalds@linux-foundation.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).