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
maint
Junio C Hamano 2025-02-27 15:23:00 -08:00
commit 3c0f4abaf5
5 changed files with 44 additions and 11 deletions

View File

@ -8,9 +8,9 @@ git-refs - Low-level access to refs

SYNOPSIS
--------
[verse]
'git refs migrate' --ref-format=<format> [--dry-run]
'git refs verify' [--strict] [--verbose]
[synopsis]
git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]
git refs verify [--strict] [--verbose]

DESCRIPTION
-----------
@ -43,6 +43,11 @@ include::ref-storage-format.adoc[]
can be used to double check that the migration works as expected before
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':

--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,
N_("perform a non-destructive dry-run"),
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(),
};
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)
goto done;

ret = refs_for_each_reflog(old_refs, migrate_one_reflog, &data);
if (ret < 0)
goto done;
if (!(flags & REPO_MIGRATE_REF_STORAGE_FORMAT_SKIP_REFLOG)) {
ret = refs_for_each_reflog(old_refs, migrate_one_reflog, &data);
if (ret < 0)
goto done;
}

ret = ref_transaction_commit(transaction, errbuf);
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
* without touching the main repository. The result will be written into a
* 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

View File

@ -9,14 +9,21 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME

# Migrate the provided repository from one format to the other and
# 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.
# <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 () {
repo=$1 &&
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 \
--format='%(refname) %(objectname) %(symref)' >expect &&
if ! $skip_reflog_verify
@ -25,7 +32,7 @@ test_migration () {
git -C "$repo" reflog list >expect_log_list
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 \
--format='%(refname) %(objectname) %(symref)' >actual &&
@ -241,6 +248,19 @@ do
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