Skip to content

Commit 40a163f

Browse files
committed
Merge branch 'ps/ref-storage-migration'
A new command has been added to migrate a repository that uses the files backend for its ref storage to use the reftable backend, with limitations. * ps/ref-storage-migration: builtin/refs: new command to migrate ref storage formats refs: implement logic to migrate between ref storage formats refs: implement removal of ref storages worktree: don't store main worktree twice reftable: inline `merged_table_release()` refs/files: fix NULL pointer deref when releasing ref store refs/files: extract function to iterate through root refs refs/files: refactor `add_pseudoref_and_head_entries()` refs: allow to skip creation of reflog entries refs: pass storage format to `ref_store_init()` explicitly refs: convert ref storage format to an enum setup: unset ref storage when reinitializing repository version
2 parents dfd668f + 25a0023 commit 40a163f

26 files changed

+979
-82
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
/git-rebase
127127
/git-receive-pack
128128
/git-reflog
129+
/git-refs
129130
/git-remote
130131
/git-remote-http
131132
/git-remote-https

Documentation/git-refs.txt

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
git-refs(1)
2+
===========
3+
4+
NAME
5+
----
6+
git-refs - Low-level access to refs
7+
8+
9+
SYNOPSIS
10+
--------
11+
[verse]
12+
'git refs migrate' --ref-format=<format> [--dry-run]
13+
14+
DESCRIPTION
15+
-----------
16+
17+
This command provides low-level access to refs.
18+
19+
COMMANDS
20+
--------
21+
22+
migrate::
23+
Migrate ref store between different formats.
24+
25+
OPTIONS
26+
-------
27+
28+
The following options are specific to 'git refs migrate':
29+
30+
--ref-format=<format>::
31+
The ref format to migrate the ref store to. Can be one of:
32+
+
33+
include::ref-storage-format.txt[]
34+
35+
--dry-run::
36+
Perform the migration, but do not modify the repository. The migrated
37+
refs will be written into a separate directory that can be inspected
38+
separately. The name of the directory will be reported on stdout. This
39+
can be used to double check that the migration works as expected before
40+
performing the actual migration.
41+
42+
KNOWN LIMITATIONS
43+
-----------------
44+
45+
The ref format migration has several known limitations in its current form:
46+
47+
* It is not possible to migrate repositories that have reflogs.
48+
49+
* It is not possible to migrate repositories that have worktrees.
50+
51+
* There is no way to block concurrent writes to the repository during an
52+
ongoing migration. Concurrent writes can lead to an inconsistent migrated
53+
state. Users are expected to block writes on a higher level. If your
54+
repository is registered for scheduled maintenance, it is recommended to
55+
unregister it first with git-maintenance(1).
56+
57+
These limitations may eventually be lifted.
58+
59+
GIT
60+
---
61+
Part of the linkgit:git[1] suite

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,7 @@ BUILTIN_OBJS += builtin/read-tree.o
12811281
BUILTIN_OBJS += builtin/rebase.o
12821282
BUILTIN_OBJS += builtin/receive-pack.o
12831283
BUILTIN_OBJS += builtin/reflog.o
1284+
BUILTIN_OBJS += builtin/refs.o
12841285
BUILTIN_OBJS += builtin/remote-ext.o
12851286
BUILTIN_OBJS += builtin/remote-fd.o
12861287
BUILTIN_OBJS += builtin/remote.o

builtin.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ int cmd_rebase(int argc, const char **argv, const char *prefix);
207207
int cmd_rebase__interactive(int argc, const char **argv, const char *prefix);
208208
int cmd_receive_pack(int argc, const char **argv, const char *prefix);
209209
int cmd_reflog(int argc, const char **argv, const char *prefix);
210+
int cmd_refs(int argc, const char **argv, const char *prefix);
210211
int cmd_remote(int argc, const char **argv, const char *prefix);
211212
int cmd_remote_ext(int argc, const char **argv, const char *prefix);
212213
int cmd_remote_fd(int argc, const char **argv, const char *prefix);

builtin/clone.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -970,7 +970,7 @@ int cmd_clone(int argc, const char **argv, const char *prefix)
970970
int submodule_progress;
971971
int filter_submodules = 0;
972972
int hash_algo;
973-
unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
973+
enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
974974
const int do_not_override_repo_unix_permissions = -1;
975975

976976
struct transport_ls_refs_options transport_ls_refs_options =

builtin/init-db.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ int cmd_init_db(int argc, const char **argv, const char *prefix)
8181
const char *ref_format = NULL;
8282
const char *initial_branch = NULL;
8383
int hash_algo = GIT_HASH_UNKNOWN;
84-
unsigned int ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
84+
enum ref_storage_format ref_storage_format = REF_STORAGE_FORMAT_UNKNOWN;
8585
int init_shared_repository = -1;
8686
const struct option init_db_options[] = {
8787
OPT_STRING(0, "template", &template_dir, N_("template-directory"),

builtin/refs.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
#include "builtin.h"
2+
#include "parse-options.h"
3+
#include "refs.h"
4+
#include "repository.h"
5+
#include "strbuf.h"
6+
7+
#define REFS_MIGRATE_USAGE \
8+
N_("git refs migrate --ref-format=<format> [--dry-run]")
9+
10+
static int cmd_refs_migrate(int argc, const char **argv, const char *prefix)
11+
{
12+
const char * const migrate_usage[] = {
13+
REFS_MIGRATE_USAGE,
14+
NULL,
15+
};
16+
const char *format_str = NULL;
17+
enum ref_storage_format format;
18+
unsigned int flags = 0;
19+
struct option options[] = {
20+
OPT_STRING_F(0, "ref-format", &format_str, N_("format"),
21+
N_("specify the reference format to convert to"),
22+
PARSE_OPT_NONEG),
23+
OPT_BIT(0, "dry-run", &flags,
24+
N_("perform a non-destructive dry-run"),
25+
REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN),
26+
OPT_END(),
27+
};
28+
struct strbuf errbuf = STRBUF_INIT;
29+
int err;
30+
31+
argc = parse_options(argc, argv, prefix, options, migrate_usage, 0);
32+
if (argc)
33+
usage(_("too many arguments"));
34+
if (!format_str)
35+
usage(_("missing --ref-format=<format>"));
36+
37+
format = ref_storage_format_by_name(format_str);
38+
if (format == REF_STORAGE_FORMAT_UNKNOWN) {
39+
err = error(_("unknown ref storage format '%s'"), format_str);
40+
goto out;
41+
}
42+
43+
if (the_repository->ref_storage_format == format) {
44+
err = error(_("repository already uses '%s' format"),
45+
ref_storage_format_to_name(format));
46+
goto out;
47+
}
48+
49+
if (repo_migrate_ref_storage_format(the_repository, format, flags, &errbuf) < 0) {
50+
err = error("%s", errbuf.buf);
51+
goto out;
52+
}
53+
54+
err = 0;
55+
56+
out:
57+
strbuf_release(&errbuf);
58+
return err;
59+
}
60+
61+
int cmd_refs(int argc, const char **argv, const char *prefix)
62+
{
63+
const char * const refs_usage[] = {
64+
REFS_MIGRATE_USAGE,
65+
NULL,
66+
};
67+
parse_opt_subcommand_fn *fn = NULL;
68+
struct option opts[] = {
69+
OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate),
70+
OPT_END(),
71+
};
72+
73+
argc = parse_options(argc, argv, prefix, opts, refs_usage, 0);
74+
return fn(argc, argv, prefix);
75+
}

command-list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ git-read-tree plumbingmanipulators
157157
git-rebase mainporcelain history
158158
git-receive-pack synchelpers
159159
git-reflog ancillarymanipulators complete
160+
git-refs ancillarymanipulators complete
160161
git-remote ancillarymanipulators complete
161162
git-repack ancillarymanipulators complete
162163
git-replace ancillarymanipulators complete

git.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,7 @@ static struct cmd_struct commands[] = {
594594
{ "rebase", cmd_rebase, RUN_SETUP | NEED_WORK_TREE },
595595
{ "receive-pack", cmd_receive_pack },
596596
{ "reflog", cmd_reflog, RUN_SETUP },
597+
{ "refs", cmd_refs, RUN_SETUP },
597598
{ "remote", cmd_remote, RUN_SETUP },
598599
{ "remote-ext", cmd_remote_ext, NO_PARSEOPT },
599600
{ "remote-fd", cmd_remote_fd, NO_PARSEOPT },

0 commit comments

Comments
 (0)