git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Jiang Xin <worldhello.net@gmail.com>
To: Junio C Hamano <gitster@pobox.com>,
	Patrick Steinhardt <ps@pks.im>, Git List <git@vger.kernel.org>
Cc: Jiang Xin <zhiyou.jx@alibaba-inc.com>,
	Jiang Xin <worldhello.net@gmail.com>
Subject: [PATCH 6/9] refs: add reflog_info to hold more fields for reflog entry
Date: Fri, 29 Jul 2022 18:12:42 +0800	[thread overview]
Message-ID: <20220729101245.6469-7-worldhello.net@gmail.com> (raw)
In-Reply-To: <20220729101245.6469-1-worldhello.net@gmail.com>

From: Jiang Xin <zhiyou.jx@alibaba-inc.com>

The parameter "msg" of the functions "ref_transaction_add_update()" and
"refs_update_ref()" is used as a comment for creating a new reflog
entry. For some cases, like copying or renaming a branch, we may need
more custom fields for the new reflog entry, such as old-oid which is
different from the oid we get from the lock file. Therefore, we create
a new structure "reflog_info" to hold more custom fields for the new
reflog entry, and add two additional extended version functions.

We will use this extension in a later commit to reimplement
"files_copy_or_rename_ref()" using "refs_update_ref_extended()" to
create new reference in a transaction and add proper reflog entry.

Signed-off-by: Jiang Xin <zhiyou.jx@alibaba-inc.com>
---
 refs.c               | 54 +++++++++++++++++++++++++++++++++++++++-----
 refs.h               | 20 ++++++++++++++++
 refs/debug.c         |  2 +-
 refs/files-backend.c | 14 ++++++++----
 refs/refs-internal.h | 17 ++++++++++++--
 5 files changed, 94 insertions(+), 13 deletions(-)

diff --git a/refs.c b/refs.c
index 48b69460e2..e53f011e6b 100644
--- a/refs.c
+++ b/refs.c
@@ -1045,7 +1045,11 @@ void ref_transaction_free(struct ref_transaction *transaction)
 	}
 
 	for (i = 0; i < transaction->nr; i++) {
-		free(transaction->updates[i]->msg);
+		if (transaction->updates[i]->reflog_info) {
+			free(transaction->updates[i]->reflog_info->msg);
+			free(transaction->updates[i]->reflog_info->old_oid);
+			free(transaction->updates[i]->reflog_info);
+		}
 		free(transaction->updates[i]);
 	}
 	free(transaction->updates);
@@ -1057,7 +1061,7 @@ struct ref_update *ref_transaction_add_update(
 		const char *refname, unsigned int flags,
 		const struct object_id *new_oid,
 		const struct object_id *old_oid,
-		const char *msg)
+		const struct reflog_info *reflog_info)
 {
 	struct ref_update *update;
 
@@ -1074,7 +1078,12 @@ struct ref_update *ref_transaction_add_update(
 		oidcpy(&update->new_oid, new_oid);
 	if (flags & REF_HAVE_OLD)
 		oidcpy(&update->old_oid, old_oid);
-	update->msg = normalize_reflog_message(msg);
+	if (reflog_info) {
+		update->reflog_info = xmalloc(sizeof(*reflog_info));
+		update->reflog_info->msg = normalize_reflog_message(reflog_info->msg);
+		if (reflog_info->old_oid)
+			update->reflog_info->old_oid = oiddup(reflog_info->old_oid);
+	}
 	return update;
 }
 
@@ -1084,6 +1093,23 @@ int ref_transaction_update(struct ref_transaction *transaction,
 			   const struct object_id *old_oid,
 			   unsigned int flags, const char *msg,
 			   struct strbuf *err)
+{
+	struct reflog_info reflog_info;
+
+	reflog_info.msg = (char *)msg;
+	reflog_info.old_oid = NULL;
+	return ref_transaction_update_extended(transaction,
+					       refname, new_oid, old_oid,
+					       flags, &reflog_info, err);
+}
+
+int ref_transaction_update_extended(struct ref_transaction *transaction,
+				    const char *refname,
+				    const struct object_id *new_oid,
+				    const struct object_id *old_oid,
+				    unsigned int flags,
+				    const struct reflog_info *reflog_info,
+				    struct strbuf *err)
 {
 	assert(err);
 
@@ -1109,7 +1135,7 @@ int ref_transaction_update(struct ref_transaction *transaction,
 	flags |= (new_oid ? REF_HAVE_NEW : 0) | (old_oid ? REF_HAVE_OLD : 0);
 
 	ref_transaction_add_update(transaction, refname, flags,
-				   new_oid, old_oid, msg);
+				   new_oid, old_oid, reflog_info);
 	return 0;
 }
 
@@ -1157,6 +1183,22 @@ int refs_update_ref(struct ref_store *refs, const char *msg,
 		    const char *refname, const struct object_id *new_oid,
 		    const struct object_id *old_oid, unsigned int flags,
 		    enum action_on_err onerr)
+{
+	struct reflog_info reflog_info;
+
+	reflog_info.msg = (char *)msg;
+	reflog_info.old_oid = NULL;
+	return refs_update_ref_extended(refs, refname, new_oid, old_oid,
+					flags, &reflog_info, onerr);
+}
+
+int refs_update_ref_extended(struct ref_store *refs,
+			     const char *refname,
+			     const struct object_id *new_oid,
+			     const struct object_id *old_oid,
+			     unsigned int flags,
+			     const struct reflog_info *reflog_info,
+			     enum action_on_err onerr)
 {
 	struct ref_transaction *t = NULL;
 	struct strbuf err = STRBUF_INIT;
@@ -1164,8 +1206,8 @@ int refs_update_ref(struct ref_store *refs, const char *msg,
 
 	t = ref_store_transaction_begin(refs, &err);
 	if (!t ||
-	    ref_transaction_update(t, refname, new_oid, old_oid, flags, msg,
-				   &err) ||
+	    ref_transaction_update_extended(t, refname, new_oid, old_oid,
+					    flags, reflog_info, &err) ||
 	    ref_transaction_commit(t, &err)) {
 		ret = 1;
 		ref_transaction_free(t);
diff --git a/refs.h b/refs.h
index 715127ab58..0f21ba259f 100644
--- a/refs.h
+++ b/refs.h
@@ -10,6 +10,7 @@ struct strbuf;
 struct string_list;
 struct string_list_item;
 struct worktree;
+struct reflog_info;
 
 /*
  * Resolve a reference, recursively following symbolic refererences.
@@ -677,6 +678,18 @@ int ref_transaction_update(struct ref_transaction *transaction,
 			   const struct object_id *old_oid,
 			   unsigned int flags, const char *msg,
 			   struct strbuf *err);
+/*
+ * Extended version of ref_transaction_update() that allows us to
+ * provide more fields (in reflog_info) to custom reflog, such
+ * as msg and old_oid.
+ */
+int ref_transaction_update_extended(struct ref_transaction *transaction,
+				    const char *refname,
+				    const struct object_id *new_oid,
+				    const struct object_id *old_oid,
+				    unsigned int flags,
+				    const struct reflog_info *reflog_info,
+				    struct strbuf *err);
 
 /*
  * Add a reference creation to transaction. new_oid is the value that
@@ -806,6 +819,13 @@ void ref_transaction_free(struct ref_transaction *transaction);
 int refs_update_ref(struct ref_store *refs, const char *msg, const char *refname,
 		    const struct object_id *new_oid, const struct object_id *old_oid,
 		    unsigned int flags, enum action_on_err onerr);
+int refs_update_ref_extended(struct ref_store *refs,
+			     const char *refname,
+			     const struct object_id *new_oid,
+			     const struct object_id *old_oid,
+			     unsigned int flags,
+			     const struct reflog_info *reflog_info,
+			     enum action_on_err onerr);
 int update_ref(const char *msg, const char *refname,
 	       const struct object_id *new_oid, const struct object_id *old_oid,
 	       unsigned int flags, enum action_on_err onerr);
diff --git a/refs/debug.c b/refs/debug.c
index eed8bc94b0..1e60507249 100644
--- a/refs/debug.c
+++ b/refs/debug.c
@@ -79,7 +79,7 @@ static void print_transaction(struct ref_transaction *transaction)
 	for (i = 0; i < transaction->nr; i++) {
 		struct ref_update *u = transaction->updates[i];
 		print_update(i, u->refname, &u->old_oid, &u->new_oid, u->flags,
-			     u->type, u->msg);
+			     u->type, u->reflog_info? u->reflog_info->msg : NULL);
 	}
 	trace_printf_key(&trace_refs, "}\n");
 }
diff --git a/refs/files-backend.c b/refs/files-backend.c
index e8d12cb343..e2eabe9d8e 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -2340,7 +2340,7 @@ static int split_head_update(struct ref_update *update,
 			transaction, "HEAD",
 			update->flags | REF_LOG_ONLY | REF_NO_DEREF,
 			&update->new_oid, &update->old_oid,
-			update->msg);
+			update->reflog_info);
 
 	/*
 	 * Add "HEAD". This insertion is O(N) in the transaction
@@ -2403,7 +2403,7 @@ static int split_symref_update(struct ref_update *update,
 	new_update = ref_transaction_add_update(
 			transaction, referent, new_flags,
 			&update->new_oid, &update->old_oid,
-			update->msg);
+			update->reflog_info);
 
 	new_update->parent_update = update;
 
@@ -2893,9 +2893,15 @@ static int files_transaction_finish(struct ref_store *ref_store,
 		    update->flags & REF_LOG_ONLY) {
 			if (files_log_ref_write(refs,
 						lock->ref_name,
-						&lock->old_oid,
+						update->reflog_info &&
+						update->reflog_info->old_oid ?
+							update->reflog_info->old_oid :
+							&lock->old_oid,
 						&update->new_oid,
-						update->msg, update->flags,
+						update->reflog_info ?
+							update->reflog_info->msg :
+							NULL,
+						update->flags,
 						err)) {
 				char *old_msg = strbuf_detach(err, NULL);
 
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index 5220d1980d..782cf5fa78 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -104,6 +104,19 @@ enum peel_status {
  */
 enum peel_status peel_object(const struct object_id *name, struct object_id *oid);
 
+/*
+ * When using refs_update_ref() to copy or rename a branch, the old-oid
+ * for the new created branch is null_oid, but the old_oid for the new
+ * appended log entry for the reflog file which is copied from the
+ * original reflog should be the same as the new_oid for the target
+ * branch. Use "reflog_info" to hold log message and old_oid for the
+ * new reflog entry.
+ */
+struct reflog_info {
+	struct object_id *old_oid;
+	char *msg;
+};
+
 /**
  * Information needed for a single ref update. Set new_oid to the new
  * value or to null_oid to delete the ref. To check the old value
@@ -133,7 +146,7 @@ struct ref_update {
 
 	void *backend_data;
 	unsigned int type;
-	char *msg;
+	struct reflog_info *reflog_info;
 
 	/*
 	 * If this ref_update was split off of a symref update via
@@ -174,7 +187,7 @@ struct ref_update *ref_transaction_add_update(
 		const char *refname, unsigned int flags,
 		const struct object_id *new_oid,
 		const struct object_id *old_oid,
-		const char *msg);
+		const struct reflog_info *reflog_info);
 
 /*
  * Transaction states.
-- 
2.36.1.25.gc87d5ad63a.dirty


  parent reply	other threads:[~2022-07-29 10:13 UTC|newest]

Thread overview: 27+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-29 10:12 [PATCH 0/9] Fix issues of reference-transaction hook for various git commands Jiang Xin
2022-07-29 10:12 ` [PATCH 1/9] t1416: more testcases for reference-transaction hook Jiang Xin
2022-07-30  6:44   ` Eric Sunshine
2022-07-31  3:25     ` Jiang Xin
2022-07-29 10:12 ` [PATCH 2/9] refs: update missing old-oid in transaction from lockfile Jiang Xin
2022-07-29 10:12 ` [PATCH 3/9] refs: add new field in transaction for running transaction hook Jiang Xin
2022-07-29 10:12 ` [PATCH 4/9] refs: do not run transaction hook for git-pack-refs Jiang Xin
2022-07-29 10:12 ` [PATCH 5/9] refs: avoid duplicate running of the reference-transaction hook Jiang Xin
2022-08-02 12:18   ` Michael Heemskerk
2022-08-05  1:41     ` Jiang Xin
2022-08-19  3:21       ` [PATCH v2 0/9] Fix issues of refx-txn hook for various git commands Jiang Xin
2022-08-19  3:21       ` [PATCH v2 1/9] t1416: more testcases for reference-transaction hook Jiang Xin
2022-08-19  3:21       ` [PATCH v2 2/9] refs: update missing old-oid in transaction from lockfile Jiang Xin
2022-08-19  3:21       ` [PATCH v2 3/9] refs: add new field in transaction for running transaction hook Jiang Xin
2022-08-19  3:21       ` [PATCH v2 4/9] refs: do not run transaction hook for git-pack-refs Jiang Xin
2022-08-19  3:21       ` [PATCH v2 5/9] refs: avoid duplicate running of the reference-transaction hook Jiang Xin
2022-08-19  3:21       ` [PATCH v2 6/9] refs: add reflog_info to hold more fields for reflog entry Jiang Xin
2022-08-19  3:21       ` [PATCH v2 7/9] refs: get error message via refs_update_ref_extended() Jiang Xin
2022-08-19  3:21       ` [PATCH v2 8/9] refs: reimplement files_copy_or_rename_ref() to run refs-txn hook Jiang Xin
2022-08-19  3:21       ` [PATCH v2 9/9] refs: reimplement refs_delete_refs() and run hook once Jiang Xin
2022-07-29 10:12 ` Jiang Xin [this message]
2022-08-01 11:32   ` [PATCH 6/9] refs: add reflog_info to hold more fields for reflog entry Jiang Xin
2022-07-29 10:12 ` [PATCH 7/9] refs: get error message via refs_update_ref_extended() Jiang Xin
2022-07-29 10:12 ` [PATCH 8/9] refs: reimplement files_copy_or_rename_ref() to run hook Jiang Xin
2022-07-29 10:12 ` [PATCH 9/9] refs: reimplement refs_delete_refs() and run hook once Jiang Xin
2022-08-02 12:42   ` Michael Heemskerk
2022-08-09 11:05     ` Patrick Steinhardt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220729101245.6469-7-worldhello.net@gmail.com \
    --to=worldhello.net@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=ps@pks.im \
    --cc=zhiyou.jx@alibaba-inc.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).