@@ -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 = xcalloc(1, 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);
@@ -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);
@@ -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");
}
@@ -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;
@@ -2902,9 +2902,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);
@@ -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.