[PATCH v3 03/19] refs.c: make ref_transaction_commit return an error string
- From
Ronnie Sahlberg <sahlberg@google.com>
- Date
- Apr 25, 2014, 16:14 UTC
- Message-ID
- <1398442494-23438-4-git-send-email-sahlberg@google.com>
- In-Reply-To
- <1398442494-23438-1-git-send-email-sahlberg@google.com>
Let ref_transaction_commit return an optional error string that describes the transaction failure. Start by returning the same error as update_ref_lock returns, modulo the initial error:/fatal: preamble.
This will make it easier for callers to craft better error messages when a transaction call fails.
Signed-off-by: Ronnie Sahlberg <sahlberg@google.com> --- builtin/update-ref.c | 2 +- refs.c | 12 +++++++++++- refs.h | 5 ++++- 3 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 405267f..aaa06aa 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -367,7 +367,7 @@ int cmd_update_ref(int argc, const char **argv, const char *prefix) if (end_null) line_termination = '\0'; update_refs_stdin(); - ret = ref_transaction_commit(transaction, msg, + ret = ref_transaction_commit(transaction, msg, NULL, UPDATE_REFS_DIE_ON_ERR); return ret; } diff --git a/refs.c b/refs.c index 2d83ef6..0712912 100644 --- a/refs.c +++ b/refs.c @@ -3414,7 +3414,8 @@ static int ref_update_reject_duplicates(struct ref_update **updates, int n, } int ref_transaction_commit(struct ref_transaction *transaction, - const char *msg, enum action_on_err onerr) + const char *msg, char **err, + enum action_on_err onerr) { int ret = 0, delnum = 0, i; const char **delnames; @@ -3424,6 +3425,9 @@ int ref_transaction_commit(struct ref_transaction *transaction, if (!n) return 0; + if (err) + *err = NULL; + /* Allocate work space */ delnames = xmalloc(sizeof(*delnames) * n); @@ -3443,6 +3447,12 @@ int ref_transaction_commit(struct ref_transaction *transaction, update->flags, &update->type, onerr); if (!update->lock) { + if (err) { + const char *str = "Cannot lock the ref '%s'."; + *err = xmalloc(PATH_MAX + 24); + snprintf(*err, PATH_MAX + 24, str, + update->refname); + } ret = 1; goto cleanup; } diff --git a/refs.h b/refs.h index 892c5b6..615c73d 100644 --- a/refs.h +++ b/refs.h @@ -268,9 +268,12 @@ void ref_transaction_delete(struct ref_transaction *transaction, * Commit all of the changes that have been queued in transaction, as * atomically as possible. Return a nonzero value if there is a * problem. The ref_transaction is freed by this function. + * If error is non-NULL it will return an error string that describes + * why a commit failed. This string must be free()ed by the caller. */ int ref_transaction_commit(struct ref_transaction *transaction, - const char *msg, enum action_on_err onerr); + const char *msg, char **err, + enum action_on_err onerr); /** Lock a ref and then write its file */ int update_ref(const char *action, const char *refname,
-- 1.9.1.521.g5dc89fa