Subject: [PATCH v3 0/4] Don't lazy-fetch commits when parsing them

From: Jonathan Tan <[email-masked]>
Date: Thu, 8 Dec 2022 12:57:04 -0800

Thanks everyone for your review. map_loose_object_1() definitely looks
less "busy" than before after following your suggestions.

Jonathan Tan (4):
  object-file: remove OBJECT_INFO_IGNORE_LOOSE
  object-file: refactor map_loose_object_1()
  object-file: emit corruption errors when detected
  commit: don't lazy-fetch commits

 commit.c       |  15 ++++++-
 object-file.c  | 111 +++++++++++++++++++++++++------------------------
 object-store.h |   7 ++--
 3 files changed, 73 insertions(+), 60 deletions(-)

Range-diff against v2:
1:  9ad34a1dce < -:  ---------- object-file: don't exit early if skipping loose
-:  ---------- > 1:  be0b08cac2 object-file: remove OBJECT_INFO_IGNORE_LOOSE
-:  ---------- > 2:  7419e4ac70 object-file: refactor map_loose_object_1()
2:  9ddfff3585 ! 3:  7c9ed861e7 object-file: emit corruption errors when detected
    @@ Commit message
         Signed-off-by: Jonathan Tan <[email-masked]>
     
      ## object-file.c ##
    -@@ object-file.c: static int quick_has_loose(struct repository *r,
    -  * searching for a loose object named "oid".
    -  */
    - static void *map_loose_object_1(struct repository *r, const char *path,
    --			     const struct object_id *oid, unsigned long *size)
    -+				const struct object_id *oid, unsigned long *size,
    -+				char **mapped_path)
    - {
    - 	void *map;
    - 	int fd;
    -@@ object-file.c: static void *map_loose_object_1(struct repository *r, const char *path,
    - 		fd = git_open(path);
    - 	else
    - 		fd = open_loose_object(r, oid, &path);
    -+	if (mapped_path)
    -+		*mapped_path = xstrdup(path);
    -+
    - 	map = NULL;
    - 	if (fd >= 0) {
    - 		struct stat st;
    -@@ object-file.c: void *map_loose_object(struct repository *r,
    - 		       const struct object_id *oid,
    - 		       unsigned long *size)
    - {
    --	return map_loose_object_1(r, NULL, oid, size);
    -+	return map_loose_object_1(r, NULL, oid, size, NULL);
    - }
    - 
    - enum unpack_loose_header_result unpack_loose_header(git_zstream *stream,
     @@ object-file.c: static int loose_object_info(struct repository *r,
      {
      	int status = 0;
      	unsigned long mapsize;
    -+	char *mapped_path = NULL;
    ++	const char *path = NULL;
      	void *map;
      	git_zstream stream;
      	char hdr[MAX_HEADER_LEN];
    @@ object-file.c: static int loose_object_info(struct repository *r,
      	}
      
     -	map = map_loose_object(r, oid, &mapsize);
    --	if (!map)
    -+	map = map_loose_object_1(r, NULL, oid, &mapsize, &mapped_path);
    -+	if (!map) {
    -+		free(mapped_path);
    ++	map = map_loose_object_1(r, oid, &mapsize, &path);
    + 	if (!map)
      		return -1;
    -+	}
      
    - 	if (!oi->sizep)
    - 		oi->sizep = &size_scratch;
     @@ object-file.c: static int loose_object_info(struct repository *r,
      		break;
      	}
      
     +	if (status && (flags & OBJECT_INFO_DIE_IF_CORRUPT))
     +		die(_("loose object %s (stored in %s) is corrupt"),
    -+		    oid_to_hex(oid), mapped_path);
    ++		    oid_to_hex(oid), path);
     +
      	git_inflate_end(&stream);
      cleanup:
    -+	free(mapped_path);
      	munmap(map, mapsize);
    - 	if (oi->sizep == &size_scratch)
    - 		oi->sizep = NULL;
     @@ object-file.c: static int do_oid_object_info_extended(struct repository *r,
      			continue;
      		}
    @@ object-file.c: int force_object_loose(const struct object_id *oid, time_t mtime)
      	if (!buf)
      		return error(_("cannot read object for %s"), oid_to_hex(oid));
      	hdrlen = format_object_header(hdr, sizeof(hdr), type, len);
    -@@ object-file.c: int read_loose_object(const char *path,
    - 	char hdr[MAX_HEADER_LEN];
    - 	unsigned long *size = oi->sizep;
    - 
    --	map = map_loose_object_1(the_repository, path, NULL, &mapsize);
    -+	map = map_loose_object_1(the_repository, path, NULL, &mapsize, NULL);
    - 	if (!map) {
    - 		error_errno(_("unable to mmap %s"), path);
    - 		goto out;
     
      ## object-store.h ##
     @@ object-store.h: struct object_info {
    @@ object-store.h: struct object_info {
      #define OBJECT_INFO_FOR_PREFETCH (OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK)
      
     +/* Die if object corruption (not just an object being missing) was detected. */
    -+#define OBJECT_INFO_DIE_IF_CORRUPT 64
    ++#define OBJECT_INFO_DIE_IF_CORRUPT 32
     +
      int oid_object_info_extended(struct repository *r,
      			     const struct object_id *,
3:  c5fe42deb0 = 4:  5924a5120b commit: don't lazy-fetch commits
-- 
2.39.0.rc1.256.g54fd8350bd-goog