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

Re: Getting a commit sha1 from fast-import in a remote-helper

From
Jonathan Nieder <jrnieder@gmail.com>
Date
Nov 18, 2014, 01:40 UTC
Message-ID
<20141118014028.GF4336@google.com>
In-Reply-To
<20141118003426.GA6528@glandium.org>
Mike Hommey wrote:
Show 7 quoted lines
> - fast-import's `ls` command documentation about its output format
>   mentions that the output may contain commits, so I tried the trick of
>   creating a tree with commits, but fast-import then fails with:
>     fatal: Not a blob (actually a commit)
>   which I totally understand, but then I wonder why the documentation
>   mentions it and how one would get a tree containing references to
>   commits. I guess the documentation should be fixed.
Odd.  Here's what happens when I try:
 $ echo "ls $(git rev-parse HEAD)" | git fast-import --quiet
 fatal: Missing space after tree-ish: ls a4a226a366ab0a173ed9e5f70f2a95d0d21e54c5
 fast-import: dumping crash report to .git/fast_import_crash_14080
 $ echo "ls $(git rev-parse HEAD) " | git fast-import --quiet
 040000 tree d3d38e7d71cb40ebbaf2798b01837b3de43fd4a1
How did you get that "Not a blob" message?

I think a good fix would be to teach parse_ls a mode with no <path> parameter. Something like this (untested; needs cleanup and tests):

Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
diff --git i/fast-import.c w/fast-import.c
index d0bd285..a9a46be 100644
--- i/fast-import.c
+++ w/fast-import.c
@@ -278,6 +278,8 @@ struct recent_command {
 	char *buf;
 };
 
+extern const char *tag_type;
+
 /* Configured limits on output */
 static unsigned long max_depth = 10;
 static off_t max_packsize;
@@ -3047,6 +3049,49 @@ static void parse_ls(const char *p, struct branch *b)
 	struct tree_entry *root = NULL;
 	struct tree_entry leaf = {NULL};
 
+	/* ls SP <tree-ish> */
+	if (*p != '"' && !strchr(p, ' ')) {
+		unsigned char sha1[20];
+		struct object_entry *e;
+		static struct strbuf line = STRBUF_INIT;
+		const char *type;
+
+		if (*p == ':') {	/* <mark> */
+			e = find_mark(parse_mark_ref_eol(p));
+			if (!e)
+				die("Unknown mark: %s", command_buf.buf);
+			hashcpy(sha1, e->idx.sha1);
+		} else {	/* <sha1> */
+			if (get_sha1_hex(p, sha1))
+				die("Invalid dataref: %s", command_buf.buf);
+			e = find_object(sha1);
+			p += 40;
+			if (*p)
+				die("Garbage after dataref: %s", command_buf.buf);
+		}
+
+		switch (e->type) {
+		case OBJ_COMMIT:
+			type = commit_type;
+			break;
+		case OBJ_TREE:
+			type = tree_type;
+			break;
+		case OBJ_BLOB:
+			type = blob_type;
+			break;
+		case OBJ_TAG:
+			type = tag_type;
+			break;
+		default:
+			die("Not a tree-ish: %s", command_buf.buf);
+		}
+
+		strbuf_reset(&line);
+		strbuf_addf(&line, "%s %s\n", type, sha1_to_hex(sha1));
+		cat_blob_write(line.buf, line.len);
+	}
+
 	/* ls SP (<tree-ish> SP)? <path> */
 	if (*p == '"') {
 		if (!b)
Previous: Mike HommeyNext: Mike Hommey
Message 2 of 15 in “Getting a commit sha1 from fast-import in a remote-helper”
  1. Mike HommeyNov 18, 2014
  2. Jonathan NiederNov 18, 2014
  3. Mike HommeyNov 18, 2014
  4. Jonathan NiederNov 18, 2014
  5. Mike HommeyNov 18, 2014
  6. Mike HommeyNov 19, 2014
  7. Jonathan NiederNov 19, 2014
  8. Mike HommeyNov 19, 2014
  9. Jonathan NiederNov 19, 2014
  10. Mike HommeyNov 18, 2014
  11. Mike HommeyNov 18, 2014
  12. Jonathan NiederNov 18, 2014
  13. Mike HommeyNov 18, 2014
  14. Jonathan NiederNov 18, 2014
  15. Mike HommeyNov 18, 2014

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.