{"thread":{"id":"11688","subject":"[PATCH 2/2] Document the hairy gfi_unpack_entry part of fast-import","startedAt":"2008-01-21T04:37:01Z","lastAt":"2008-01-21T04:37:01Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"66074","messageId":"20080121043701.GB27521@spearce.org","threadId":"11688","inReplyTo":null,"subject":"[PATCH 2/2] Document the hairy gfi_unpack_entry part of fast-import","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2008-01-21T04:37:01Z","receivedAt":"2008-01-21T04:37:01Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio pointed out this part of fast-import wasn't very clear on\ninitial read, and it took some time for someone who was new to\nfast-import's \"dirty little tricks\" to understand how this was\neven working.  So a little bit of commentary in the proper place\nmay help future readers.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n fast-import.c |   33 +++++++++++++++++++++++++++++++++\n 1 files changed, 33 insertions(+), 0 deletions(-)\n\ndiff --git a/fast-import.c b/fast-import.c\nindex f6872fe..a523b17 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -1125,6 +1125,24 @@ static int store_object(\n \treturn 0;\n }\n \n+/* All calls must be guarded by find_object() or find_mark() to\n+ * ensure the 'struct object_entry' passed was written by this\n+ * process instance.  We unpack the entry by the offset, avoiding\n+ * the need for the corresponding .idx file.  This unpacking rule\n+ * works because we only use OBJ_REF_DELTA within the packfiles\n+ * created by fast-import.\n+ *\n+ * oe must not be NULL.  Such an oe usually comes from giving\n+ * an unknown SHA-1 to find_object() or an undefined mark to\n+ * find_mark().  Callers must test for this condition and use\n+ * the standard read_sha1_file() when it happens.\n+ *\n+ * oe->pack_id must not be MAX_PACK_ID.  Such an oe is usually from\n+ * find_mark(), where the mark was reloaded from an existing marks\n+ * file and is referencing an object that this fast-import process\n+ * instance did not write out to a packfile.  Callers must test for\n+ * this condition and use read_sha1_file() instead.\n+ */\n static void *gfi_unpack_entry(\n \tstruct object_entry *oe,\n \tunsigned long *sizep)\n@@ -1132,7 +1150,22 @@ static void *gfi_unpack_entry(\n \tenum object_type type;\n \tstruct packed_git *p = all_packs[oe->pack_id];\n \tif (p == pack_data && p->pack_size < (pack_size + 20)) {\n+\t\t/* The object is stored in the packfile we are writing to\n+\t\t * and we have modified it since the last time we scanned\n+\t\t * back to read a previously written object.  If an old\n+\t\t * window covered [p->pack_size, p->pack_size + 20) its\n+\t\t * data is stale and is not valid.  Closing all windows\n+\t\t * and updating the packfile length ensures we can read\n+\t\t * the newly written data.\n+\t\t */\n \t\tclose_pack_windows(p);\n+\n+\t\t/* We have to offer 20 bytes additional on the end of\n+\t\t * the packfile as the core unpacker code assumes the\n+\t\t * footer is present at the file end and must promise\n+\t\t * at least 20 bytes within any window it maps.  But\n+\t\t * we don't actually create the footer here.\n+\t\t */\n \t\tp->pack_size = pack_size + 20;\n \t}\n \treturn unpack_entry(p, oe->offset, &type, sizep);\n-- \n1.5.4.rc4.1109.g30426\n"}]}