From 835e3c992fd453d172466be29283b55a792cac76 Mon Sep 17 00:00:00 2001 From: Ronnie Sahlberg Date: Fri, 20 Jun 2014 07:42:51 -0700 Subject: [PATCH] refs.c: verify_lock should set errno to something meaningful Making errno when returning from verify_lock() meaningful, which should almost but not completely fix * a bug in "git fetch"'s s_update_ref, which trusts the result of an errno == ENOTDIR check to detect D/F conflicts ENOTDIR makes sense as a sign that a file was in the way of a directory we wanted to create. Should "git fetch" also look for ENOTEMPTY or EEXIST to catch cases where a directory was in the way of a file to be created? Signed-off-by: Ronnie Sahlberg Signed-off-by: Junio C Hamano Acked-by: Michael Haggerty --- refs.c | 4 ++++ refs.h | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/refs.c b/refs.c index 9ea519c3f..a48f80512 100644 --- a/refs.c +++ b/refs.c @@ -1932,18 +1932,22 @@ int refname_match(const char *abbrev_name, const char *full_name) return 0; } +/* This function should make sure errno is meaningful on error */ static struct ref_lock *verify_lock(struct ref_lock *lock, const unsigned char *old_sha1, int mustexist) { if (read_ref_full(lock->ref_name, lock->old_sha1, mustexist, NULL)) { + int save_errno = errno; error("Can't verify ref %s", lock->ref_name); unlock_ref(lock); + errno = save_errno; return NULL; } if (hashcmp(lock->old_sha1, old_sha1)) { error("Ref %s is at %s but expected %s", lock->ref_name, sha1_to_hex(lock->old_sha1), sha1_to_hex(old_sha1)); unlock_ref(lock); + errno = EBUSY; return NULL; } return lock; diff --git a/refs.h b/refs.h index 82cc5cb2a..8d6cac717 100644 --- a/refs.h +++ b/refs.h @@ -137,11 +137,15 @@ extern int ref_exists(const char *); */ extern int peel_ref(const char *refname, unsigned char *sha1); -/** Locks a "refs/" ref returning the lock on success and NULL on failure. **/ +/* + * Locks a "refs/" ref returning the lock on success and NULL on failure. + * On failure errno is set to something meaningful. + */ extern struct ref_lock *lock_ref_sha1(const char *refname, const unsigned char *old_sha1); /** Locks any ref (for 'HEAD' type refs). */ #define REF_NODEREF 0x01 +/* errno is set to something meaningful on failure */ extern struct ref_lock *lock_any_ref_for_update(const char *refname, const unsigned char *old_sha1, int flags, int *type_p); -- 2.11.0