[PATCH] Add "--summary" option to git diff.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Remove the need to pipe git diff through git apply to
get the extended headers summary.

Signed-off-by: Sean Estabrooks <seanlkml@xxxxxxxxxxxx>

---

e5d981eef0203c399d8b1890be94add525eee969
 Documentation/diff-options.txt |    4 ++
 diff.c                         |   88 ++++++++++++++++++++++++++++++++++++++++
 diff.h                         |    3 +
 3 files changed, 93 insertions(+), 2 deletions(-)

e5d981eef0203c399d8b1890be94add525eee969
diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt
index c183dc9..f523ec2 100644
--- a/Documentation/diff-options.txt
+++ b/Documentation/diff-options.txt
@@ -10,6 +10,10 @@
 --stat::
 	Generate a diffstat instead of a patch.
 
+--summary::
+	Output a condensed summary of extended header information
+	such as creations, renames and mode changes.
+
 --patch-with-stat::
 	Generate patch and prepend its diffstat.
 
diff --git a/diff.c b/diff.c
index 7a7b839..00b1044 100644
--- a/diff.c
+++ b/diff.c
@@ -1233,6 +1233,8 @@ int diff_opt_parse(struct diff_options *
 	}
 	else if (!strcmp(arg, "--stat"))
 		options->output_format = DIFF_FORMAT_DIFFSTAT;
+	else if (!strcmp(arg, "--summary"))
+		options->summary = 1;
 	else if (!strcmp(arg, "--patch-with-stat")) {
 		options->output_format = DIFF_FORMAT_PATCH;
 		options->with_stat = 1;
@@ -1703,6 +1705,85 @@ static void flush_one_pair(struct diff_f
 	}
 }
 
+static void show_file_mode_name(const char *newdelete, struct diff_filespec *fs)
+{
+	if (fs->mode)
+		printf(" %s mode %06o %s\n", newdelete, fs->mode, fs->path);
+	else
+		printf(" %s %s\n", newdelete, fs->path);
+}
+
+
+static void show_mode_change(struct diff_filepair *p, int show_name)
+{
+	if (p->one->mode && p->two->mode && p->one->mode != p->two->mode) {
+		if (show_name)
+			printf(" mode change %06o => %06o %s\n",
+			       p->one->mode, p->two->mode, p->two->path);
+		else
+			printf(" mode change %06o => %06o\n",
+			       p->one->mode, p->two->mode);
+	}
+}
+
+static void show_rename_copy(const char *renamecopy, struct diff_filepair *p)
+{
+	const char *old, *new;
+
+	/* Find common prefix */
+	old = p->one->path;
+	new = p->two->path;
+	while (1) {
+		const char *slash_old, *slash_new;
+		slash_old = strchr(old, '/');
+		slash_new = strchr(new, '/');
+		if (!slash_old ||
+		    !slash_new ||
+		    slash_old - old != slash_new - new ||
+		    memcmp(old, new, slash_new - new))
+			break;
+		old = slash_old + 1;
+		new = slash_new + 1;
+	}
+	/* p->one->path thru old is the common prefix, and old and new
+	 * through the end of names are renames
+	 */
+	if (old != p->one->path)
+		printf(" %s %.*s{%s => %s} (%d%%)\n", renamecopy,
+		       (int)(old - p->one->path), p->one->path,
+		       old, new, (int)(0.5 + p->score * 100.0/MAX_SCORE));
+	else
+		printf(" %s %s => %s (%d%%)\n", renamecopy,
+		       p->one->path, p->two->path,
+		       (int)(0.5 + p->score * 100.0/MAX_SCORE));
+	show_mode_change(p, 0);
+}
+
+static void diff_summary(struct diff_filepair *p)
+{
+	switch(p->status) {
+	case DIFF_STATUS_DELETED:
+		show_file_mode_name("delete", p->one);
+		break;
+	case DIFF_STATUS_ADDED:
+		show_file_mode_name("create", p->two);
+		break;
+	case DIFF_STATUS_COPIED:
+		show_rename_copy("copy", p);
+		break;
+	case DIFF_STATUS_RENAMED:
+		show_rename_copy("rename", p);
+		break;
+	default:
+		if (p->score) {
+			printf(" rewrite %s (%d%%)\n", p->two->path,
+				(int)(0.5 + p->score * 100.0/MAX_SCORE));
+			show_mode_change(p, 0);
+		} else	show_mode_change(p, 1);
+		break;
+	}
+}
+
 void diff_flush(struct diff_options *options)
 {
 	struct diff_queue_struct *q = &diff_queued_diff;
@@ -1736,7 +1817,6 @@ void diff_flush(struct diff_options *opt
 	for (i = 0; i < q->nr; i++) {
 		struct diff_filepair *p = q->queue[i];
 		flush_one_pair(p, diff_output_format, options, diffstat);
-		diff_free_filepair(p);
 	}
 
 	if (diffstat) {
@@ -1744,6 +1824,12 @@ void diff_flush(struct diff_options *opt
 		free(diffstat);
 	}
 
+	for (i = 0; i < q->nr; i++) {
+		if (options->summary)
+			diff_summary(q->queue[i]);
+		diff_free_filepair(q->queue[i]);
+	}
+
 	free(q->queue);
 	q->queue = NULL;
 	q->nr = q->alloc = 0;
diff --git a/diff.h b/diff.h
index d052608..70077c6 100644
--- a/diff.h
+++ b/diff.h
@@ -31,7 +31,8 @@ struct diff_options {
 		 binary:1,
 		 full_index:1,
 		 silent_on_remove:1,
-		 find_copies_harder:1;
+		 find_copies_harder:1,
+		 summary:1;
 	int break_opt;
 	int detect_rename;
 	int line_termination;
-- 
1.3.2.gab2a

-
: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]