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

[PATCH 2/2] git-show: use pathattr to run "display"

From
Junio C Hamano <junkio@cox.net>
Date
Mar 1, 2007, 07:18 UTC
Message-ID
<7vodndxwia.fsf@assigned-by-dhcp.cox.net>

This is a bit of detour, to demonstrate a possible use of pathattr infrastructure. With this,

	$ git show v1.4.4:t/test4012.png
would hopefully do what you would expect.
Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 * I was planning to write the config reader as a follow-up, but
   got sidetracked.  After all, doing something whose effect is
   visible is more fun.
 builtin-log.c |   31 ++++++++++++++++++++++++-------
 pathattr.c    |    8 ++++++++
 pathattr.h    |    3 +++
 3 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/builtin-log.c b/builtin-log.c
index 1c9f7d0..519fab2 100644
--- a/builtin-log.c
+++ b/builtin-log.c
@@ -12,6 +12,7 @@
 #include "builtin.h"
 #include "tag.h"
 #include "reflog-walk.h"
+#include "pathattr.h"
 
 static int default_show_root = 1;
 
@@ -86,26 +87,42 @@ 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)
+static void to_stdout(const unsigned char *blobdata, unsigned long size)
+{
+	fwrite(blobdata, size, 1, stdout);
+}
+
+static int show_object(const unsigned char *sha1, const char *path, int nohead)
 {
 	unsigned long size;
 	enum object_type type;
-	char *buf = read_sha1_file(sha1, &type, &size);
+	unsigned char *buf = read_sha1_file(sha1, &type, &size);
 	int offset = 0;
+	pretty_fn pretty = to_stdout;
 
 	if (!buf)
 		return error("Could not read object %s", sha1_to_hex(sha1));
 
-	if (suppress_header)
+	if (nohead) {
 		while (offset < size && buf[offset++] != '\n') {
 			int new_offset = offset;
 			while (new_offset < size && buf[new_offset++] != '\n')
 				; /* do nothing */
 			offset = new_offset;
 		}
+	}
+
+	if (size <= offset)
+		goto finish;
+
+	if (path) {
+		const struct pathattr *a = pathattr_lookup(path);
+		if (a && a->pretty)
+			pretty = a->pretty;
+	}
 
-	if (offset < size)
-		fwrite(buf + offset, size - offset, 1, stdout);
+	pretty(buf + offset, size - offset);
+ finish:
 	free(buf);
 	return 0;
 }
@@ -142,7 +159,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
 		const char *name = objects[i].name;
 		switch (o->type) {
 		case OBJ_BLOB:
-			ret = show_object(o->sha1, 0);
+			ret = show_object(o->sha1, name, 0);
 			break;
 		case OBJ_TAG: {
 			struct tag *t = (struct tag *)o;
@@ -153,7 +170,7 @@ int cmd_show(int argc, const char **argv, const char *prefix)
 					t->tag,
 					diff_get_color(rev.diffopt.color_diff,
 						DIFF_RESET));
-			ret = show_object(o->sha1, 1);
+			ret = show_object(o->sha1, name, 1);
 			objects[i].item = (struct object *)t->tagged;
 			i--;
 			break;
diff --git a/pathattr.c b/pathattr.c
index 06bbb4e..c84be39 100644
--- a/pathattr.c
+++ b/pathattr.c
@@ -1,6 +1,13 @@
 #include "cache.h"
 #include "pathattr.h"
 
+static void show_display(const unsigned char *blobdata, unsigned long size)
+{
+	FILE *display = popen("display -", "w");
+	fwrite(blobdata, size, 1, display);
+	fclose(display);
+}
+
 /*
  * Path match specification
  */
@@ -93,6 +100,7 @@ static void init_stack(void)
 	a = locate(stk, "image/*");
 	a->conv_i = NULL;
 	a->conv_o = NULL;
+	a->pretty = show_display;
 	add_match(stk, a, "*.png");
 	add_match(stk, a, "*.jpg");
 	add_match(stk, a, "*.gif");
diff --git a/pathattr.h b/pathattr.h
index 4ca4e60..bfd9ff1 100644
--- a/pathattr.h
+++ b/pathattr.h
@@ -3,6 +3,8 @@
 
 #include "convert.h"
 
+typedef void (*pretty_fn)(const unsigned char *blobdata, unsigned long size);
+
 /*
  * Data in one section of [pathattr "name"], except
  * the path match specification.
@@ -11,6 +13,7 @@ struct pathattr {
 	char *name;
 	convi_fn conv_i;
 	convo_fn conv_o;
+	pretty_fn pretty;
 };
 
 const struct pathattr *pathattr_lookup(const char *);
-- 
1.5.0.2.809.g0f936
Next: Andy Parkins
Message 1 of 6 in “git-show: use pathattr to run "display"”
  1. 2/2 git-show: use pathattr to run "display"Junio C Hamano, Mar 1, 2007
  2. Andy ParkinsMar 1, 2007
  3. Andy ParkinsMar 1, 2007
  4. 3/2 pathattr: read from git_config().Junio C Hamano, Mar 1, 2007
  5. 4/2 pathattr: allow piping to external program.Junio C Hamano, Mar 1, 2007
  6. Junio C HamanoMar 1, 2007

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.