Subject: [PATCH v2 2/3] fetch-pack: use index-pack --unpack-limit instead of unpack-objects

From: Nguyễn Thái Ngọc Duy <[email-masked]>
Date: Fri, 6 Sep 2013 07:46:02 +0700

Current code peeks into the transfered pack's header, if the number of
objects is under a limit, unpack-objects is called to handle the rest,
otherwise index-pack is. This patch makes index-pack handle both
cases. After the next patch, unpack-objects will no longer be used. It
may be removed in future.

Now we only have two code paths to maintain regarding pack reading
(sha1_file.c and index-pack.c). When .pack v4 comes, we don't need to
duplicate work in index-pack and unpack-objects.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email-masked]>
---
 fetch-pack.c | 86 +++++++++++++++++++++++++-----------------------------------
 1 file changed, 35 insertions(+), 51 deletions(-)

diff --git a/fetch-pack.c b/fetch-pack.c
index f5d99c1..44d029f 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -682,16 +682,16 @@ static int sideband_demux(int in, int out, void *data)
 }
 
 static int get_pack(struct fetch_pack_args *args,
-		    int xd[2], char **pack_lockfile)
+		    int xd[2], char **pack_lockfile_p)
 {
 	struct async demux;
-	const char *argv[22];
+	const char *argv[23];
 	char keep_arg[256];
-	char hdr_arg[256];
+	char unpack_limit_arg[256];
 	const char **av;
-	int do_keep = args->keep_pack;
 	struct child_process cmd;
 	int ret;
+	char *pack_lockfile;
 
 	memset(&demux, 0, sizeof(demux));
 	if (use_sideband) {
@@ -711,54 +711,33 @@ static int get_pack(struct fetch_pack_args *args,
 
 	memset(&cmd, 0, sizeof(cmd));
 	cmd.argv = argv;
+	cmd.out = -1;
 	av = argv;
-	*hdr_arg = 0;
-	if (!args->keep_pack && unpack_limit) {
-		struct pack_header header;
-
-		if (read_pack_header(demux.out, &header))
-			die("protocol error: bad pack header");
-		snprintf(hdr_arg, sizeof(hdr_arg),
-			 "--pack_header=%"PRIu32",%"PRIu32,
-			 ntohl(header.hdr_version), ntohl(header.hdr_entries));
-		if (ntohl(header.hdr_entries) < unpack_limit)
-			do_keep = 0;
-		else
-			do_keep = 1;
-	}
 
 	if (alternate_shallow_file) {
 		*av++ = "--shallow-file";
 		*av++ = alternate_shallow_file;
 	}
 
-	if (do_keep) {
-		if (pack_lockfile)
-			cmd.out = -1;
-		*av++ = "index-pack";
-		*av++ = "--stdin";
-		if (!args->quiet && !args->no_progress)
-			*av++ = "-v";
-		if (args->use_thin_pack)
-			*av++ = "--fix-thin";
-		if (args->lock_pack || unpack_limit) {
-			int s = sprintf(keep_arg,
-					"--keep=fetch-pack %"PRIuMAX " on ", (uintmax_t) getpid());
-			if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
-				strcpy(keep_arg + s, "localhost");
-			*av++ = keep_arg;
-		}
-		if (args->check_self_contained_and_connected)
-			*av++ = "--check-self-contained-and-connected";
-	}
-	else {
-		*av++ = "unpack-objects";
-		if (args->quiet || args->no_progress)
-			*av++ = "-q";
-		args->check_self_contained_and_connected = 0;
-	}
-	if (*hdr_arg)
-		*av++ = hdr_arg;
+	*av++ = "index-pack";
+	*av++ = "--stdin";
+	if (!args->quiet && !args->no_progress)
+		*av++ = "-v";
+	if (args->use_thin_pack)
+		*av++ = "--fix-thin";
+	if (args->lock_pack || unpack_limit) {
+		int s = sprintf(keep_arg,
+				"--keep=fetch-pack %"PRIuMAX " on ", (uintmax_t) getpid());
+		if (gethostname(keep_arg + s, sizeof(keep_arg) - s))
+			strcpy(keep_arg + s, "localhost");
+		*av++ = keep_arg;
+	}
+	if (!args->keep_pack) {
+		sprintf(unpack_limit_arg, "--unpack-limit=%u", unpack_limit);
+		*av++ = unpack_limit_arg;
+	}
+	if (args->check_self_contained_and_connected)
+		*av++ = "--check-self-contained-and-connected";
 	if (fetch_fsck_objects >= 0
 	    ? fetch_fsck_objects
 	    : transfer_fsck_objects >= 0
@@ -771,20 +750,26 @@ static int get_pack(struct fetch_pack_args *args,
 	cmd.git_cmd = 1;
 	if (start_command(&cmd))
 		die("fetch-pack: unable to fork off %s", argv[0]);
-	if (do_keep && pack_lockfile) {
-		*pack_lockfile = index_pack_lockfile(cmd.out);
-		close(cmd.out);
-	}
-
+	pack_lockfile = index_pack_lockfile(cmd.out);
+	close(cmd.out);
 	ret = finish_command(&cmd);
+
 	if (!ret || (args->check_self_contained_and_connected && ret == 1))
 		args->self_contained_and_connected =
 			args->check_self_contained_and_connected &&
 			ret == 0;
 	else
 		die("%s failed", argv[0]);
+
 	if (use_sideband && finish_async(&demux))
 		die("error in sideband demultiplexer");
+
+	if (pack_lockfile)
+		reprepare_packed_git();
+
+	if (pack_lockfile_p)
+		*pack_lockfile_p = pack_lockfile;
+
 	return 0;
 }
 
@@ -997,6 +982,5 @@ struct ref *fetch_pack(struct fetch_pack_args *args,
 			commit_lock_file(&shallow_lock);
 	}
 
-	reprepare_packed_git();
 	return ref_cpy;
 }
-- 
1.8.2.83.gc99314b