Subject: Re: [PATCH 4/8] builtin/reflog: implement subcommand to write new entries

From: Toon Claes <[email-masked]>
Date: Thu, 24 Jul 2025 14:54:53 +0200

Patrick Steinhardt <[email-masked]> writes:

> While we provide a couple of subcommands in git-reflog(1) to remove
> reflog entries, we don't provide any to write new entries. Obviously
> this is not an operation that really would be needed for many use cases
> out there, or otherwise people would have complained that such a command
> does not exist yet. But the introduction of the "reftable" backend
> changes the picture a bit, as it is now basically impossible to manually
> append a reflog entry if one wanted to do so due to the binary format.
>
> Plug this gap by introducing a simple "write" subcommand. For now, all
> this command does is to append a single new reflog entry with the given
> object IDs and message to the reflog. More specifically, it is not yet
> possible to:
>
>   - Write multiple reflog entries at once.
>
>   - Insert reflog entries at arbitrary indices.
>
>   - Specify the date of the reflog entry.
>
>   - Insert reflog entries that refer to nonexistent objects.
>
> If required, those features can be added at a future point in time. For
> now though, the new command aims to fulfill the most basic use cases
> while being as strict as possible when it comes to verifying parameters.
>
> Signed-off-by: Patrick Steinhardt <[email-masked]>
> ---
>  Documentation/git-reflog.adoc |  1 +
>  builtin/reflog.c              | 65 ++++++++++++++++++++++++++++++++++
>  t/meson.build                 |  1 +
>  t/t1421-reflog-write.sh       | 81 +++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 148 insertions(+)
>
> diff --git a/Documentation/git-reflog.adoc b/Documentation/git-reflog.adoc
> index 6ae13e772b8..798dbc0a00a 100644
> --- a/Documentation/git-reflog.adoc
> +++ b/Documentation/git-reflog.adoc
> @@ -12,6 +12,7 @@ SYNOPSIS
>  git reflog [show] [<log-options>] [<ref>]
>  git reflog list
>  git reflog exists <ref>
> +git reflog write <ref> <old-oid> <new-oid> <message>
>  git reflog delete [--rewrite] [--updateref]
>  	[--dry-run | -n] [--verbose] <ref>@{<specifier>}...
>  git reflog drop [--all [--single-worktree] | <refs>...]
> diff --git a/builtin/reflog.c b/builtin/reflog.c
> index b00b3f9edc9..d0374295620 100644
> --- a/builtin/reflog.c
> +++ b/builtin/reflog.c
> @@ -3,6 +3,8 @@
>  #include "builtin.h"
>  #include "config.h"
>  #include "gettext.h"
> +#include "hex.h"
> +#include "odb.h"
>  #include "revision.h"
>  #include "reachable.h"
>  #include "wildmatch.h"
> @@ -20,6 +22,9 @@
>  #define BUILTIN_REFLOG_EXISTS_USAGE \
>  	N_("git reflog exists <ref>")
>  
> +#define BUILTIN_REFLOG_WRITE_USAGE \
> +	N_("git reflog write <ref> <old-oid> <new-oid> <message>")
> +
>  #define BUILTIN_REFLOG_DELETE_USAGE \
>  	N_("git reflog delete [--rewrite] [--updateref]\n" \
>  	   "                  [--dry-run | -n] [--verbose] <ref>@{<specifier>}...")
> @@ -47,6 +52,11 @@ static const char *const reflog_exists_usage[] = {
>  	NULL,
>  };
>  
> +static const char *const reflog_write_usage[] = {
> +	BUILTIN_REFLOG_WRITE_USAGE,
> +	NULL,
> +};
> +
>  static const char *const reflog_delete_usage[] = {
>  	BUILTIN_REFLOG_DELETE_USAGE,
>  	NULL
> @@ -66,6 +76,7 @@ static const char *const reflog_usage[] = {
>  	BUILTIN_REFLOG_SHOW_USAGE,
>  	BUILTIN_REFLOG_LIST_USAGE,
>  	BUILTIN_REFLOG_EXISTS_USAGE,
> +	BUILTIN_REFLOG_WRITE_USAGE,
>  	BUILTIN_REFLOG_DELETE_USAGE,
>  	BUILTIN_REFLOG_DROP_USAGE,
>  	BUILTIN_REFLOG_EXPIRE_USAGE,
> @@ -392,6 +403,59 @@ static int cmd_reflog_drop(int argc, const char **argv, const char *prefix,
>  	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_drop_usage, 0);

Wrong usage string here: s/reflog_drop_usage/reflog_write_usage/.

-- 
Cheers,
Toon