2018-07-12 21:39:20 +02:00
|
|
|
#include "builtin.h"
|
2023-03-21 07:25:58 +01:00
|
|
|
#include "abspath.h"
|
2018-07-12 21:39:20 +02:00
|
|
|
#include "cache.h"
|
|
|
|
#include "config.h"
|
2023-03-21 07:26:03 +01:00
|
|
|
#include "environment.h"
|
2023-03-21 07:25:54 +01:00
|
|
|
#include "gettext.h"
|
2018-07-12 21:39:20 +02:00
|
|
|
#include "parse-options.h"
|
2018-07-12 21:39:21 +02:00
|
|
|
#include "midx.h"
|
2019-03-21 20:36:13 +01:00
|
|
|
#include "trace2.h"
|
2021-03-30 17:04:11 +02:00
|
|
|
#include "object-store.h"
|
2018-07-12 21:39:20 +02:00
|
|
|
|
2021-03-30 17:03:54 +02:00
|
|
|
#define BUILTIN_MIDX_WRITE_USAGE \
|
midx: preliminary support for `--refs-snapshot`
To figure out which commits we can write a bitmap for, the multi-pack
index/bitmap code does a reachability traversal, marking any commit
which can be found in the MIDX as eligible to receive a bitmap.
This approach will cause a problem when multi-pack bitmaps are able to
be generated from `git repack`, since the reference tips can change
during the repack. Even though we ignore commits that don't exist in
the MIDX (when doing a scan of the ref tips), it's possible that a
commit in the MIDX reaches something that isn't.
This can happen when a multi-pack index contains some pack which refers
to loose objects (e.g., if a pack was pushed after starting the repack
but before generating the MIDX which depends on an object which is
stored as loose in the repository, and by definition isn't included in
the multi-pack index).
By taking a snapshot of the references before we start repacking, we can
close that race window. In the above scenario (where we have a packed
object pointing at a loose one), we'll either (a) take a snapshot of the
references before seeing the packed one, or (b) take it after, at which
point we can guarantee that the loose object will be packed and included
in the MIDX.
This patch does just that. It writes a temporary "reference snapshot",
which is a list of OIDs that are at the ref tips before writing a
multi-pack bitmap. References that are "preferred" (i.e,. are a suffix
of at least one value of the 'pack.preferBitmapTips' configuration) are
marked with a special '+'.
The format is simple: one line per commit at each tip, with an optional
'+' at the beginning (for preferred references, as described above).
When provided, the reference snapshot is used to drive bitmap selection
instead of the MIDX code doing its own traversal. When it isn't
provided, the usual traversal takes place instead.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-29 03:55:07 +02:00
|
|
|
N_("git multi-pack-index [<options>] write [--preferred-pack=<pack>]" \
|
|
|
|
"[--refs-snapshot=<path>]")
|
2021-03-30 17:03:54 +02:00
|
|
|
|
|
|
|
#define BUILTIN_MIDX_VERIFY_USAGE \
|
|
|
|
N_("git multi-pack-index [<options>] verify")
|
|
|
|
|
|
|
|
#define BUILTIN_MIDX_EXPIRE_USAGE \
|
|
|
|
N_("git multi-pack-index [<options>] expire")
|
|
|
|
|
|
|
|
#define BUILTIN_MIDX_REPACK_USAGE \
|
|
|
|
N_("git multi-pack-index [<options>] repack [--batch-size=<size>]")
|
|
|
|
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
static char const * const builtin_multi_pack_index_write_usage[] = {
|
|
|
|
BUILTIN_MIDX_WRITE_USAGE,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
static char const * const builtin_multi_pack_index_verify_usage[] = {
|
|
|
|
BUILTIN_MIDX_VERIFY_USAGE,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
static char const * const builtin_multi_pack_index_expire_usage[] = {
|
|
|
|
BUILTIN_MIDX_EXPIRE_USAGE,
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
static char const * const builtin_multi_pack_index_repack_usage[] = {
|
|
|
|
BUILTIN_MIDX_REPACK_USAGE,
|
|
|
|
NULL
|
|
|
|
};
|
2018-07-12 21:39:20 +02:00
|
|
|
static char const * const builtin_multi_pack_index_usage[] = {
|
2021-03-30 17:03:54 +02:00
|
|
|
BUILTIN_MIDX_WRITE_USAGE,
|
|
|
|
BUILTIN_MIDX_VERIFY_USAGE,
|
|
|
|
BUILTIN_MIDX_EXPIRE_USAGE,
|
|
|
|
BUILTIN_MIDX_REPACK_USAGE,
|
2018-07-12 21:39:20 +02:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct opts_multi_pack_index {
|
2022-04-25 20:27:13 +02:00
|
|
|
char *object_dir;
|
2021-03-30 17:04:11 +02:00
|
|
|
const char *preferred_pack;
|
midx: preliminary support for `--refs-snapshot`
To figure out which commits we can write a bitmap for, the multi-pack
index/bitmap code does a reachability traversal, marking any commit
which can be found in the MIDX as eligible to receive a bitmap.
This approach will cause a problem when multi-pack bitmaps are able to
be generated from `git repack`, since the reference tips can change
during the repack. Even though we ignore commits that don't exist in
the MIDX (when doing a scan of the ref tips), it's possible that a
commit in the MIDX reaches something that isn't.
This can happen when a multi-pack index contains some pack which refers
to loose objects (e.g., if a pack was pushed after starting the repack
but before generating the MIDX which depends on an object which is
stored as loose in the repository, and by definition isn't included in
the multi-pack index).
By taking a snapshot of the references before we start repacking, we can
close that race window. In the above scenario (where we have a packed
object pointing at a loose one), we'll either (a) take a snapshot of the
references before seeing the packed one, or (b) take it after, at which
point we can guarantee that the loose object will be packed and included
in the MIDX.
This patch does just that. It writes a temporary "reference snapshot",
which is a list of OIDs that are at the ref tips before writing a
multi-pack bitmap. References that are "preferred" (i.e,. are a suffix
of at least one value of the 'pack.preferBitmapTips' configuration) are
marked with a special '+'.
The format is simple: one line per commit at each tip, with an optional
'+' at the beginning (for preferred references, as described above).
When provided, the reference snapshot is used to drive bitmap selection
instead of the MIDX code doing its own traversal. When it isn't
provided, the usual traversal takes place instead.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-29 03:55:07 +02:00
|
|
|
const char *refs_snapshot;
|
2019-06-11 01:35:26 +02:00
|
|
|
unsigned long batch_size;
|
2021-03-30 17:03:47 +02:00
|
|
|
unsigned flags;
|
2021-09-29 03:55:04 +02:00
|
|
|
int stdin_packs;
|
2018-07-12 21:39:20 +02:00
|
|
|
} opts;
|
|
|
|
|
2022-04-25 20:27:13 +02:00
|
|
|
|
|
|
|
static int parse_object_dir(const struct option *opt, const char *arg,
|
|
|
|
int unset)
|
|
|
|
{
|
2022-10-06 15:10:53 +02:00
|
|
|
char **value = opt->value;
|
|
|
|
free(*value);
|
2022-04-25 20:27:13 +02:00
|
|
|
if (unset)
|
2022-10-06 15:10:53 +02:00
|
|
|
*value = xstrdup(get_object_directory());
|
2022-04-25 20:27:13 +02:00
|
|
|
else
|
2022-10-06 15:10:53 +02:00
|
|
|
*value = real_pathdup(arg, 1);
|
2022-04-25 20:27:13 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
static struct option common_opts[] = {
|
2022-04-25 20:27:13 +02:00
|
|
|
OPT_CALLBACK(0, "object-dir", &opts.object_dir,
|
|
|
|
N_("directory"),
|
|
|
|
N_("object directory containing set of packfile and pack-index pairs"),
|
|
|
|
parse_object_dir),
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct option *add_common_options(struct option *prev)
|
|
|
|
{
|
|
|
|
return parse_options_concat(common_opts, prev);
|
|
|
|
}
|
|
|
|
|
2021-09-15 00:06:06 +02:00
|
|
|
static int git_multi_pack_index_write_config(const char *var, const char *value,
|
2022-08-25 19:09:48 +02:00
|
|
|
void *cb UNUSED)
|
2021-09-15 00:06:06 +02:00
|
|
|
{
|
|
|
|
if (!strcmp(var, "pack.writebitmaphashcache")) {
|
|
|
|
if (git_config_bool(var, value))
|
|
|
|
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
|
|
|
|
else
|
|
|
|
opts.flags &= ~MIDX_WRITE_BITMAP_HASH_CACHE;
|
|
|
|
}
|
|
|
|
|
2022-08-14 18:55:09 +02:00
|
|
|
if (!strcmp(var, "pack.writebitmaplookuptable")) {
|
|
|
|
if (git_config_bool(var, value))
|
|
|
|
opts.flags |= MIDX_WRITE_BITMAP_LOOKUP_TABLE;
|
|
|
|
else
|
|
|
|
opts.flags &= ~MIDX_WRITE_BITMAP_LOOKUP_TABLE;
|
|
|
|
}
|
|
|
|
|
2021-09-15 00:06:06 +02:00
|
|
|
/*
|
|
|
|
* We should never make a fall-back call to 'git_default_config', since
|
|
|
|
* this was already called in 'cmd_multi_pack_index()'.
|
|
|
|
*/
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2021-09-29 03:55:04 +02:00
|
|
|
static void read_packs_from_stdin(struct string_list *to)
|
|
|
|
{
|
|
|
|
struct strbuf buf = STRBUF_INIT;
|
|
|
|
while (strbuf_getline(&buf, stdin) != EOF)
|
|
|
|
string_list_append(to, buf.buf);
|
|
|
|
string_list_sort(to);
|
|
|
|
|
|
|
|
strbuf_release(&buf);
|
|
|
|
}
|
|
|
|
|
2022-08-19 18:04:05 +02:00
|
|
|
static int cmd_multi_pack_index_write(int argc, const char **argv,
|
|
|
|
const char *prefix)
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
{
|
2021-03-30 17:04:11 +02:00
|
|
|
struct option *options;
|
|
|
|
static struct option builtin_multi_pack_index_write_options[] = {
|
|
|
|
OPT_STRING(0, "preferred-pack", &opts.preferred_pack,
|
|
|
|
N_("preferred-pack"),
|
|
|
|
N_("pack for reuse when computing a multi-pack bitmap")),
|
2021-08-31 22:52:24 +02:00
|
|
|
OPT_BIT(0, "bitmap", &opts.flags, N_("write multi-pack bitmap"),
|
|
|
|
MIDX_WRITE_BITMAP | MIDX_WRITE_REV_INDEX),
|
2021-09-20 23:39:19 +02:00
|
|
|
OPT_BIT(0, "progress", &opts.flags,
|
|
|
|
N_("force progress reporting"), MIDX_PROGRESS),
|
2021-09-29 03:55:04 +02:00
|
|
|
OPT_BOOL(0, "stdin-packs", &opts.stdin_packs,
|
|
|
|
N_("write multi-pack index containing only given indexes")),
|
midx: preliminary support for `--refs-snapshot`
To figure out which commits we can write a bitmap for, the multi-pack
index/bitmap code does a reachability traversal, marking any commit
which can be found in the MIDX as eligible to receive a bitmap.
This approach will cause a problem when multi-pack bitmaps are able to
be generated from `git repack`, since the reference tips can change
during the repack. Even though we ignore commits that don't exist in
the MIDX (when doing a scan of the ref tips), it's possible that a
commit in the MIDX reaches something that isn't.
This can happen when a multi-pack index contains some pack which refers
to loose objects (e.g., if a pack was pushed after starting the repack
but before generating the MIDX which depends on an object which is
stored as loose in the repository, and by definition isn't included in
the multi-pack index).
By taking a snapshot of the references before we start repacking, we can
close that race window. In the above scenario (where we have a packed
object pointing at a loose one), we'll either (a) take a snapshot of the
references before seeing the packed one, or (b) take it after, at which
point we can guarantee that the loose object will be packed and included
in the MIDX.
This patch does just that. It writes a temporary "reference snapshot",
which is a list of OIDs that are at the ref tips before writing a
multi-pack bitmap. References that are "preferred" (i.e,. are a suffix
of at least one value of the 'pack.preferBitmapTips' configuration) are
marked with a special '+'.
The format is simple: one line per commit at each tip, with an optional
'+' at the beginning (for preferred references, as described above).
When provided, the reference snapshot is used to drive bitmap selection
instead of the MIDX code doing its own traversal. When it isn't
provided, the usual traversal takes place instead.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-29 03:55:07 +02:00
|
|
|
OPT_FILENAME(0, "refs-snapshot", &opts.refs_snapshot,
|
|
|
|
N_("refs snapshot for selecting bitmap commits")),
|
2021-03-30 17:04:11 +02:00
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
|
2021-09-15 00:06:06 +02:00
|
|
|
opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE;
|
|
|
|
|
|
|
|
git_config(git_multi_pack_index_write_config, NULL);
|
|
|
|
|
2021-03-30 17:04:11 +02:00
|
|
|
options = add_common_options(builtin_multi_pack_index_write_options);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
|
2021-03-30 17:04:01 +02:00
|
|
|
trace2_cmd_mode(argv[0]);
|
|
|
|
|
2021-09-20 23:39:19 +02:00
|
|
|
if (isatty(2))
|
|
|
|
opts.flags |= MIDX_PROGRESS;
|
pass subcommand "prefix" arguments to parse_options()
Recent commits such as bf0a6b65fc (builtin/multi-pack-index.c: let
parse-options parse subcommands, 2022-08-19) converted a few functions
to match our usual argc/argv/prefix conventions, but the prefix argument
remains unused.
However, there is a good use for it: they should pass it to their own
parse_options() functions, where it may be used to adjust the value of
any filename options. In all but one of these functions, there's no
behavior change, since they don't use OPT_FILENAME. But this is an
actual fix for one option, which you can see by modifying the test suite
like so:
diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
index 4fe57414c1..d0974d4371 100755
--- a/t/t5326-multi-pack-bitmaps.sh
+++ b/t/t5326-multi-pack-bitmaps.sh
@@ -186,7 +186,11 @@ test_expect_success 'writing a bitmap with --refs-snapshot' '
# Then again, but with a refs snapshot which only sees
# refs/tags/one.
- git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
+ (
+ mkdir subdir &&
+ cd subdir &&
+ git multi-pack-index write --bitmap --refs-snapshot=../snapshot
+ ) &&
test_path_is_file $midx &&
test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
I'd emphasize that this wasn't broken by bf0a6b65fc; it has been broken
all along, because the sub-function never got to see the prefix. It is
that commit which is actually enabling us to fix it (and which also
brought attention to the problem because it triggers -Wunused-parameter!)
The other functions changed here don't use OPT_FILENAME at all. In their
cases this isn't fixing anything visible, but it's following the usual
pattern and future-proofing them against somebody adding new options and
being surprised.
I didn't include a test for the one visible case above. We don't
generally test routine parse-options behavior for individual options.
The challenge here was finding the problem, and now that this has been
done, it's not likely to regress. Likewise, we could apply the patch
above to cover it "for free" but it makes reading the rest of the test
unnecessarily complicated.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-25 12:47:00 +02:00
|
|
|
argc = parse_options(argc, argv, prefix,
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
options, builtin_multi_pack_index_write_usage,
|
2022-07-10 17:16:45 +02:00
|
|
|
0);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
if (argc)
|
|
|
|
usage_with_options(builtin_multi_pack_index_write_usage,
|
|
|
|
options);
|
|
|
|
|
2021-03-30 17:04:11 +02:00
|
|
|
FREE_AND_NULL(options);
|
|
|
|
|
2021-09-29 03:55:04 +02:00
|
|
|
if (opts.stdin_packs) {
|
|
|
|
struct string_list packs = STRING_LIST_INIT_DUP;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
read_packs_from_stdin(&packs);
|
|
|
|
|
|
|
|
ret = write_midx_file_only(opts.object_dir, &packs,
|
midx: preliminary support for `--refs-snapshot`
To figure out which commits we can write a bitmap for, the multi-pack
index/bitmap code does a reachability traversal, marking any commit
which can be found in the MIDX as eligible to receive a bitmap.
This approach will cause a problem when multi-pack bitmaps are able to
be generated from `git repack`, since the reference tips can change
during the repack. Even though we ignore commits that don't exist in
the MIDX (when doing a scan of the ref tips), it's possible that a
commit in the MIDX reaches something that isn't.
This can happen when a multi-pack index contains some pack which refers
to loose objects (e.g., if a pack was pushed after starting the repack
but before generating the MIDX which depends on an object which is
stored as loose in the repository, and by definition isn't included in
the multi-pack index).
By taking a snapshot of the references before we start repacking, we can
close that race window. In the above scenario (where we have a packed
object pointing at a loose one), we'll either (a) take a snapshot of the
references before seeing the packed one, or (b) take it after, at which
point we can guarantee that the loose object will be packed and included
in the MIDX.
This patch does just that. It writes a temporary "reference snapshot",
which is a list of OIDs that are at the ref tips before writing a
multi-pack bitmap. References that are "preferred" (i.e,. are a suffix
of at least one value of the 'pack.preferBitmapTips' configuration) are
marked with a special '+'.
The format is simple: one line per commit at each tip, with an optional
'+' at the beginning (for preferred references, as described above).
When provided, the reference snapshot is used to drive bitmap selection
instead of the MIDX code doing its own traversal. When it isn't
provided, the usual traversal takes place instead.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-29 03:55:07 +02:00
|
|
|
opts.preferred_pack,
|
|
|
|
opts.refs_snapshot, opts.flags);
|
2021-09-29 03:55:04 +02:00
|
|
|
|
|
|
|
string_list_clear(&packs, 0);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
}
|
2021-03-30 17:04:11 +02:00
|
|
|
return write_midx_file(opts.object_dir, opts.preferred_pack,
|
midx: preliminary support for `--refs-snapshot`
To figure out which commits we can write a bitmap for, the multi-pack
index/bitmap code does a reachability traversal, marking any commit
which can be found in the MIDX as eligible to receive a bitmap.
This approach will cause a problem when multi-pack bitmaps are able to
be generated from `git repack`, since the reference tips can change
during the repack. Even though we ignore commits that don't exist in
the MIDX (when doing a scan of the ref tips), it's possible that a
commit in the MIDX reaches something that isn't.
This can happen when a multi-pack index contains some pack which refers
to loose objects (e.g., if a pack was pushed after starting the repack
but before generating the MIDX which depends on an object which is
stored as loose in the repository, and by definition isn't included in
the multi-pack index).
By taking a snapshot of the references before we start repacking, we can
close that race window. In the above scenario (where we have a packed
object pointing at a loose one), we'll either (a) take a snapshot of the
references before seeing the packed one, or (b) take it after, at which
point we can guarantee that the loose object will be packed and included
in the MIDX.
This patch does just that. It writes a temporary "reference snapshot",
which is a list of OIDs that are at the ref tips before writing a
multi-pack bitmap. References that are "preferred" (i.e,. are a suffix
of at least one value of the 'pack.preferBitmapTips' configuration) are
marked with a special '+'.
The format is simple: one line per commit at each tip, with an optional
'+' at the beginning (for preferred references, as described above).
When provided, the reference snapshot is used to drive bitmap selection
instead of the MIDX code doing its own traversal. When it isn't
provided, the usual traversal takes place instead.
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-09-29 03:55:07 +02:00
|
|
|
opts.refs_snapshot, opts.flags);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
}
|
|
|
|
|
2022-08-19 18:04:05 +02:00
|
|
|
static int cmd_multi_pack_index_verify(int argc, const char **argv,
|
|
|
|
const char *prefix)
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
{
|
2021-09-20 23:39:19 +02:00
|
|
|
struct option *options;
|
|
|
|
static struct option builtin_multi_pack_index_verify_options[] = {
|
|
|
|
OPT_BIT(0, "progress", &opts.flags,
|
|
|
|
N_("force progress reporting"), MIDX_PROGRESS),
|
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
options = add_common_options(builtin_multi_pack_index_verify_options);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
|
2021-03-30 17:04:01 +02:00
|
|
|
trace2_cmd_mode(argv[0]);
|
|
|
|
|
2021-09-20 23:39:19 +02:00
|
|
|
if (isatty(2))
|
|
|
|
opts.flags |= MIDX_PROGRESS;
|
pass subcommand "prefix" arguments to parse_options()
Recent commits such as bf0a6b65fc (builtin/multi-pack-index.c: let
parse-options parse subcommands, 2022-08-19) converted a few functions
to match our usual argc/argv/prefix conventions, but the prefix argument
remains unused.
However, there is a good use for it: they should pass it to their own
parse_options() functions, where it may be used to adjust the value of
any filename options. In all but one of these functions, there's no
behavior change, since they don't use OPT_FILENAME. But this is an
actual fix for one option, which you can see by modifying the test suite
like so:
diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
index 4fe57414c1..d0974d4371 100755
--- a/t/t5326-multi-pack-bitmaps.sh
+++ b/t/t5326-multi-pack-bitmaps.sh
@@ -186,7 +186,11 @@ test_expect_success 'writing a bitmap with --refs-snapshot' '
# Then again, but with a refs snapshot which only sees
# refs/tags/one.
- git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
+ (
+ mkdir subdir &&
+ cd subdir &&
+ git multi-pack-index write --bitmap --refs-snapshot=../snapshot
+ ) &&
test_path_is_file $midx &&
test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
I'd emphasize that this wasn't broken by bf0a6b65fc; it has been broken
all along, because the sub-function never got to see the prefix. It is
that commit which is actually enabling us to fix it (and which also
brought attention to the problem because it triggers -Wunused-parameter!)
The other functions changed here don't use OPT_FILENAME at all. In their
cases this isn't fixing anything visible, but it's following the usual
pattern and future-proofing them against somebody adding new options and
being surprised.
I didn't include a test for the one visible case above. We don't
generally test routine parse-options behavior for individual options.
The challenge here was finding the problem, and now that this has been
done, it's not likely to regress. Likewise, we could apply the patch
above to cover it "for free" but it makes reading the rest of the test
unnecessarily complicated.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-25 12:47:00 +02:00
|
|
|
argc = parse_options(argc, argv, prefix,
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
options, builtin_multi_pack_index_verify_usage,
|
2022-07-10 17:16:45 +02:00
|
|
|
0);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
if (argc)
|
|
|
|
usage_with_options(builtin_multi_pack_index_verify_usage,
|
|
|
|
options);
|
|
|
|
|
2021-10-26 23:01:18 +02:00
|
|
|
FREE_AND_NULL(options);
|
|
|
|
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
return verify_midx_file(the_repository, opts.object_dir, opts.flags);
|
|
|
|
}
|
|
|
|
|
2022-08-19 18:04:05 +02:00
|
|
|
static int cmd_multi_pack_index_expire(int argc, const char **argv,
|
|
|
|
const char *prefix)
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
{
|
2021-09-20 23:39:19 +02:00
|
|
|
struct option *options;
|
|
|
|
static struct option builtin_multi_pack_index_expire_options[] = {
|
|
|
|
OPT_BIT(0, "progress", &opts.flags,
|
|
|
|
N_("force progress reporting"), MIDX_PROGRESS),
|
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
options = add_common_options(builtin_multi_pack_index_expire_options);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
|
2021-03-30 17:04:01 +02:00
|
|
|
trace2_cmd_mode(argv[0]);
|
|
|
|
|
2021-09-20 23:39:19 +02:00
|
|
|
if (isatty(2))
|
|
|
|
opts.flags |= MIDX_PROGRESS;
|
pass subcommand "prefix" arguments to parse_options()
Recent commits such as bf0a6b65fc (builtin/multi-pack-index.c: let
parse-options parse subcommands, 2022-08-19) converted a few functions
to match our usual argc/argv/prefix conventions, but the prefix argument
remains unused.
However, there is a good use for it: they should pass it to their own
parse_options() functions, where it may be used to adjust the value of
any filename options. In all but one of these functions, there's no
behavior change, since they don't use OPT_FILENAME. But this is an
actual fix for one option, which you can see by modifying the test suite
like so:
diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
index 4fe57414c1..d0974d4371 100755
--- a/t/t5326-multi-pack-bitmaps.sh
+++ b/t/t5326-multi-pack-bitmaps.sh
@@ -186,7 +186,11 @@ test_expect_success 'writing a bitmap with --refs-snapshot' '
# Then again, but with a refs snapshot which only sees
# refs/tags/one.
- git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
+ (
+ mkdir subdir &&
+ cd subdir &&
+ git multi-pack-index write --bitmap --refs-snapshot=../snapshot
+ ) &&
test_path_is_file $midx &&
test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
I'd emphasize that this wasn't broken by bf0a6b65fc; it has been broken
all along, because the sub-function never got to see the prefix. It is
that commit which is actually enabling us to fix it (and which also
brought attention to the problem because it triggers -Wunused-parameter!)
The other functions changed here don't use OPT_FILENAME at all. In their
cases this isn't fixing anything visible, but it's following the usual
pattern and future-proofing them against somebody adding new options and
being surprised.
I didn't include a test for the one visible case above. We don't
generally test routine parse-options behavior for individual options.
The challenge here was finding the problem, and now that this has been
done, it's not likely to regress. Likewise, we could apply the patch
above to cover it "for free" but it makes reading the rest of the test
unnecessarily complicated.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-25 12:47:00 +02:00
|
|
|
argc = parse_options(argc, argv, prefix,
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
options, builtin_multi_pack_index_expire_usage,
|
2022-07-10 17:16:45 +02:00
|
|
|
0);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
if (argc)
|
|
|
|
usage_with_options(builtin_multi_pack_index_expire_usage,
|
|
|
|
options);
|
|
|
|
|
2021-10-26 23:01:18 +02:00
|
|
|
FREE_AND_NULL(options);
|
|
|
|
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
return expire_midx_packs(the_repository, opts.object_dir, opts.flags);
|
|
|
|
}
|
|
|
|
|
2022-08-19 18:04:05 +02:00
|
|
|
static int cmd_multi_pack_index_repack(int argc, const char **argv,
|
|
|
|
const char *prefix)
|
2018-07-12 21:39:20 +02:00
|
|
|
{
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
struct option *options;
|
|
|
|
static struct option builtin_multi_pack_index_repack_options[] = {
|
2019-06-11 01:35:26 +02:00
|
|
|
OPT_MAGNITUDE(0, "batch-size", &opts.batch_size,
|
|
|
|
N_("during repack, collect pack-files of smaller size into a batch that is larger than this size")),
|
2021-09-20 23:39:19 +02:00
|
|
|
OPT_BIT(0, "progress", &opts.flags,
|
|
|
|
N_("force progress reporting"), MIDX_PROGRESS),
|
2018-07-12 21:39:20 +02:00
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
options = add_common_options(builtin_multi_pack_index_repack_options);
|
|
|
|
|
2021-03-30 17:04:01 +02:00
|
|
|
trace2_cmd_mode(argv[0]);
|
|
|
|
|
2021-09-20 23:39:19 +02:00
|
|
|
if (isatty(2))
|
|
|
|
opts.flags |= MIDX_PROGRESS;
|
pass subcommand "prefix" arguments to parse_options()
Recent commits such as bf0a6b65fc (builtin/multi-pack-index.c: let
parse-options parse subcommands, 2022-08-19) converted a few functions
to match our usual argc/argv/prefix conventions, but the prefix argument
remains unused.
However, there is a good use for it: they should pass it to their own
parse_options() functions, where it may be used to adjust the value of
any filename options. In all but one of these functions, there's no
behavior change, since they don't use OPT_FILENAME. But this is an
actual fix for one option, which you can see by modifying the test suite
like so:
diff --git a/t/t5326-multi-pack-bitmaps.sh b/t/t5326-multi-pack-bitmaps.sh
index 4fe57414c1..d0974d4371 100755
--- a/t/t5326-multi-pack-bitmaps.sh
+++ b/t/t5326-multi-pack-bitmaps.sh
@@ -186,7 +186,11 @@ test_expect_success 'writing a bitmap with --refs-snapshot' '
# Then again, but with a refs snapshot which only sees
# refs/tags/one.
- git multi-pack-index write --bitmap --refs-snapshot=snapshot &&
+ (
+ mkdir subdir &&
+ cd subdir &&
+ git multi-pack-index write --bitmap --refs-snapshot=../snapshot
+ ) &&
test_path_is_file $midx &&
test_path_is_file $midx-$(midx_checksum $objdir).bitmap &&
I'd emphasize that this wasn't broken by bf0a6b65fc; it has been broken
all along, because the sub-function never got to see the prefix. It is
that commit which is actually enabling us to fix it (and which also
brought attention to the problem because it triggers -Wunused-parameter!)
The other functions changed here don't use OPT_FILENAME at all. In their
cases this isn't fixing anything visible, but it's following the usual
pattern and future-proofing them against somebody adding new options and
being surprised.
I didn't include a test for the one visible case above. We don't
generally test routine parse-options behavior for individual options.
The challenge here was finding the problem, and now that this has been
done, it's not likely to regress. Likewise, we could apply the patch
above to cover it "for free" but it makes reading the rest of the test
unnecessarily complicated.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2022-08-25 12:47:00 +02:00
|
|
|
argc = parse_options(argc, argv, prefix,
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
options,
|
|
|
|
builtin_multi_pack_index_repack_usage,
|
2022-07-10 17:16:45 +02:00
|
|
|
0);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
if (argc)
|
|
|
|
usage_with_options(builtin_multi_pack_index_repack_usage,
|
|
|
|
options);
|
|
|
|
|
|
|
|
FREE_AND_NULL(options);
|
|
|
|
|
|
|
|
return midx_repack(the_repository, opts.object_dir,
|
|
|
|
(size_t)opts.batch_size, opts.flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
int cmd_multi_pack_index(int argc, const char **argv,
|
|
|
|
const char *prefix)
|
|
|
|
{
|
2022-04-25 20:27:13 +02:00
|
|
|
int res;
|
2022-08-19 18:04:05 +02:00
|
|
|
parse_opt_subcommand_fn *fn = NULL;
|
|
|
|
struct option builtin_multi_pack_index_options[] = {
|
|
|
|
OPT_SUBCOMMAND("repack", &fn, cmd_multi_pack_index_repack),
|
|
|
|
OPT_SUBCOMMAND("write", &fn, cmd_multi_pack_index_write),
|
|
|
|
OPT_SUBCOMMAND("verify", &fn, cmd_multi_pack_index_verify),
|
|
|
|
OPT_SUBCOMMAND("expire", &fn, cmd_multi_pack_index_expire),
|
|
|
|
OPT_END(),
|
|
|
|
};
|
|
|
|
struct option *options = parse_options_concat(builtin_multi_pack_index_options, common_opts);
|
builtin/multi-pack-index.c: split sub-commands
Handle sub-commands of the 'git multi-pack-index' builtin (e.g.,
"write", "repack", etc.) separately from one another. This allows
sub-commands with unique options, without forcing cmd_multi_pack_index()
to reject invalid combinations itself.
This comes at the cost of some duplication and boilerplate. Luckily, the
duplication is reduced to a minimum, since common options are shared
among sub-commands due to a suggestion by Ævar. (Sub-commands do have to
retain the common options, too, since this builtin accepts common
options on either side of the sub-command).
Roughly speaking, cmd_multi_pack_index() parses options (including
common ones), and stops at the first non-option, which is the
sub-command. It then dispatches to the appropriate sub-command, which
parses the remaining options (also including common options).
Unknown options are kept by the sub-commands in order to detect their
presence (and complain that too many arguments were given).
Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2021-03-30 17:03:57 +02:00
|
|
|
|
2018-07-12 21:39:20 +02:00
|
|
|
git_config(git_default_config, NULL);
|
|
|
|
|
2022-04-25 20:27:13 +02:00
|
|
|
if (the_repository &&
|
|
|
|
the_repository->objects &&
|
|
|
|
the_repository->objects->odb)
|
|
|
|
opts.object_dir = xstrdup(the_repository->objects->odb->path);
|
|
|
|
|
2022-08-19 18:04:05 +02:00
|
|
|
argc = parse_options(argc, argv, prefix, options,
|
|
|
|
builtin_multi_pack_index_usage, 0);
|
|
|
|
FREE_AND_NULL(options);
|
|
|
|
|
|
|
|
res = fn(argc, argv, prefix);
|
2022-04-25 20:27:13 +02:00
|
|
|
|
|
|
|
free(opts.object_dir);
|
|
|
|
return res;
|
2018-07-12 21:39:20 +02:00
|
|
|
}
|