Merge branch 'kn/ref-migrate-skip-reflog'

"git refs migrate" can optionally be told not to migrate the reflog.

* kn/ref-migrate-skip-reflog:
  builtin/refs: add '--no-reflog' flag to drop reflogs
This commit is contained in:
Junio C Hamano
2025-02-27 15:23:00 -08:00
5 changed files with 44 additions and 11 deletions

View File

@@ -8,9 +8,9 @@ git-refs - Low-level access to refs
SYNOPSIS SYNOPSIS
-------- --------
[verse] [synopsis]
'git refs migrate' --ref-format=<format> [--dry-run] git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]
'git refs verify' [--strict] [--verbose] git refs verify [--strict] [--verbose]
DESCRIPTION DESCRIPTION
----------- -----------
@@ -43,6 +43,11 @@ include::ref-storage-format.adoc[]
can be used to double check that the migration works as expected before can be used to double check that the migration works as expected before
performing the actual migration. performing the actual migration.
--reflog::
--no-reflog::
Choose between migrating the reflog data to the new backend,
and discarding them. The default is "--reflog", to migrate.
The following options are specific to 'git refs verify': The following options are specific to 'git refs verify':
--strict:: --strict::

View File

@@ -30,6 +30,9 @@ static int cmd_refs_migrate(int argc, const char **argv, const char *prefix,
OPT_BIT(0, "dry-run", &flags, OPT_BIT(0, "dry-run", &flags,
N_("perform a non-destructive dry-run"), N_("perform a non-destructive dry-run"),
REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN), REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN),
OPT_BIT(0, "no-reflog", &flags,
N_("drop reflogs entirely during the migration"),
REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG),
OPT_END(), OPT_END(),
}; };
struct strbuf errbuf = STRBUF_INIT; struct strbuf errbuf = STRBUF_INIT;

8
refs.c
View File

@@ -3043,9 +3043,11 @@ int repo_migrate_ref_storage_format(struct repository *repo,
if (ret < 0) if (ret < 0)
goto done; goto done;
ret = refs_for_each_reflog(old_refs, migrate_one_reflog, &data); if (!(flags & REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG)) {
if (ret < 0) ret = refs_for_each_reflog(old_refs, migrate_one_reflog, &data);
goto done; if (ret < 0)
goto done;
}
ret = ref_transaction_commit(transaction, errbuf); ret = ref_transaction_commit(transaction, errbuf);
if (ret < 0) if (ret < 0)

5
refs.h
View File

@@ -1143,8 +1143,11 @@ int is_pseudo_ref(const char *refname);
* - REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN: perform a dry-run migration * - REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN: perform a dry-run migration
* without touching the main repository. The result will be written into a * without touching the main repository. The result will be written into a
* temporary ref storage directory. * temporary ref storage directory.
*
* - REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG: skip migration of reflogs.
*/ */
#define REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN (1 << 0) #define REPO_MIGRATE_REF_STORAGE_FORMAT_DRYRUN (1 << 0)
#define REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG (1 << 1)
/* /*
* Migrate the ref storage format used by the repository to the * Migrate the ref storage format used by the repository to the

View File

@@ -9,14 +9,21 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
# Migrate the provided repository from one format to the other and # Migrate the provided repository from one format to the other and
# verify that the references and logs are migrated over correctly. # verify that the references and logs are migrated over correctly.
# Usage: test_migration <repo> <format> <skip_reflog_verify> # Usage: test_migration <repo> <format> [<skip_reflog_verify> [<options...>]]
# <repo> is the relative path to the repo to be migrated. # <repo> is the relative path to the repo to be migrated.
# <format> is the ref format to be migrated to. # <format> is the ref format to be migrated to.
# <skip_reflog_verify> (true or false) whether to skip reflog verification. # <skip_reflog_verify> (default: false) whether to skip reflog verification.
# <options...> are other options be passed directly to 'git refs migrate'.
test_migration () { test_migration () {
repo=$1 && repo=$1 &&
format=$2 && format=$2 &&
skip_reflog_verify=${3:-false} && shift 2 &&
skip_reflog_verify=false &&
if test $# -ge 1
then
skip_reflog_verify=$1
shift
fi &&
git -C "$repo" for-each-ref --include-root-refs \ git -C "$repo" for-each-ref --include-root-refs \
--format='%(refname) %(objectname) %(symref)' >expect && --format='%(refname) %(objectname) %(symref)' >expect &&
if ! $skip_reflog_verify if ! $skip_reflog_verify
@@ -25,7 +32,7 @@ test_migration () {
git -C "$repo" reflog list >expect_log_list git -C "$repo" reflog list >expect_log_list
fi && fi &&
git -C "$repo" refs migrate --ref-format="$2" && git -C "$repo" refs migrate --ref-format="$format" "$@" &&
git -C "$repo" for-each-ref --include-root-refs \ git -C "$repo" for-each-ref --include-root-refs \
--format='%(refname) %(objectname) %(symref)' >actual && --format='%(refname) %(objectname) %(symref)' >actual &&
@@ -241,6 +248,19 @@ do
test_cmp expect.reflog actual.reflog test_cmp expect.reflog actual.reflog
) )
' '
test_expect_success "$from_format -> $to_format: skip reflog with --skip-reflog" '
test_when_finished "rm -rf repo" &&
git init --ref-format=$from_format repo &&
test_commit -C repo initial &&
# we see that the repository contains reflogs.
git -C repo reflog --all >reflogs &&
test_line_count = 2 reflogs &&
test_migration repo "$to_format" true --no-reflog &&
# there should be no reflogs post migration.
git -C repo reflog --all >reflogs &&
test_must_be_empty reflogs
'
done done
done done