From: Junio C Hamano Date: Thu, 21 Aug 2025 20:46:57 +0000 (-0700) Subject: Merge branch 'ps/reflog-migrate-fixes' X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c3c8b6910a7cd3d5a25522d3fd6925083048be24;p=thirdparty%2Fgit.git Merge branch 'ps/reflog-migrate-fixes' "git refs migrate" to migrate the reflog entries from a refs backend to another had a handful of bugs squashed. * ps/reflog-migrate-fixes: refs: fix invalid old object IDs when migrating reflogs refs: stop unsetting REF_HAVE_OLD for log-only updates refs/files: detect race when generating reflog entry for HEAD refs: fix identity for migrated reflogs ident: fix type of string length parameter builtin/reflog: implement subcommand to write new entries refs: export `ref_transaction_update_reflog()` builtin/reflog: improve grouping of subcommands Documentation/git-reflog: convert to use synopsis type --- c3c8b6910a7cd3d5a25522d3fd6925083048be24 diff --cc builtin/reflog.c index 1db26aa65f,a1b4e02204..c8f6b93d60 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@@ -3,6 -3,8 +3,8 @@@ #include "builtin.h" #include "config.h" #include "gettext.h" + #include "hex.h" -#include "object-store.h" ++#include "odb.h" #include "revision.h" #include "reachable.h" #include "wildmatch.h" @@@ -395,6 -403,59 +406,59 @@@ static int cmd_reflog_drop(int argc, co return ret; } + static int cmd_reflog_write(int argc, const char **argv, const char *prefix, + struct repository *repo) + { + const struct option options[] = { + OPT_END() + }; + struct object_id old_oid, new_oid; + struct strbuf err = STRBUF_INIT; + struct ref_transaction *tx; + const char *ref, *message; + int ret; + + argc = parse_options(argc, argv, prefix, options, reflog_write_usage, 0); + if (argc != 4) + usage_with_options(reflog_write_usage, options); + + ref = argv[0]; + if (!is_root_ref(ref) && check_refname_format(ref, 0)) + die(_("invalid reference name: %s"), ref); + + ret = get_oid_hex_algop(argv[1], &old_oid, repo->hash_algo); + if (ret) + die(_("invalid old object ID: '%s'"), argv[1]); - if (!is_null_oid(&old_oid) && !has_object(the_repository, &old_oid, 0)) ++ if (!is_null_oid(&old_oid) && !odb_has_object(repo->objects, &old_oid, 0)) + die(_("old object '%s' does not exist"), argv[1]); + + ret = get_oid_hex_algop(argv[2], &new_oid, repo->hash_algo); + if (ret) + die(_("invalid new object ID: '%s'"), argv[2]); - if (!is_null_oid(&new_oid) && !has_object(the_repository, &new_oid, 0)) ++ if (!is_null_oid(&new_oid) && !odb_has_object(repo->objects, &new_oid, 0)) + die(_("new object '%s' does not exist"), argv[2]); + + message = argv[3]; + + tx = ref_store_transaction_begin(get_main_ref_store(repo), 0, &err); + if (!tx) + die(_("cannot start transaction: %s"), err.buf); + + ret = ref_transaction_update_reflog(tx, ref, &new_oid, &old_oid, + git_committer_info(0), + message, 0, &err); + if (ret) + die(_("cannot queue reflog update: %s"), err.buf); + + ret = ref_transaction_commit(tx, &err); + if (ret) + die(_("cannot commit reflog update: %s"), err.buf); + + ref_transaction_free(tx); + strbuf_release(&err); + return 0; + } + /* * main "reflog" */