diff options
Diffstat (limited to 'refs.c')
-rw-r--r-- | refs.c | 53 |
1 files changed, 44 insertions, 9 deletions
@@ -174,6 +174,24 @@ int refname_is_safe(const char *refname) return 1; } +/* + * Return true if refname, which has the specified oid and flags, can + * be resolved to an object in the database. If the referred-to object + * does not exist, emit a warning and return false. + */ +int ref_resolves_to_object(const char *refname, + const struct object_id *oid, + unsigned int flags) +{ + if (flags & REF_ISBROKEN) + return 0; + if (!has_sha1_file(oid->hash)) { + error("%s does not point to a valid object!", refname); + return 0; + } + return 1; +} + char *refs_resolve_refdup(struct ref_store *refs, const char *refname, int resolve_flags, unsigned char *sha1, int *flags) @@ -561,6 +579,21 @@ enum ref_type ref_type(const char *refname) return REF_TYPE_NORMAL; } +long get_files_ref_lock_timeout_ms(void) +{ + static int configured = 0; + + /* The default timeout is 100 ms: */ + static int timeout_ms = 100; + + if (!configured) { + git_config_get_int("core.filesreflocktimeout", &timeout_ms); + configured = 1; + } + + return timeout_ms; +} + static int write_pseudoref(const char *pseudoref, const unsigned char *sha1, const unsigned char *old_sha1, struct strbuf *err) { @@ -573,7 +606,9 @@ static int write_pseudoref(const char *pseudoref, const unsigned char *sha1, strbuf_addf(&buf, "%s\n", sha1_to_hex(sha1)); filename = git_path("%s", pseudoref); - fd = hold_lock_file_for_update(&lock, filename, LOCK_DIE_ON_ERROR); + fd = hold_lock_file_for_update_timeout(&lock, filename, + LOCK_DIE_ON_ERROR, + get_files_ref_lock_timeout_ms()); if (fd < 0) { strbuf_addf(err, "could not open '%s' for writing: %s", filename, strerror(errno)); @@ -616,8 +651,9 @@ static int delete_pseudoref(const char *pseudoref, const unsigned char *old_sha1 int fd; unsigned char actual_old_sha1[20]; - fd = hold_lock_file_for_update(&lock, filename, - LOCK_DIE_ON_ERROR); + fd = hold_lock_file_for_update_timeout( + &lock, filename, LOCK_DIE_ON_ERROR, + get_files_ref_lock_timeout_ms()); if (fd < 0) die_errno(_("Could not open '%s' for writing"), filename); if (read_ref(pseudoref, actual_old_sha1)) @@ -818,7 +854,7 @@ int read_ref_at(const char *refname, unsigned int flags, timestamp_t at_time, in for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb); if (!cb.reccnt) { - if (flags & GET_SHA1_QUIETLY) + if (flags & GET_OID_QUIETLY) exit(128); else die("Log for %s is empty.", refname); @@ -1160,7 +1196,7 @@ int ref_is_hidden(const char *refname, const char *refname_full) const char *match = hide_refs->items[i].string; const char *subject; int neg = 0; - int len; + const char *p; if (*match == '!') { neg = 1; @@ -1175,10 +1211,9 @@ int ref_is_hidden(const char *refname, const char *refname_full) } /* refname can be NULL when namespaces are used. */ - if (!subject || !starts_with(subject, match)) - continue; - len = strlen(match); - if (!subject[len] || subject[len] == '/') + if (subject && + skip_prefix(subject, match, &p) && + (!*p || *p == '/')) return !neg; } return 0; |