git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH] git-show: grok blobs, trees and tags, too

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Dec 14, 2006, 10:31 UTC
Message-ID
<Pine.LNX.4.63.0612141129320.3635@wbgn013.biozentrum.uni-wuerzburg.de>

Since git-show is pure Porcelain, it is the ideal candidate to pretty print other things than commits, too.

Signed-off-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
---
 Documentation/git-show.txt |   40 ++++++++++++++++++---
 builtin-log.c              |   82 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 114 insertions(+), 8 deletions(-)
diff --git a/Documentation/git-show.txt b/Documentation/git-show.txt
index 4c880a8..1d9d781 100644
--- a/Documentation/git-show.txt
+++ b/Documentation/git-show.txt
@@ -3,20 +3,27 @@ git-show(1)
 
 NAME
 ----
-git-show - Show one commit with difference it introduces
+git-show - Show blobs, trees, tags and commits with difference they introduce
 
 
 SYNOPSIS
 --------
-'git-show' <option>...
+'git-show' [options] <object>...
 
 DESCRIPTION
 -----------
-Shows commit log and textual diff for a single commit.  The
-command internally invokes 'git-rev-list' piped to
-'git-diff-tree', and takes command line options for both of
-these commands. It also presents the merge commit in a special
-format as produced by 'git-diff-tree --cc'.
+Shows one or more objects.
+
+For commits it shows the log message and textual diff. It also
+presents the merge commit in a special format as produced by
+'git-diff-tree --cc'.
+
+For tags, it shows the tag message and the referenced objects.
+
+For trees, it shows the names (equivalent to gitlink:git-ls-tree[1]
+with \--name-only).
+
+For plain blobs, it shows the plain contents.
 
 This manual page describes only the most frequently used options.
 
@@ -28,6 +35,25 @@ OPTIONS
 
 include::pretty-formats.txt[]
 
+
+EXAMPLES
+--------
+
+git show v1.0.0::
+	Shows the tag `v1.0.0`.
+
+git show v1.0.0^{tree}::
+	Shows the tree pointed to by the tag `v1.0.0`.
+
+git show next~10:Documentation/README
+	Shows the contents of the file `Documentation/README` as
+	they were current in the 10th last commit of the branch
+	`next`.
+
+git show master:Makefile master:t/Makefile
+	Concatenates the contents of said Makefiles in the head
+	of the branch `master`.
+
 Author
 ------
 Written by Linus Torvalds <torvalds@osdl.org> and
diff --git a/builtin-log.c b/builtin-log.c
index 6821a08..17014f7 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -10,6 +10,7 @@
 #include "revision.h"
 #include "log-tree.h"
 #include "builtin.h"
+#include "tag.h"
 #include <time.h>
 #include <sys/time.h>
 
@@ -71,9 +72,43 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix)
 	return cmd_log_walk(&rev);
 }
 
+static int show_object(const unsigned char *sha1, int suppress_header)
+{
+	unsigned long size;
+	char type[20];
+	char *buf = read_sha1_file(sha1, type, &size);
+	int offset = 0;
+
+	if (!buf)
+		return error("Could not read object %s", sha1_to_hex(sha1));
+
+	if (suppress_header)
+		while (offset < size && buf[offset++] != '\n') {
+			int new_offset = offset;
+			while (new_offset < size && buf[new_offset++] != '\n')
+				; /* do nothing */
+			offset = new_offset;
+		}
+
+	if (offset < size)
+		fwrite(buf + offset, size - offset, 1, stdout);
+	free(buf);
+	return 0;
+}
+
+static int show_tree_object(const unsigned char *sha1,
+		const char *base, int baselen,
+		const char *pathname, unsigned mode, int stage)
+{
+	printf("%s%s\n", pathname, S_ISDIR(mode) ? "/" : "");
+	return 0;
+}
+
 int cmd_show(int argc, const char **argv, const char *prefix)
 {
 	struct rev_info rev;
+	struct object_array_entry *objects;
+	int i, count, ret = 0;
 
 	git_config(git_log_config);
 	init_revisions(&rev, prefix);
@@ -85,7 +120,52 @@ int cmd_show(int argc, const char **argv, const char *prefix)
 	rev.ignore_merges = 0;
 	rev.no_walk = 1;
 	cmd_log_init(argc, argv, prefix, &rev);
-	return cmd_log_walk(&rev);
+
+	count = rev.pending.nr;
+	objects = rev.pending.objects;
+	for (i = 0; i < count && !ret; i++) {
+		struct object *o = objects[i].item;
+		const char *name = objects[i].name;
+		switch (o->type) {
+		case OBJ_BLOB:
+			ret = show_object(o->sha1, 0);
+			break;
+		case OBJ_TAG: {
+			struct tag *t = (struct tag *)o;
+
+			printf("%stag %s%s\n\n",
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_COMMIT),
+					t->tag,
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_RESET));
+			ret = show_object(o->sha1, 1);
+			objects[i].item = (struct object *)t->tagged;
+			i--;
+			break;
+		}
+		case OBJ_TREE:
+			printf("%stree %s%s\n\n",
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_COMMIT),
+					name,
+					diff_get_color(rev.diffopt.color_diff,
+						DIFF_RESET));
+			read_tree_recursive((struct tree *)o, "", 0, 0, NULL,
+					show_tree_object);
+			break;
+		case OBJ_COMMIT:
+			rev.pending.nr = rev.pending.alloc = 0;
+			rev.pending.objects = NULL;
+			add_object_array(o, name, &rev.pending);
+			ret = cmd_log_walk(&rev);
+			break;
+		default:
+			ret = error("Unknown type: %d", o->type);
+		}
+	}
+	free(objects);
+	return ret;
 }
 
Next: Shawn Pearce
Message 1 of 9 in “git-show: grok blobs, trees and tags, too”
  1. git-show: grok blobs, trees and tags, tooJohannes Schindelin, Dec 14, 2006
  2. Shawn PearceDec 14, 2006
  3. Johannes SchindelinDec 14, 2006
  4. Junio C HamanoDec 14, 2006
  5. Johannes SchindelinDec 14, 2006
  6. Jakub NarebskiDec 15, 2006
  7. Johannes SchindelinDec 15, 2006
  8. Santi BéjarDec 15, 2006
  9. Johannes SchindelinDec 15, 2006

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.