From mboxrd@z Thu Jan 1 00:00:00 1970 From: David Turner Subject: [PATCH v5 09/26] refs.c: move dwim and friend functions to the common refs code Date: Tue, 27 Oct 2015 22:14:10 -0400 Message-ID: <1445998467-11511-10-git-send-email-dturner@twopensource.com> References: <1445998467-11511-1-git-send-email-dturner@twopensource.com> Cc: Ronnie Sahlberg , David Turner , Junio C Hamano To: git@vger.kernel.org, mhagger@alum.mit.edu X-From: git-owner@vger.kernel.org Wed Oct 28 03:15:07 2015 Return-path: Envelope-to: gcvg-git-2@plane.gmane.org Received: from vger.kernel.org ([209.132.180.67]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1ZrGGX-00011F-4e for gcvg-git-2@plane.gmane.org; Wed, 28 Oct 2015 03:15:05 +0100 Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755236AbbJ1CO6 (ORCPT ); Tue, 27 Oct 2015 22:14:58 -0400 Received: from mail-ig0-f176.google.com ([209.85.213.176]:33279 "EHLO mail-ig0-f176.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755207AbbJ1CO4 (ORCPT ); Tue, 27 Oct 2015 22:14:56 -0400 Received: by igbkq10 with SMTP id kq10so108252990igb.0 for ; Tue, 27 Oct 2015 19:14:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=twopensource_com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=ZBAcIBQFH+gpDOzK8TaA3ViV19aqncPDvm1mvbRRMfE=; b=HiYA0gFxl0sAhLg1fETmiGLK3jYJt0nreJGQRiuVwgh2cl8vVgKc7QuQer89d2QzOt JNPMEd4Y0211+/DNLlcxYd9uBIaOToVgf1cKbTrMkD5O4EvHR8feL27fX6DopttbfT+z dc89fE7iCK1exbv1rOQv+wIhz3y4XqDUx5Gg1QSp6TTBB+aDMbqABum/+Pe988bC7tUV l8Eo9/A+hN4pP8Pr4+Ljm7uwNtaHNttM5xpwLIGk948CdNsvqH/Cg2EOdmUqNBgqzX75 bqNGmxMWqWD29I3VUmc6DWFfnz4Cwye2+NIBGOqBkTxsfrV+MjCuw876WCwQWKEwvrTJ Hlzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=ZBAcIBQFH+gpDOzK8TaA3ViV19aqncPDvm1mvbRRMfE=; b=ETogYUFpxLAiyHW0OXPvioDE/qkZuXKk0SysrNzNpcUjyt7yyNFvZnO/j991qzoD4U 311+gmKgaBf5C/CfmAdGMqwkjp6T6oLJWxe25wo6RPnYrDP6vJZDVwmwQ1wzLup+jjvM F8ZO2yRHwteSEO1U91/zC+sEN++tK09TlIzh5CWmvB1tvWD4+GqZT/i9DMFe1mziC6zx +IIFOmsDLGAgfJkuWKJUm/+9ff1ykXY7f2EQAhJ3dAA8md6x69NrNRS2bul7cuBaWELq 4nbNMDgsAn1R7t/pHTJvgU63D/TABdrDe2G+PyqJfr3VibAEd18+kPGIZldMhmEdlW6T MrvQ== X-Gm-Message-State: ALoCoQkbSf7NHw/JwVoNvqM44MTOSYlksRwoHk/HVQ7ApiTB/3aGNeqnZZmgsO+RHbvCyr8noTIy X-Received: by 10.50.61.145 with SMTP id p17mr342108igr.68.1445998495837; Tue, 27 Oct 2015 19:14:55 -0700 (PDT) Received: from ubuntu.twitter.corp? ([8.25.196.25]) by smtp.gmail.com with ESMTPSA id lo2sm9240077igb.17.2015.10.27.19.14.54 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 27 Oct 2015 19:14:54 -0700 (PDT) X-Mailer: git-send-email 2.4.2.658.g6d8523e-twtrsrc In-Reply-To: <1445998467-11511-1-git-send-email-dturner@twopensource.com> Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Archived-At: From: Ronnie Sahlberg These functions do not contain any backend specific code so we move them to the common code and share across all backends. Signed-off-by: Ronnie Sahlberg Signed-off-by: David Turner Signed-off-by: Junio C Hamano --- refs-be-files.c | 203 -------------------------------------------------------- refs.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 203 insertions(+), 203 deletions(-) diff --git a/refs-be-files.c b/refs-be-files.c index 8be8405..b74b6cc 100644 --- a/refs-be-files.c +++ b/refs-be-files.c @@ -2247,30 +2247,6 @@ const char *prettify_refname(const char *name) 0); } -static const char *ref_rev_parse_rules[] = { - "%.*s", - "refs/%.*s", - "refs/tags/%.*s", - "refs/heads/%.*s", - "refs/remotes/%.*s", - "refs/remotes/%.*s/HEAD", - NULL -}; - -int refname_match(const char *abbrev_name, const char *full_name) -{ - const char **p; - const int abbrev_name_len = strlen(abbrev_name); - - for (p = ref_rev_parse_rules; *p; p++) { - if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) { - return 1; - } - } - - return 0; -} - static void unlock_ref(struct ref_lock *lock) { /* Do not free lock->lk -- atexit() still looks at them */ @@ -2323,92 +2299,6 @@ static int remove_empty_directories(struct strbuf *path) } /* - * *string and *len will only be substituted, and *string returned (for - * later free()ing) if the string passed in is a magic short-hand form - * to name a branch. - */ -static char *substitute_branch_name(const char **string, int *len) -{ - struct strbuf buf = STRBUF_INIT; - int ret = interpret_branch_name(*string, *len, &buf); - - if (ret == *len) { - size_t size; - *string = strbuf_detach(&buf, &size); - *len = size; - return (char *)*string; - } - - return NULL; -} - -int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) -{ - char *last_branch = substitute_branch_name(&str, &len); - const char **p, *r; - int refs_found = 0; - - *ref = NULL; - for (p = ref_rev_parse_rules; *p; p++) { - char fullref[PATH_MAX]; - unsigned char sha1_from_ref[20]; - unsigned char *this_result; - int flag; - - this_result = refs_found ? sha1_from_ref : sha1; - mksnpath(fullref, sizeof(fullref), *p, len, str); - r = resolve_ref_unsafe(fullref, RESOLVE_REF_READING, - this_result, &flag); - if (r) { - if (!refs_found++) - *ref = xstrdup(r); - if (!warn_ambiguous_refs) - break; - } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) { - warning("ignoring dangling symref %s.", fullref); - } else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) { - warning("ignoring broken ref %s.", fullref); - } - } - free(last_branch); - return refs_found; -} - -int dwim_log(const char *str, int len, unsigned char *sha1, char **log) -{ - char *last_branch = substitute_branch_name(&str, &len); - const char **p; - int logs_found = 0; - - *log = NULL; - for (p = ref_rev_parse_rules; *p; p++) { - unsigned char hash[20]; - char path[PATH_MAX]; - const char *ref, *it; - - mksnpath(path, sizeof(path), *p, len, str); - ref = resolve_ref_unsafe(path, RESOLVE_REF_READING, - hash, NULL); - if (!ref) - continue; - if (reflog_exists(path)) - it = path; - else if (strcmp(ref, path) && reflog_exists(ref)) - it = ref; - else - continue; - if (!logs_found++) { - *log = xstrdup(it); - hashcpy(sha1, hash); - } - if (!warn_ambiguous_refs) - break; - } - free(last_branch); - return logs_found; -} - -/* * Locks a ref returning the lock on success and NULL on failure. * On failure errno is set to something meaningful. */ @@ -4121,99 +4011,6 @@ cleanup: return ret; } -char *shorten_unambiguous_ref(const char *refname, int strict) -{ - int i; - static char **scanf_fmts; - static int nr_rules; - char *short_name; - - if (!nr_rules) { - /* - * Pre-generate scanf formats from ref_rev_parse_rules[]. - * Generate a format suitable for scanf from a - * ref_rev_parse_rules rule by interpolating "%s" at the - * location of the "%.*s". - */ - size_t total_len = 0; - size_t offset = 0; - - /* the rule list is NULL terminated, count them first */ - for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++) - /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */ - total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1; - - scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len); - - offset = 0; - for (i = 0; i < nr_rules; i++) { - assert(offset < total_len); - scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset; - offset += snprintf(scanf_fmts[i], total_len - offset, - ref_rev_parse_rules[i], 2, "%s") + 1; - } - } - - /* bail out if there are no rules */ - if (!nr_rules) - return xstrdup(refname); - - /* buffer for scanf result, at most refname must fit */ - short_name = xstrdup(refname); - - /* skip first rule, it will always match */ - for (i = nr_rules - 1; i > 0 ; --i) { - int j; - int rules_to_fail = i; - int short_name_len; - - if (1 != sscanf(refname, scanf_fmts[i], short_name)) - continue; - - short_name_len = strlen(short_name); - - /* - * in strict mode, all (except the matched one) rules - * must fail to resolve to a valid non-ambiguous ref - */ - if (strict) - rules_to_fail = nr_rules; - - /* - * check if the short name resolves to a valid ref, - * but use only rules prior to the matched one - */ - for (j = 0; j < rules_to_fail; j++) { - const char *rule = ref_rev_parse_rules[j]; - char refname[PATH_MAX]; - - /* skip matched rule */ - if (i == j) - continue; - - /* - * the short name is ambiguous, if it resolves - * (with this previous rule) to a valid ref - * read_ref() returns 0 on success - */ - mksnpath(refname, sizeof(refname), - rule, short_name_len, short_name); - if (ref_exists(refname)) - break; - } - - /* - * short name is non-ambiguous if all previous rules - * haven't resolved to a valid ref - */ - if (j == rules_to_fail) - return short_name; - } - - free(short_name); - return xstrdup(refname); -} - struct expire_reflog_cb { unsigned int flags; reflog_expiry_should_prune_fn *should_prune_fn; diff --git a/refs.c b/refs.c index 071784c..e0bc031 100644 --- a/refs.c +++ b/refs.c @@ -342,3 +342,206 @@ int ref_is_hidden(const char *refname) } return 0; } + +static const char *ref_rev_parse_rules[] = { + "%.*s", + "refs/%.*s", + "refs/tags/%.*s", + "refs/heads/%.*s", + "refs/remotes/%.*s", + "refs/remotes/%.*s/HEAD", + NULL +}; + +int refname_match(const char *abbrev_name, const char *full_name) +{ + const char **p; + const int abbrev_name_len = strlen(abbrev_name); + + for (p = ref_rev_parse_rules; *p; p++) { + if (!strcmp(full_name, mkpath(*p, abbrev_name_len, abbrev_name))) { + return 1; + } + } + + return 0; +} + +/* + * *string and *len will only be substituted, and *string returned (for + * later free()ing) if the string passed in is a magic short-hand form + * to name a branch. + */ +static char *substitute_branch_name(const char **string, int *len) +{ + struct strbuf buf = STRBUF_INIT; + int ret = interpret_branch_name(*string, *len, &buf); + + if (ret == *len) { + size_t size; + *string = strbuf_detach(&buf, &size); + *len = size; + return (char *)*string; + } + + return NULL; +} + +int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) +{ + char *last_branch = substitute_branch_name(&str, &len); + const char **p, *r; + int refs_found = 0; + + *ref = NULL; + for (p = ref_rev_parse_rules; *p; p++) { + char fullref[PATH_MAX]; + unsigned char sha1_from_ref[20]; + unsigned char *this_result; + int flag; + + this_result = refs_found ? sha1_from_ref : sha1; + mksnpath(fullref, sizeof(fullref), *p, len, str); + r = resolve_ref_unsafe(fullref, RESOLVE_REF_READING, + this_result, &flag); + if (r) { + if (!refs_found++) + *ref = xstrdup(r); + if (!warn_ambiguous_refs) + break; + } else if ((flag & REF_ISSYMREF) && strcmp(fullref, "HEAD")) { + warning("ignoring dangling symref %s.", fullref); + } else if ((flag & REF_ISBROKEN) && strchr(fullref, '/')) { + warning("ignoring broken ref %s.", fullref); + } + } + free(last_branch); + return refs_found; +} + +int dwim_log(const char *str, int len, unsigned char *sha1, char **log) +{ + char *last_branch = substitute_branch_name(&str, &len); + const char **p; + int logs_found = 0; + + *log = NULL; + for (p = ref_rev_parse_rules; *p; p++) { + unsigned char hash[20]; + char path[PATH_MAX]; + const char *ref, *it; + + mksnpath(path, sizeof(path), *p, len, str); + ref = resolve_ref_unsafe(path, RESOLVE_REF_READING, + hash, NULL); + if (!ref) + continue; + if (reflog_exists(path)) + it = path; + else if (strcmp(ref, path) && reflog_exists(ref)) + it = ref; + else + continue; + if (!logs_found++) { + *log = xstrdup(it); + hashcpy(sha1, hash); + } + if (!warn_ambiguous_refs) + break; + } + free(last_branch); + return logs_found; +} + +char *shorten_unambiguous_ref(const char *refname, int strict) +{ + int i; + static char **scanf_fmts; + static int nr_rules; + char *short_name; + + if (!nr_rules) { + /* + * Pre-generate scanf formats from ref_rev_parse_rules[]. + * Generate a format suitable for scanf from a + * ref_rev_parse_rules rule by interpolating "%s" at the + * location of the "%.*s". + */ + size_t total_len = 0; + size_t offset = 0; + + /* the rule list is NULL terminated, count them first */ + for (nr_rules = 0; ref_rev_parse_rules[nr_rules]; nr_rules++) + /* -2 for strlen("%.*s") - strlen("%s"); +1 for NUL */ + total_len += strlen(ref_rev_parse_rules[nr_rules]) - 2 + 1; + + scanf_fmts = xmalloc(nr_rules * sizeof(char *) + total_len); + + offset = 0; + for (i = 0; i < nr_rules; i++) { + assert(offset < total_len); + scanf_fmts[i] = (char *)&scanf_fmts[nr_rules] + offset; + offset += snprintf(scanf_fmts[i], total_len - offset, + ref_rev_parse_rules[i], 2, "%s") + 1; + } + } + + /* bail out if there are no rules */ + if (!nr_rules) + return xstrdup(refname); + + /* buffer for scanf result, at most refname must fit */ + short_name = xstrdup(refname); + + /* skip first rule, it will always match */ + for (i = nr_rules - 1; i > 0 ; --i) { + int j; + int rules_to_fail = i; + int short_name_len; + + if (1 != sscanf(refname, scanf_fmts[i], short_name)) + continue; + + short_name_len = strlen(short_name); + + /* + * in strict mode, all (except the matched one) rules + * must fail to resolve to a valid non-ambiguous ref + */ + if (strict) + rules_to_fail = nr_rules; + + /* + * check if the short name resolves to a valid ref, + * but use only rules prior to the matched one + */ + for (j = 0; j < rules_to_fail; j++) { + const char *rule = ref_rev_parse_rules[j]; + char refname[PATH_MAX]; + + /* skip matched rule */ + if (i == j) + continue; + + /* + * the short name is ambiguous, if it resolves + * (with this previous rule) to a valid ref + * read_ref() returns 0 on success + */ + mksnpath(refname, sizeof(refname), + rule, short_name_len, short_name); + if (ref_exists(refname)) + break; + } + + /* + * short name is non-ambiguous if all previous rules + * haven't resolved to a valid ref + */ + if (j == rules_to_fail) + return short_name; + } + + free(short_name); + return xstrdup(refname); +} -- 2.4.2.658.g6d8523e-twtrsrc