We have a transaction in rename_ref to managing the ref during the rename. Use this transaction to manage the changes to the reflog too. This now means that rename_ref is almost completely agnostic about how refs storage is implemented and should be easier to migrate if/when we allow a different store for refs, such as a database.
Signed-off-by: Ronnie Sahlberg <sahlb...@google.com> --- refs.c | 62 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/refs.c b/refs.c index bcce8fe..829c89a 100644 --- a/refs.c +++ b/refs.c @@ -2633,6 +2633,24 @@ struct ref_update { const char refname[FLEX_ARRAY]; }; +struct rename_reflog_cb { + struct ref_transaction *t; + const char *refname; +}; + +static int rename_reflog_ent(unsigned char *osha1, unsigned char *nsha1, + const char *email, unsigned long timestamp, int tz, + const char *message, void *cb_data) +{ + struct rename_reflog_cb *cb = cb_data; + + transaction_update_reflog(cb->t, cb->refname, nsha1, osha1, + email, timestamp, tz, message, 0, + NULL); + + return 0; +} + int rename_ref(const char *oldrefname, const char *newrefname, const char *logmsg) { unsigned char sha1[20]; @@ -2664,40 +2682,44 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms get_loose_refs(&ref_cache), NULL, 0)) return 1; - if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG))) - return error("unable to move logfile logs/%s to "TMP_RENAMED_LOG": %s", - oldrefname, strerror(errno)); - if (pack_refs(PACK_REFS_ALL | PACK_REFS_PRUNE)) return error("unable to pack refs"); transaction = transaction_begin(); - if (!transaction || - transaction_delete_sha1(transaction, oldrefname, sha1, + if (log) { + struct rename_reflog_cb cb; + + transaction_update_reflog(transaction, newrefname, + null_sha1, null_sha1, NULL, + 0, 0, NULL, + REFLOG_TRUNCATE, + NULL); + + cb.t = transaction; + cb.refname = newrefname; + for_each_reflog_ent(oldrefname, rename_reflog_ent, &cb); + + transaction_update_reflog(transaction, newrefname, + sha1, sha1, + git_committer_info(0), + 0, 0, logmsg, + REFLOG_EMAIL_IS_COMMITTER, + &err); + } + + if (transaction_delete_sha1(transaction, oldrefname, sha1, REF_NODEREF | REF_ISPACKONLY, 1, NULL, &err) || transaction_update_sha1(transaction, newrefname, sha1, - NULL, 0, 0, logmsg, &err) || + NULL, 0, 0, NULL, &err) || transaction_commit(transaction, &err)) { transaction_rollback(transaction); error("rename_ref failed: %s", err.buf); strbuf_release(&err); - goto rollbacklog; + return 1; } transaction_free(transaction); - - if (log && rename_tmp_log(newrefname)) - goto rollbacklog; - return 0; - - rollbacklog: - if (log && - rename(git_path(TMP_RENAMED_LOG), git_path("logs/%s", oldrefname))) - error("unable to restore logfile %s from "TMP_RENAMED_LOG": %s", - oldrefname, strerror(errno)); - - return 1; } static int close_ref(struct ref_lock *lock) -- 2.0.0.rc3.506.g3739a35 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html