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

[PATCH v3 6/6] chunked-object: fallback checkout codepaths

From
Junio C Hamano <gitster@pobox.com>
Date
Dec 2, 2011, 00:40 UTC
Message-ID
<1322786449-25753-7-git-send-email-gitster@pobox.com>
In-Reply-To
<1322786449-25753-1-git-send-email-gitster@pobox.com>

This prepares the default codepaths based on the traditional "slurping everything in-core" model around read_sha1_file() API for objects that use chunked encoding. Needless to say, these codepaths are unsuitable for the kind of objects that use chunked encoding and are intended to only serve as the fallback where specialized "large object API" support is still lacking.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 sha1_file.c      |   54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/t1050-large.sh |   14 +++++++++++++-
 2 files changed, 67 insertions(+), 1 deletions(-)
diff --git a/sha1_file.c b/sha1_file.c
index 14902cc..7355716 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -1607,6 +1607,11 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset,
 		if (sizep)
 			*sizep = size;
 		break;
+	case OBJ_CHUNKED_BLOB:
+		if (sizep)
+			*sizep = size;
+		type = OBJ_DEKNUHC(type);
+		break;
 	default:
 		error("unknown object type %i at offset %"PRIuMAX" in %s",
 		      type, (uintmax_t)obj_offset, p->pack_name);
@@ -1648,6 +1653,51 @@ static void *unpack_compressed_entry(struct packed_git *p,
 	return buffer;
 }
 
+static void *unpack_chunked_entry(struct packed_git *p,
+				  struct pack_window **w_curs,
+				  off_t curpos,
+				  unsigned long size)
+{
+	/*
+	 * *NOTE* *NOTE* *NOTE*
+	 *
+	 * In the longer term, we should aim to exercise this codepath
+	 * less and less often, as it defeats the whole purpose of
+	 * chuncked object encoding!
+	 */
+	unsigned char *buffer;
+	const unsigned char *in, *ptr;
+	unsigned long avail, ofs;
+	int chunk_cnt;
+
+	buffer = xmallocz(size);
+	in = use_pack(p, w_curs, curpos, &avail);
+	ptr = in;
+	chunk_cnt = decode_in_pack_varint(&ptr);
+	curpos += ptr - in;
+	ofs = 0;
+	while (chunk_cnt--) {
+		unsigned long csize;
+		unsigned char *data;
+		enum object_type type;
+
+		in = use_pack(p, w_curs, curpos, &avail);
+		data = read_sha1_file(in, &type, &csize);
+		if (!data)
+			die("malformed chunked object contents ('%s' does not exist)",
+			    sha1_to_hex(in));
+		if (type != OBJ_BLOB)
+			die("malformed chunked object contents (not a blob)");
+		if (size < ofs + csize)
+			die("malformed chunked object contents (sizes do not add up)");
+		memcpy(buffer + ofs, data, csize);
+		ofs += csize;
+		curpos += 20;
+		free(data);
+	}
+	return buffer;
+}
+
 #define MAX_DELTA_CACHE (256)
 
 static size_t delta_base_cached;
@@ -1883,6 +1933,10 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset,
 	case OBJ_TAG:
 		data = unpack_compressed_entry(p, &w_curs, curpos, *sizep);
 		break;
+	case OBJ_CHUNKED_BLOB:
+		data = unpack_chunked_entry(p, &w_curs, curpos, *sizep);
+		*type = OBJ_DEKNUHC(*type);
+		break;
 	default:
 		data = NULL;
 		error("unknown object type %i at offset %"PRIuMAX" in %s",
diff --git a/t/t1050-large.sh b/t/t1050-large.sh
index d6cb66d..eea45d1 100755
--- a/t/t1050-large.sh
+++ b/t/t1050-large.sh
@@ -124,8 +124,20 @@ test_expect_success 'split limit' '
 		# switch to a better chunking heuristics.
 		echo cruft >head &&
 		cat split >>head &&
-		git add head
+		git add head &&
 
+		echo blob >expect &&
+		git cat-file -t :split >actual &&
+		test_cmp expect actual &&
+
+		git cat-file -p :split >actual &&
+		# You probably do not want to use test_cmp here...
+		cmp split actual &&
+
+		mv split expect &&
+		git checkout split &&
+		# You probably do not want to use test_cmp here...
+		cmp expect split
 	)
 '
 
-- 
1.7.8.rc4.177.g4d64
Previous: Junio C Hamano
Message 15 of 15 in “Bulk Check-in”
  1. 0/5 Bulk Check-inJunio C Hamano, Dec 1, 2011
  2. 1/5 write_pack_header(): a helper functionJunio C Hamano, Dec 1, 2011
  3. 2/5 create_tmp_packfile(): a helper functionJunio C Hamano, Dec 1, 2011
  4. 3/5 finish_tmp_packfile(): a helper functionJunio C Hamano, Dec 1, 2011
  5. 4/5 csum-file: introduce sha1file_checkpointJunio C Hamano, Dec 1, 2011
  6. 5/5 bulk-checkin: replace fast-import based implementationJunio C Hamano, Dec 1, 2011
  7. Nguyen Thai Ngoc DuyDec 1, 2011
  8. Junio C HamanoDec 1, 2011
  9. 0/6 Bulk check-inJunio C Hamano, Dec 2, 2011
  10. 1/6 bulk-checkin: replace fast-import based implementationJunio C Hamano, Dec 2, 2011
  11. 2/6 varint-in-pack: refactor varint encoding/decodingJunio C Hamano, Dec 2, 2011
  12. 3/6 new representation types in the packstreamJunio C Hamano, Dec 2, 2011
  13. 4/6 bulk-checkin: allow the same data to be multiply hashedJunio C Hamano, Dec 2, 2011
  14. 5/6 bulk-checkin: support chunked-object encodingJunio C Hamano, Dec 2, 2011
  15. 6/6 chunked-object: fallback checkout codepathsJunio C Hamano, Dec 2, 2011

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.