Skip to content

Commit db0babf

Browse files
committed
Merge branch 'ms/refs-optimize'
"git refs optimize" is added for not very well explained reason despite it does the same thing as "git pack-refs"... * ms/refs-optimize: t: add test for git refs optimize subcommand t0601: refactor tests to be shareable builtin/refs: add optimize subcommand doc: pack-refs: factor out common options builtin/pack-refs: factor out core logic into a shared library builtin/pack-refs: convert to use the generic refs_optimize() API reftable-backend: implement 'optimize' action files-backend: implement 'optimize' action refs: add a generic 'optimize' API
2 parents fd13909 + c44afd6 commit db0babf

18 files changed

+647
-530
lines changed

Documentation/git-pack-refs.adoc

Lines changed: 1 addition & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -45,58 +45,7 @@ unpacked.
4545
OPTIONS
4646
-------
4747

48-
--all::
49-
50-
The command by default packs all tags and refs that are already
51-
packed, and leaves other refs
52-
alone. This is because branches are expected to be actively
53-
developed and packing their tips does not help performance.
54-
This option causes all refs to be packed as well, with the exception
55-
of hidden refs, broken refs, and symbolic refs. Useful for a repository
56-
with many branches of historical interests.
57-
58-
--no-prune::
59-
60-
The command usually removes loose refs under `$GIT_DIR/refs`
61-
hierarchy after packing them. This option tells it not to.
62-
63-
--auto::
64-
65-
Pack refs as needed depending on the current state of the ref database. The
66-
behavior depends on the ref format used by the repository and may change in the
67-
future.
68-
+
69-
- "files": Loose references are packed into the `packed-refs` file
70-
based on the ratio of loose references to the size of the
71-
`packed-refs` file. The bigger the `packed-refs` file, the more loose
72-
references need to exist before we repack.
73-
+
74-
- "reftable": Tables are compacted such that they form a geometric
75-
sequence. For two tables N and N+1, where N+1 is newer, this
76-
maintains the property that N is at least twice as big as N+1. Only
77-
tables that violate this property are compacted.
78-
79-
--include <pattern>::
80-
81-
Pack refs based on a `glob(7)` pattern. Repetitions of this option
82-
accumulate inclusion patterns. If a ref is both included in `--include` and
83-
`--exclude`, `--exclude` takes precedence. Using `--include` will preclude all
84-
tags from being included by default. Symbolic refs and broken refs will never
85-
be packed. When used with `--all`, it will be a noop. Use `--no-include` to clear
86-
and reset the list of patterns.
87-
88-
--exclude <pattern>::
89-
90-
Do not pack refs matching the given `glob(7)` pattern. Repetitions of this option
91-
accumulate exclusion patterns. Use `--no-exclude` to clear and reset the list of
92-
patterns. If a ref is already packed, including it with `--exclude` will not
93-
unpack it.
94-
+
95-
When used with `--all`, pack only loose refs which do not match any of
96-
the provided `--exclude` patterns.
97-
+
98-
When used with `--include`, refs provided to `--include`, minus refs that are
99-
provided to `--exclude` will be packed.
48+
include::pack-refs-options.adoc[]
10049

10150

10251
BUGS

Documentation/git-refs.adoc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ git refs list [--count=<count>] [--shell|--perl|--python|--tcl]
1919
[(--exclude=<pattern>)...] [--start-after=<marker>]
2020
[ --stdin | (<pattern>...)]
2121
git refs exists <ref>
22+
git refs optimize [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]
2223

2324
DESCRIPTION
2425
-----------
@@ -45,6 +46,11 @@ exists::
4546
failed with an error other than the reference being missing. This does
4647
not verify whether the reference resolves to an actual object.
4748

49+
optimize::
50+
Optimizes references to improve repository performance and reduce disk
51+
usage. This subcommand is an alias for linkgit:git-pack-refs[1] and
52+
offers identical functionality.
53+
4854
OPTIONS
4955
-------
5056

@@ -80,6 +86,10 @@ The following options are specific to 'git refs list':
8086

8187
include::for-each-ref-options.adoc[]
8288

89+
The following options are specific to 'git refs optimize':
90+
91+
include::pack-refs-options.adoc[]
92+
8393
KNOWN LIMITATIONS
8494
-----------------
8595

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
--all::
2+
3+
The command by default packs all tags and refs that are already
4+
packed, and leaves other refs
5+
alone. This is because branches are expected to be actively
6+
developed and packing their tips does not help performance.
7+
This option causes all refs to be packed as well, with the exception
8+
of hidden refs, broken refs, and symbolic refs. Useful for a repository
9+
with many branches of historical interests.
10+
11+
--no-prune::
12+
13+
The command usually removes loose refs under `$GIT_DIR/refs`
14+
hierarchy after packing them. This option tells it not to.
15+
16+
--auto::
17+
18+
Pack refs as needed depending on the current state of the ref database. The
19+
behavior depends on the ref format used by the repository and may change in the
20+
future.
21+
+
22+
- "files": Loose references are packed into the `packed-refs` file
23+
based on the ratio of loose references to the size of the
24+
`packed-refs` file. The bigger the `packed-refs` file, the more loose
25+
references need to exist before we repack.
26+
+
27+
- "reftable": Tables are compacted such that they form a geometric
28+
sequence. For two tables N and N+1, where N+1 is newer, this
29+
maintains the property that N is at least twice as big as N+1. Only
30+
tables that violate this property are compacted.
31+
32+
--include <pattern>::
33+
34+
Pack refs based on a `glob(7)` pattern. Repetitions of this option
35+
accumulate inclusion patterns. If a ref is both included in `--include` and
36+
`--exclude`, `--exclude` takes precedence. Using `--include` will preclude all
37+
tags from being included by default. Symbolic refs and broken refs will never
38+
be packed. When used with `--all`, it will be a noop. Use `--no-include` to clear
39+
and reset the list of patterns.
40+
41+
--exclude <pattern>::
42+
43+
Do not pack refs matching the given `glob(7)` pattern. Repetitions of this option
44+
accumulate exclusion patterns. Use `--no-exclude` to clear and reset the list of
45+
patterns. If a ref is already packed, including it with `--exclude` will not
46+
unpack it.
47+
+
48+
When used with `--all`, pack only loose refs which do not match any of
49+
the provided `--exclude` patterns.
50+
+
51+
When used with `--include`, refs provided to `--include`, minus refs that are
52+
provided to `--exclude` will be packed.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1093,6 +1093,7 @@ LIB_OBJS += pack-bitmap.o
10931093
LIB_OBJS += pack-check.o
10941094
LIB_OBJS += pack-mtimes.o
10951095
LIB_OBJS += pack-objects.o
1096+
LIB_OBJS += pack-refs.o
10961097
LIB_OBJS += pack-revindex.o
10971098
LIB_OBJS += pack-write.o
10981099
LIB_OBJS += packfile.o

builtin/pack-refs.c

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,16 @@
11
#include "builtin.h"
2-
#include "config.h"
3-
#include "environment.h"
42
#include "gettext.h"
5-
#include "parse-options.h"
6-
#include "refs.h"
7-
#include "revision.h"
8-
9-
static char const * const pack_refs_usage[] = {
10-
N_("git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]"),
11-
NULL
12-
};
3+
#include "pack-refs.h"
134

145
int cmd_pack_refs(int argc,
156
const char **argv,
167
const char *prefix,
178
struct repository *repo)
189
{
19-
struct ref_exclusions excludes = REF_EXCLUSIONS_INIT;
20-
struct string_list included_refs = STRING_LIST_INIT_NODUP;
21-
struct pack_refs_opts pack_refs_opts = {
22-
.exclusions = &excludes,
23-
.includes = &included_refs,
24-
.flags = PACK_REFS_PRUNE,
25-
};
26-
struct string_list option_excluded_refs = STRING_LIST_INIT_NODUP;
27-
struct string_list_item *item;
28-
int pack_all = 0;
29-
int ret;
30-
31-
struct option opts[] = {
32-
OPT_BOOL(0, "all", &pack_all, N_("pack everything")),
33-
OPT_BIT(0, "prune", &pack_refs_opts.flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE),
34-
OPT_BIT(0, "auto", &pack_refs_opts.flags, N_("auto-pack refs as needed"), PACK_REFS_AUTO),
35-
OPT_STRING_LIST(0, "include", pack_refs_opts.includes, N_("pattern"),
36-
N_("references to include")),
37-
OPT_STRING_LIST(0, "exclude", &option_excluded_refs, N_("pattern"),
38-
N_("references to exclude")),
39-
OPT_END(),
10+
static char const * const pack_refs_usage[] = {
11+
N_("git pack-refs " PACK_REFS_OPTS),
12+
NULL
4013
};
41-
repo_config(repo, git_default_config, NULL);
42-
if (parse_options(argc, argv, prefix, opts, pack_refs_usage, 0))
43-
usage_with_options(pack_refs_usage, opts);
44-
45-
for_each_string_list_item(item, &option_excluded_refs)
46-
add_ref_exclusion(pack_refs_opts.exclusions, item->string);
47-
48-
if (pack_all)
49-
string_list_append(pack_refs_opts.includes, "*");
50-
51-
if (!pack_refs_opts.includes->nr)
52-
string_list_append(pack_refs_opts.includes, "refs/tags/*");
53-
54-
ret = refs_pack_refs(get_main_ref_store(repo), &pack_refs_opts);
5514

56-
clear_ref_exclusions(&excludes);
57-
string_list_clear(&included_refs, 0);
58-
string_list_clear(&option_excluded_refs, 0);
59-
return ret;
15+
return pack_refs_core(argc, argv, prefix, repo, pack_refs_usage);
6016
}

builtin/refs.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include "builtin.h"
33
#include "config.h"
44
#include "fsck.h"
5+
#include "pack-refs.h"
56
#include "parse-options.h"
67
#include "refs.h"
78
#include "strbuf.h"
@@ -18,6 +19,9 @@
1819
#define REFS_EXISTS_USAGE \
1920
N_("git refs exists <ref>")
2021

22+
#define REFS_OPTIMIZE_USAGE \
23+
N_("git refs optimize " PACK_REFS_OPTS)
24+
2125
static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
2226
struct repository *repo UNUSED)
2327
{
@@ -159,6 +163,17 @@ static int cmd_refs_exists(int argc, const char **argv, const char *prefix,
159163
return ret;
160164
}
161165

166+
static int cmd_refs_optimize(int argc, const char **argv, const char *prefix,
167+
struct repository *repo)
168+
{
169+
static char const * const refs_optimize_usage[] = {
170+
REFS_OPTIMIZE_USAGE,
171+
NULL
172+
};
173+
174+
return pack_refs_core(argc, argv, prefix, repo, refs_optimize_usage);
175+
}
176+
162177
int cmd_refs(int argc,
163178
const char **argv,
164179
const char *prefix,
@@ -169,6 +184,7 @@ int cmd_refs(int argc,
169184
REFS_VERIFY_USAGE,
170185
"git refs list " COMMON_USAGE_FOR_EACH_REF,
171186
REFS_EXISTS_USAGE,
187+
REFS_OPTIMIZE_USAGE,
172188
NULL,
173189
};
174190
parse_opt_subcommand_fn *fn = NULL;
@@ -177,6 +193,7 @@ int cmd_refs(int argc,
177193
OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify),
178194
OPT_SUBCOMMAND("list", &fn, cmd_refs_list),
179195
OPT_SUBCOMMAND("exists", &fn, cmd_refs_exists),
196+
OPT_SUBCOMMAND("optimize", &fn, cmd_refs_optimize),
180197
OPT_END(),
181198
};
182199

meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ libgit_sources = [
406406
'pack-check.c',
407407
'pack-mtimes.c',
408408
'pack-objects.c',
409+
'pack-refs.c',
409410
'pack-revindex.c',
410411
'pack-write.c',
411412
'packfile.c',

pack-refs.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#include "builtin.h"
2+
#include "config.h"
3+
#include "environment.h"
4+
#include "pack-refs.h"
5+
#include "parse-options.h"
6+
#include "refs.h"
7+
#include "revision.h"
8+
9+
int pack_refs_core(int argc,
10+
const char **argv,
11+
const char *prefix,
12+
struct repository *repo,
13+
const char * const *usage_opts)
14+
{
15+
struct ref_exclusions excludes = REF_EXCLUSIONS_INIT;
16+
struct string_list included_refs = STRING_LIST_INIT_NODUP;
17+
struct pack_refs_opts pack_refs_opts = {
18+
.exclusions = &excludes,
19+
.includes = &included_refs,
20+
.flags = PACK_REFS_PRUNE,
21+
};
22+
struct string_list option_excluded_refs = STRING_LIST_INIT_NODUP;
23+
struct string_list_item *item;
24+
int pack_all = 0;
25+
int ret;
26+
27+
struct option opts[] = {
28+
OPT_BOOL(0, "all", &pack_all, N_("pack everything")),
29+
OPT_BIT(0, "prune", &pack_refs_opts.flags, N_("prune loose refs (default)"), PACK_REFS_PRUNE),
30+
OPT_BIT(0, "auto", &pack_refs_opts.flags, N_("auto-pack refs as needed"), PACK_REFS_AUTO),
31+
OPT_STRING_LIST(0, "include", pack_refs_opts.includes, N_("pattern"),
32+
N_("references to include")),
33+
OPT_STRING_LIST(0, "exclude", &option_excluded_refs, N_("pattern"),
34+
N_("references to exclude")),
35+
OPT_END(),
36+
};
37+
repo_config(repo, git_default_config, NULL);
38+
if (parse_options(argc, argv, prefix, opts, usage_opts, 0))
39+
usage_with_options(usage_opts, opts);
40+
41+
for_each_string_list_item(item, &option_excluded_refs)
42+
add_ref_exclusion(pack_refs_opts.exclusions, item->string);
43+
44+
if (pack_all)
45+
string_list_append(pack_refs_opts.includes, "*");
46+
47+
if (!pack_refs_opts.includes->nr)
48+
string_list_append(pack_refs_opts.includes, "refs/tags/*");
49+
50+
ret = refs_optimize(get_main_ref_store(repo), &pack_refs_opts);
51+
52+
clear_ref_exclusions(&excludes);
53+
string_list_clear(&included_refs, 0);
54+
string_list_clear(&option_excluded_refs, 0);
55+
return ret;
56+
}

pack-refs.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef PACK_REFS_H
2+
#define PACK_REFS_H
3+
4+
struct repository;
5+
6+
/*
7+
* Shared usage string for options common to git-pack-refs(1)
8+
* and git-refs-optimize(1). The command-specific part (e.g., "git refs optimize ")
9+
* must be prepended by the caller.
10+
*/
11+
#define PACK_REFS_OPTS \
12+
"[--all] [--no-prune] [--auto] [--include <pattern>] [--exclude <pattern>]"
13+
14+
/*
15+
* The core logic for pack-refs and its clones.
16+
*/
17+
int pack_refs_core(int argc,
18+
const char **argv,
19+
const char *prefix,
20+
struct repository *repo,
21+
const char * const *usage_opts);
22+
23+
#endif /* PACK_REFS_H */

refs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,6 +2304,11 @@ int refs_pack_refs(struct ref_store *refs, struct pack_refs_opts *opts)
23042304
return refs->be->pack_refs(refs, opts);
23052305
}
23062306

2307+
int refs_optimize(struct ref_store *refs, struct pack_refs_opts *opts)
2308+
{
2309+
return refs->be->optimize(refs, opts);
2310+
}
2311+
23072312
int peel_iterated_oid(struct repository *r, const struct object_id *base, struct object_id *peeled)
23082313
{
23092314
if (current_ref_iter &&

0 commit comments

Comments
 (0)