Skip to content

Commit

Permalink
survey: add command line opts to select references
Browse files Browse the repository at this point in the history
By default we will scan all references in "refs/heads/", "refs/tags/"
and "refs/remotes/".

Add command line opts let the use ask for all refs or a subset of them
and to include a detached HEAD.

Signed-off-by: Jeff Hostetler <[email protected]>
  • Loading branch information
jeffhostetler authored and dscho committed Jul 17, 2024
1 parent d493e7b commit 891929e
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
34 changes: 34 additions & 0 deletions Documentation/git-survey.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,46 @@ As repositories grow to "monorepo" size, certain data shapes can cause
performance problems. `git-survey` attempts to measure and report on
known problem areas.

Ref Selection and Reachable Objects
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In this first analysis phase, `git survey` will iterate over the set of
requested branches, tags, and other refs and treewalk over all of the
reachable commits, trees, and blobs and generate various statistics.

OPTIONS
-------

--progress::
Show progress. This is automatically enabled when interactive.

Ref Selection
~~~~~~~~~~~~~

The following options control the set of refs that `git survey` will examine.
By default, `git survey` will look at tags, local branches, and remote refs.
If any of the following options are given, the default set is cleared and
only refs for the given options are added.

--all-refs::
Use all refs. This includes local branches, tags, remote refs,
notes, and stashes. This option overrides all of the following.

--branches::
Add local branches (`refs/heads/`) to the set.

--tags::
Add tags (`refs/tags/`) to the set.

--remotes::
Add remote branches (`refs/remote/`) to the set.

--detached::
Add HEAD to the set.

--other::
Add notes (`refs/notes/`) and stashes (`refs/stash/`) to the set.

OUTPUT
------

Expand Down
99 changes: 99 additions & 0 deletions builtin/survey.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,117 @@ static const char * const survey_usage[] = {
NULL,
};

struct survey_refs_wanted {
int want_all_refs; /* special override */

int want_branches;
int want_tags;
int want_remotes;
int want_detached;
int want_other; /* see FILTER_REFS_OTHERS -- refs/notes/, refs/stash/ */
};

/*
* The set of refs that we will search if the user doesn't select
* any on the command line.
*/
static struct survey_refs_wanted refs_if_unspecified = {
.want_all_refs = 0,

.want_branches = 1,
.want_tags = 1,
.want_remotes = 1,
.want_detached = 0,
.want_other = 0,
};

struct survey_opts {
int verbose;
int show_progress;
struct survey_refs_wanted refs;
};

static struct survey_opts survey_opts = {
.verbose = 0,
.show_progress = -1, /* defaults to isatty(2) */

.refs.want_all_refs = -1,

.refs.want_branches = -1, /* default these to undefined */
.refs.want_tags = -1,
.refs.want_remotes = -1,
.refs.want_detached = -1,
.refs.want_other = -1,
};

/*
* After parsing the command line arguments, figure out which refs we
* should scan.
*
* If ANY were given in positive sense, then we ONLY include them and
* do not use the builtin values.
*/
static void fixup_refs_wanted(void)
{
struct survey_refs_wanted *rw = &survey_opts.refs;

/*
* `--all-refs` overrides and enables everything.
*/
if (rw->want_all_refs == 1) {
rw->want_branches = 1;
rw->want_tags = 1;
rw->want_remotes = 1;
rw->want_detached = 1;
rw->want_other = 1;
return;
}

/*
* If none of the `--<ref-type>` were given, we assume all
* of the builtin unspecified values.
*/
if (rw->want_branches == -1 &&
rw->want_tags == -1 &&
rw->want_remotes == -1 &&
rw->want_detached == -1 &&
rw->want_other == -1) {
*rw = refs_if_unspecified;
return;
}

/*
* Since we only allow positive boolean values on the command
* line, we will only have true values where they specified
* a `--<ref-type>`.
*
* So anything that still has an unspecified value should be
* set to false.
*/
if (rw->want_branches == -1)
rw->want_branches = 0;
if (rw->want_tags == -1)
rw->want_tags = 0;
if (rw->want_remotes == -1)
rw->want_remotes = 0;
if (rw->want_detached == -1)
rw->want_detached = 0;
if (rw->want_other == -1)
rw->want_other = 0;
}

static struct option survey_options[] = {
OPT__VERBOSE(&survey_opts.verbose, N_("verbose output")),
OPT_BOOL(0, "progress", &survey_opts.show_progress, N_("show progress")),

OPT_BOOL_F(0, "all-refs", &survey_opts.refs.want_all_refs, N_("include all refs"), PARSE_OPT_NONEG),

OPT_BOOL_F(0, "branches", &survey_opts.refs.want_branches, N_("include branches"), PARSE_OPT_NONEG),
OPT_BOOL_F(0, "tags", &survey_opts.refs.want_tags, N_("include tags"), PARSE_OPT_NONEG),
OPT_BOOL_F(0, "remotes", &survey_opts.refs.want_remotes, N_("include all remotes refs"), PARSE_OPT_NONEG),
OPT_BOOL_F(0, "detached", &survey_opts.refs.want_detached, N_("include detached HEAD"), PARSE_OPT_NONEG),
OPT_BOOL_F(0, "other", &survey_opts.refs.want_other, N_("include notes and stashes"), PARSE_OPT_NONEG),

OPT_END(),
};

Expand Down Expand Up @@ -53,6 +151,7 @@ int cmd_survey(int argc, const char **argv, const char *prefix)

if (survey_opts.show_progress < 0)
survey_opts.show_progress = isatty(2);
fixup_refs_wanted();

return 0;
}

0 comments on commit 891929e

Please sign in to comment.