Skip to content

Commit

Permalink
packfile: factor out --pack_header argument parsing
Browse files Browse the repository at this point in the history
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 <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
Signed-off-by: Johannes Schindelin <[email protected]>
  • Loading branch information
peff authored and dscho committed Jan 22, 2025
1 parent 75bc40d commit b3c9b61
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 23 deletions.
14 changes: 3 additions & 11 deletions builtin/index-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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")) {
Expand Down
16 changes: 4 additions & 12 deletions builtin/unpack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -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]";
Expand Down Expand Up @@ -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)) {
Expand Down
17 changes: 17 additions & 0 deletions packfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
6 changes: 6 additions & 0 deletions packfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit b3c9b61

Please sign in to comment.