[PATCH v5 5/6] last-modified: support --extended format

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

 



On many forges when they display a tree view, they show which commit
last modified each entry of the tree. The command git-last-modified(1)
was introduced to feed the data for this view. But it only returned the
commit OID and the path.

Add option --extended to git-last-modified(1). In combination with the
path and the commit OID, it shows the raw commit data which can be used
directly to feed the tree view on a forge.

Signed-off-by: Toon Claes <toon@xxxxxxxxx>
---
 Documentation/git-last-modified.adoc | 46 ++++++++++++++++++++++++++++
 builtin/last-modified.c              | 46 +++++++++++++++++++++++-----
 t/t8020-last-modified.sh             | 22 +++++++++++++
 3 files changed, 107 insertions(+), 7 deletions(-)

diff --git a/Documentation/git-last-modified.adoc b/Documentation/git-last-modified.adoc
index 89138ebeb7..af028c7b74 100644
--- a/Documentation/git-last-modified.adoc
+++ b/Documentation/git-last-modified.adoc
@@ -27,6 +27,14 @@ OPTIONS
 -t::
 	Show tree entry itself as well as subtrees.  Implies `-r`.

+-z::
+
+	Instead of separating output entries with newlines, use a NUL byte to
+	delimit them. See 'OUTPUT' for more details.
+
+--extended::
+	Show output in extended format. See 'OUTPUT' below.
+
 <revision-range>::
 	Only traverse commits in the specified revision range. When no
 	`<revision-range>` is specified, it defaults to `HEAD` (i.e. the whole
@@ -39,6 +47,44 @@ OPTIONS
 	Without an optional path parameter, all files and subdirectories
 	in path traversal the are included in the output.

+OUTPUT
+------
+
+The default format prints for each path:
+
+	<oid> TAB <path> LF
+
+When the commit is at boundary, it's prefixed with a caret `^`.
+
+Or when option `-z` is given:
+
+	<oid> TAB <path> NUL
+
+When `--extended` is provided, the output will be in the format:
+
+	path SP <path> LF
+	commit SP <oid> LF
+	tree SP <tree> LF
+	parent SP <parent> LF
+	author SP <author> LF
+	    <message>
+
+Each line of the commit message is indented with four spaces.
+
+Unless together with `--extended` option `-z` is given, then the output is:
+
+	path SP <path> NUL
+	commit SP <oid> LF
+	tree SP <tree> LF
+	parent SP <parent> LF
+	author SP <author> LF
+	<message>
+
+In this situation the commit message is not indented.
+
+A path containing SP or special characters is enclosed in double-quotes in the C
+style as needed, unless option `-z` is provided.
+
 SEE ALSO
 --------
 linkgit:git-blame[1],
diff --git a/builtin/last-modified.c b/builtin/last-modified.c
index 466df04fba..71c66e8782 100644
--- a/builtin/last-modified.c
+++ b/builtin/last-modified.c
@@ -12,6 +12,7 @@
 #include "object-name.h"
 #include "object.h"
 #include "parse-options.h"
+#include "pretty.h"
 #include "quote.h"
 #include "repository.h"
 #include "revision.h"
@@ -39,6 +40,7 @@ struct last_modified {
 	struct hashmap paths;
 	struct rev_info rev;
 	int recursive, tree_in_recursive;
+	int extended;
 };

 static void last_modified_release(struct last_modified *lm)
@@ -244,14 +246,42 @@ static void show_entry(const char *path, const struct commit *commit, void *d)
 {
 	struct last_modified *lm = d;

-	if (commit->object.flags & BOUNDARY)
-		putchar('^');
-	printf("%s\t", oid_to_hex(&commit->object.oid));
+	if (lm->extended) {
+		struct strbuf buf = STRBUF_INIT;
+		struct pretty_print_context pp = { 0 };

-	if (lm->rev.diffopt.line_termination)
-		write_name_quoted(path, stdout, '\n');
-	else
-		printf("%s%c", path, '\0');
+		pp.abbrev = lm->rev.abbrev;
+		pp.date_mode = lm->rev.date_mode;
+		pp.date_mode_explicit = lm->rev.date_mode_explicit;
+		pp.fmt = CMIT_FMT_RAW;
+		pp.color = lm->rev.diffopt.use_color;
+		pp.rev = &lm->rev;
+		pp.no_indent = !lm->rev.diffopt.line_termination;
+
+		pretty_print_commit(&pp, commit, &buf);
+
+		printf("path ");
+		if (lm->rev.diffopt.line_termination)
+			write_name_quoted(path, stdout, '\n');
+		else
+			printf("%s%c", path, '\0');
+
+		printf("commit %s%s\n",
+		       (commit->object.flags & BOUNDARY) ? "^" : "",
+		       oid_to_hex(&commit->object.oid));
+		printf("%s%c", buf.buf, lm->rev.diffopt.line_termination);
+
+		strbuf_release(&buf);
+	} else {
+		printf("%s%s\t",
+		       (commit->object.flags & BOUNDARY) ? "^" : "",
+		       oid_to_hex(&commit->object.oid));
+
+		if (lm->rev.diffopt.line_termination)
+			write_name_quoted(path, stdout, '\n');
+		else
+			printf("%s%c", path, '\0');
+	}

 	fflush(stdout);
 }
@@ -306,6 +336,8 @@ int cmd_last_modified(int argc, const char **argv, const char *prefix,
 			 N_("recurse into subtrees")),
 		OPT_BOOL('t', "tree-in-recursive", &lm.tree_in_recursive,
 			 N_("recurse into subtrees and include the tree entries too")),
+		OPT_BOOL(0, "extended", &lm.extended,
+			 N_("extended format will include the commit message in the output")),
 		OPT_END()
 	};

diff --git a/t/t8020-last-modified.sh b/t/t8020-last-modified.sh
index 05c113a1f8..008ea708ab 100755
--- a/t/t8020-last-modified.sh
+++ b/t/t8020-last-modified.sh
@@ -48,6 +48,28 @@ test_expect_success 'last-modified non-recursive' '
 	EOF
 '

+test_expect_success 'last-modified extended output' '
+	check_last_modified --extended <<-\EOF
+	path a
+	commit 3
+	tree e9a947598482012e54c9c5d3635d5b526b43a6a4
+	parent 2
+	author A U Thor <author@xxxxxxxxxxx> 1112912113 -0700
+	committer C O Mitter <committer@xxxxxxxxxxx> 1112912113 -0700
+
+	    3
+
+	path file
+	commit 1
+	tree f27c6ae26adb8396d3861976ba268f87ad8afa0b
+	author A U Thor <author@xxxxxxxxxxx> 1112911993 -0700
+	committer C O Mitter <committer@xxxxxxxxxxx> 1112911993 -0700
+
+	    1
+
+	EOF
+'
+
 test_expect_success 'last-modified recursive' '
 	check_last_modified -r <<-\EOF
 	3 a/b/file
--
2.50.1.327.g047016eb4a




[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]

  Powered by Linux