]> git.ipfire.org Git - thirdparty/git.git/commitdiff
packfile: factor out --pack_header argument parsing
authorJeff King <peff@peff.net>
Sun, 19 Jan 2025 13:23:37 +0000 (08:23 -0500)
committerJunio C Hamano <gitster@pobox.com>
Tue, 21 Jan 2025 16:42:55 +0000 (08:42 -0800)
Both index-pack and unpack-objects accept a --pack_header argument. This
is an undocumented internal argument used by receive-pack and fetch to
pass along information about the header of the pack, which they've
already read from the incoming stream.

In preparation for a bugfix, let's factor the duplicated code into a
common helper.

The callers are still responsible for identifying the option. While this
could likewise be factored out, it is more flexible this way (e.g., if
they ever started using parse-options and wanted to handle both the
stuck and unstuck forms).

Likewise, the callers are responsible for reporting errors, though they
both just call die(). I've tweaked unpack-objects to match index-pack in
marking the error for translation.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/index-pack.c
builtin/unpack-objects.c
packfile.c
packfile.h

index 763b01372aade423bc275d08d5071c62fe2d92b1..bab42dfc2a491abb09592659ec19ffdd30c93fc1 100644 (file)
@@ -1801,18 +1801,10 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
                                        nr_threads = 1;
                                }
                        } else if (starts_with(arg, "--pack_header=")) {
-                               struct pack_header *hdr;
-                               char *c;
-
-                               hdr = (struct pack_header *)input_buffer;
-                               hdr->hdr_signature = htonl(PACK_SIGNATURE);
-                               hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
-                               if (*c != ',')
-                                       die(_("bad %s"), arg);
-                               hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
-                               if (*c)
+                               if (parse_pack_header_option(arg + 14,
+                                                            input_buffer,
+                                                            &input_len) < 0)
                                        die(_("bad %s"), arg);
-                               input_len = sizeof(*hdr);
                        } else if (!strcmp(arg, "-v")) {
                                verbose = 1;
                        } else if (!strcmp(arg, "--progress-title")) {
index 08fa2a7a743dc91f8aa83cfc8021fce471a36791..31614472749bf9784854aa81a3e9e1f9bb4008d4 100644 (file)
@@ -15,6 +15,7 @@
 #include "progress.h"
 #include "decorate.h"
 #include "fsck.h"
+#include "packfile.h"
 
 static int dry_run, quiet, recover, has_errors, strict;
 static const char unpack_usage[] = "git unpack-objects [-n] [-q] [-r] [--strict]";
@@ -639,18 +640,9 @@ int cmd_unpack_objects(int argc, const char **argv, const char *prefix UNUSED)
                                continue;
                        }
                        if (starts_with(arg, "--pack_header=")) {
-                               struct pack_header *hdr;
-                               char *c;
-
-                               hdr = (struct pack_header *)buffer;
-                               hdr->hdr_signature = htonl(PACK_SIGNATURE);
-                               hdr->hdr_version = htonl(strtoul(arg + 14, &c, 10));
-                               if (*c != ',')
-                                       die("bad %s", arg);
-                               hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
-                               if (*c)
-                                       die("bad %s", arg);
-                               len = sizeof(*hdr);
+                               if (parse_pack_header_option(arg + 14,
+                                                            buffer, &len) < 0)
+                                       die(_("bad %s"), arg);
                                continue;
                        }
                        if (skip_prefix(arg, "--max-input-size=", &arg)) {
index 813584646f762ac096e971b9074c1a7bd0ca74c9..e2bdadc7cbd44bdb8aad076ca1fd37c7060a99de 100644 (file)
@@ -2294,3 +2294,20 @@ int is_promisor_object(const struct object_id *oid)
        }
        return oidset_contains(&promisor_objects, oid);
 }
+
+int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len)
+{
+       struct pack_header *hdr;
+       char *c;
+
+       hdr = (struct pack_header *)out;
+       hdr->hdr_signature = htonl(PACK_SIGNATURE);
+       hdr->hdr_version = htonl(strtoul(in, &c, 10));
+       if (*c != ',')
+               return -1;
+       hdr->hdr_entries = htonl(strtoul(c + 1, &c, 10));
+       if (*c)
+               return -1;
+       *len = sizeof(*hdr);
+       return 0;
+}
index eb18ec15dbf3bc347bc6511c3f669af2cce61842..41f38b4832bf91a2de9464608602e0b0b1da0a37 100644 (file)
@@ -210,4 +210,10 @@ int is_promisor_object(const struct object_id *oid);
 int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
             size_t idx_size, struct packed_git *p);
 
+/*
+ * Parse a --pack_header option as accepted by index-pack and unpack-objects,
+ * turning it into the matching bytes we'd find in a pack.
+ */
+int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len);
+
 #endif