Browse Source

builtin/commit-graph.c: support for '--split[=<strategy>]'

With '--split', the commit-graph machinery writes new commits in another
incremental commit-graph which is part of the existing chain, and
optionally decides to condense the chain into a single commit-graph.
This is done to ensure that the asymptotic behavior of looking up a
commit in an incremental chain is not dominated by the number of
incrementals in that chain. It can be controlled by the '--max-commits'
and '--size-multiple' options.

In the next two commits, we will introduce additional splitting
strategies that can exert additional control over:

  - when a split commit-graph is and isn't written, and

  - when the existing commit-graph chain is discarded completely and
    replaced with another graph

To prepare for this, make '--split' take an optional strategy (as in
'--split[=<strategy>]'), and add a new enum to describe which strategy
is being used. For now, no strategies are given, and the only enumerated
value is 'COMMIT_GRAPH_SPLIT_UNSPECIFIED', indicating the absence of a
strategy.

Signed-off-by: Taylor Blau <me@ttaylorr.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Taylor Blau 5 years ago committed by Junio C Hamano
parent
commit
4f027355f6
  1. 11
      Documentation/git-commit-graph.txt
  2. 26
      builtin/commit-graph.c
  3. 5
      commit-graph.h

11
Documentation/git-commit-graph.txt

@ -57,11 +57,12 @@ or `--stdin-packs`.)
With the `--append` option, include all commits that are present in the With the `--append` option, include all commits that are present in the
existing commit-graph file. existing commit-graph file.
+ +
With the `--split` option, write the commit-graph as a chain of multiple With the `--split[=<strategy>]` option, write the commit-graph as a
commit-graph files stored in `<dir>/info/commit-graphs`. The new commits chain of multiple commit-graph files stored in
not already in the commit-graph are added in a new "tip" file. This file `<dir>/info/commit-graphs`. Commit-graph layers are merged based on the
is merged with the existing file if the following merge conditions are strategy and other splitting options. The new commits not already in the
met: commit-graph are added in a new "tip" file. This file is merged with the
existing file if the following merge conditions are met:
+ +
* If `--size-multiple=<X>` is not specified, let `X` equal 2. If the new * If `--size-multiple=<X>` is not specified, let `X` equal 2. If the new
tip file would have `N` commits and the previous tip has `M` commits and tip file would have `N` commits and the previous tip has `M` commits and

26
builtin/commit-graph.c

@ -9,7 +9,9 @@


static char const * const builtin_commit_graph_usage[] = { static char const * const builtin_commit_graph_usage[] = {
N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"), N_("git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]"),
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] [--[no-]progress] <split options>"), N_("git commit-graph write [--object-dir <objdir>] [--append] "
"[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] "
"[--[no-]progress] <split options>"),
NULL NULL
}; };


@ -19,7 +21,9 @@ static const char * const builtin_commit_graph_verify_usage[] = {
}; };


static const char * const builtin_commit_graph_write_usage[] = { static const char * const builtin_commit_graph_write_usage[] = {
N_("git commit-graph write [--object-dir <objdir>] [--append|--split] [--reachable|--stdin-packs|--stdin-commits] [--[no-]progress] <split options>"), N_("git commit-graph write [--object-dir <objdir>] [--append] "
"[--split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] "
"[--[no-]progress] <split options>"),
NULL NULL
}; };


@ -111,6 +115,18 @@ static int graph_verify(int argc, const char **argv)
extern int read_replace_refs; extern int read_replace_refs;
static struct split_commit_graph_opts split_opts; static struct split_commit_graph_opts split_opts;


static int write_option_parse_split(const struct option *opt, const char *arg,
int unset)
{
opts.split = 1;
if (!arg)
return 0;

die(_("unrecognized --split argument, %s"), arg);

return 0;
}

static int graph_write(int argc, const char **argv) static int graph_write(int argc, const char **argv)
{ {
struct string_list *pack_indexes = NULL; struct string_list *pack_indexes = NULL;
@ -133,8 +149,10 @@ static int graph_write(int argc, const char **argv)
OPT_BOOL(0, "append", &opts.append, OPT_BOOL(0, "append", &opts.append,
N_("include all commits already in the commit-graph file")), N_("include all commits already in the commit-graph file")),
OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")), OPT_BOOL(0, "progress", &opts.progress, N_("force progress reporting")),
OPT_BOOL(0, "split", &opts.split, OPT_CALLBACK_F(0, "split", &split_opts.flags, NULL,
N_("allow writing an incremental commit-graph file")), N_("allow writing an incremental commit-graph file"),
PARSE_OPT_OPTARG | PARSE_OPT_NONEG,
write_option_parse_split),
OPT_INTEGER(0, "max-commits", &split_opts.max_commits, OPT_INTEGER(0, "max-commits", &split_opts.max_commits,
N_("maximum number of commits in a non-base split commit-graph")), N_("maximum number of commits in a non-base split commit-graph")),
OPT_INTEGER(0, "size-multiple", &split_opts.size_multiple, OPT_INTEGER(0, "size-multiple", &split_opts.size_multiple,

5
commit-graph.h

@ -82,10 +82,15 @@ enum commit_graph_write_flags {
COMMIT_GRAPH_WRITE_CHECK_OIDS = (1 << 3) COMMIT_GRAPH_WRITE_CHECK_OIDS = (1 << 3)
}; };


enum commit_graph_split_flags {
COMMIT_GRAPH_SPLIT_UNSPECIFIED = 0
};

struct split_commit_graph_opts { struct split_commit_graph_opts {
int size_multiple; int size_multiple;
int max_commits; int max_commits;
timestamp_t expire_time; timestamp_t expire_time;
enum commit_graph_split_flags flags;
}; };


/* /*

Loading…
Cancel
Save