refs: include committer info in `ref_update` struct

The reference backends obtain the committer information from `git_committer_info(0)` when adding a reflog. The upcoming patches introduce support for migrating reflogs between the reference backends. This requires an interface to creating reflogs, including custom committer information. Add a new field `committer_info` to the `ref_update` struct, which is then used by the reference backends. If there is no `committer_info` provided, the reference backends default to using `git_committer_info(0)`. The field itself cannot be set to `git_committer_info(0)` since the values are dynamic and must be obtained right when the reflog is being committed. Signed-off-by: Karthik Nayak <karthik.188@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Karthik Nayak committed Dec 16, 2024 at 17:44 UTC 1a83e26d72eb2601798dfc07e6f5112964dc9413
4 files changed +27 -11
refs.c
+1
@@ -1151,6 +1151,7 @@ void ref_transaction_free(struct ref_transaction *transaction)
1151
1152 for (i = 0; i < transaction->nr; i++) {
1153 free(transaction->updates[i]->msg);
1154 + free(transaction->updates[i]->committer_info);
1155 free((char *)transaction->updates[i]->new_target);
1156 free((char *)transaction->updates[i]->old_target);
1157 free(transaction->updates[i]);
refs/files-backend.c
+14 -10
@@ -1858,6 +1858,9 @@ static int log_ref_write_fd(int fd, const struct object_id *old_oid,
1858 struct strbuf sb = STRBUF_INIT;
1859 int ret = 0;
1860
1861 + if (!committer)
1862 + committer = git_committer_info(0);
1863 +
1864 strbuf_addf(&sb, "%s %s %s", oid_to_hex(old_oid), oid_to_hex(new_oid), committer);
1865 if (msg && *msg) {
1866 strbuf_addch(&sb, '\t');
@@ -1871,8 +1874,10 @@ static int log_ref_write_fd(int fd, const struct object_id *old_oid,
1874 }
1875
1876 static int files_log_ref_write(struct files_ref_store *refs,
1874 - const char *refname, const struct object_id *old_oid,
1875 - const struct object_id *new_oid, const char *msg,
1877 + const char *refname,
1878 + const struct object_id *old_oid,
1879 + const struct object_id *new_oid,
1880 + const char *committer_info, const char *msg,
1881 int flags, struct strbuf *err)
1882 {
1883 int logfd, result;
@@ -1889,8 +1894,7 @@ static int files_log_ref_write(struct files_ref_store *refs,
1894
1895 if (logfd < 0)
1896 return 0;
1892 - result = log_ref_write_fd(logfd, old_oid, new_oid,
1893 - git_committer_info(0), msg);
1897 + result = log_ref_write_fd(logfd, old_oid, new_oid, committer_info, msg);
1898 if (result) {
1899 struct strbuf sb = STRBUF_INIT;
1900 int save_errno = errno;
@@ -1974,8 +1978,7 @@ static int commit_ref_update(struct files_ref_store *refs,
1978 files_assert_main_repository(refs, "commit_ref_update");
1979
1980 clear_loose_ref_cache(refs);
1977 - if (files_log_ref_write(refs, lock->ref_name,
1978 - &lock->old_oid, oid,
1981 + if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, oid, NULL,
1982 logmsg, flags, err)) {
1983 char *old_msg = strbuf_detach(err, NULL);
1984 strbuf_addf(err, "cannot update the ref '%s': %s",
@@ -2007,9 +2010,9 @@ static int commit_ref_update(struct files_ref_store *refs,
2010 if (head_ref && (head_flag & REF_ISSYMREF) &&
2011 !strcmp(head_ref, lock->ref_name)) {
2012 struct strbuf log_err = STRBUF_INIT;
2010 - if (files_log_ref_write(refs, "HEAD",
2011 - &lock->old_oid, oid,
2012 - logmsg, flags, &log_err)) {
2013 + if (files_log_ref_write(refs, "HEAD", &lock->old_oid,
2014 + oid, NULL, logmsg, flags,
2015 + &log_err)) {
2016 error("%s", log_err.buf);
2017 strbuf_release(&log_err);
2018 }
@@ -2969,7 +2972,8 @@ static int parse_and_write_reflog(struct files_ref_store *refs,
2972 }
2973
2974 if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid,
2972 - &update->new_oid, update->msg, update->flags, err)) {
2975 + &update->new_oid, update->committer_info,
2976 + update->msg, update->flags, err)) {
2977 char *old_msg = strbuf_detach(err, NULL);
2978
2979 strbuf_addf(err, "cannot update the ref '%s': %s",
refs/refs-internal.h
+1
@@ -113,6 +113,7 @@ struct ref_update {
113 void *backend_data;
114 unsigned int type;
115 char *msg;
116 + char *committer_info;
117
118 /*
119 * If this ref_update was split off of a symref update via
refs/reftable-backend.c
+11 -1
@@ -1379,11 +1379,21 @@ static int write_transaction_table(struct reftable_writer *writer, void *cb_data
1379 }
1380
1381 if (create_reflog) {
1382 + struct ident_split c;
1383 +
1384 ALLOC_GROW(logs, logs_nr + 1, logs_alloc);
1385 log = &logs[logs_nr++];
1386 memset(log, 0, sizeof(*log));
1387
1386 - fill_reftable_log_record(log, &committer_ident);
1388 + if (u->committer_info) {
1389 + if (split_ident_line(&c, u->committer_info,
1390 + strlen(u->committer_info)))
1391 + BUG("failed splitting committer info");
1392 + } else {
1393 + c = committer_ident;
1394 + }
1395 +
1396 + fill_reftable_log_record(log, &c);
1397 log->update_index = ts;
1398 log->refname = xstrdup(u->refname);
1399 memcpy(log->value.update.new_hash,