t4211: retire soon-to-be unimplementable tests
[gitweb.git] / sha1_name.c
index 5a58720d85be0af90a32490e31831df5bc7f1ae8..852dd951dc2d93660727de23ea9467503288e25b 100644 (file)
@@ -52,7 +52,7 @@ static void update_candidates(struct disambiguate_state *ds, const unsigned char
        }
 
        if (!ds->candidate_ok) {
-               /* discard the candidate; we know it does not satisify fn */
+               /* discard the candidate; we know it does not satisfy fn */
                hashcpy(ds->candidate, current);
                ds->candidate_checked = 0;
                return;
@@ -241,7 +241,7 @@ static int disambiguate_committish_only(const unsigned char *sha1, void *cb_data
                return 0;
 
        /* We need to do this the hard way... */
-       obj = deref_tag(lookup_object(sha1), NULL, 0);
+       obj = deref_tag(parse_object(sha1), NULL, 0);
        if (obj && obj->type == OBJ_COMMIT)
                return 1;
        return 0;
@@ -436,12 +436,33 @@ static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf);
 static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
 {
        static const char *warn_msg = "refname '%.*s' is ambiguous.";
+       static const char *object_name_msg = N_(
+       "Git normally never creates a ref that ends with 40 hex characters\n"
+       "because it will be ignored when you just specify 40-hex. These refs\n"
+       "may be created by mistake. For example,\n"
+       "\n"
+       "  git checkout -b $br $(git rev-parse ...)\n"
+       "\n"
+       "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n"
+       "examine these refs and maybe delete them. Turn this message off by\n"
+       "running \"git config advice.objectNameWarning false\"");
+       unsigned char tmp_sha1[20];
        char *real_ref = NULL;
        int refs_found = 0;
        int at, reflog_len, nth_prior = 0;
 
-       if (len == 40 && !get_sha1_hex(str, sha1))
+       if (len == 40 && !get_sha1_hex(str, sha1)) {
+               if (warn_on_object_refname_ambiguity) {
+                       refs_found = dwim_ref(str, len, tmp_sha1, &real_ref);
+                       if (refs_found > 0 && warn_ambiguous_refs) {
+                               warning(warn_msg, len, str);
+                               if (advice_object_name_warning)
+                                       fprintf(stderr, "%s\n", _(object_name_msg));
+                       }
+                       free(real_ref);
+               }
                return 0;
+       }
 
        /* basic@{time or number or -number} format to query ref-log */
        reflog_len = at = 0;
@@ -491,7 +512,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
        if (!refs_found)
                return -1;
 
-       if (warn_ambiguous_refs && refs_found > 1)
+       if (warn_ambiguous_refs &&
+           (refs_found > 1 ||
+            !get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))
                warning(warn_msg, len, str);
 
        if (reflog_len) {
@@ -523,12 +546,21 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                }
                if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
                                &co_time, &co_tz, &co_cnt)) {
+                       if (!len) {
+                               if (!prefixcmp(real_ref, "refs/heads/")) {
+                                       str = real_ref + 11;
+                                       len = strlen(real_ref + 11);
+                               } else {
+                                       /* detached HEAD */
+                                       str = "HEAD";
+                                       len = 4;
+                               }
+                       }
                        if (at_time)
                                warning("Log for '%.*s' only goes "
                                        "back to %s.", len, str,
                                        show_date(co_time, co_tz, DATE_RFC2822));
                        else {
-                               free(real_ref);
                                die("Log for '%.*s' only has %d entries.",
                                    len, str, co_cnt);
                        }
@@ -1062,14 +1094,15 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
         * points to something different than a branch.
         */
        if (!upstream)
-               return error(_("HEAD does not point to a branch"));
+               die(_("HEAD does not point to a branch"));
        if (!upstream->merge || !upstream->merge[0]->dst) {
                if (!ref_exists(upstream->refname))
-                       return error(_("No such branch: '%s'"), cp);
-               if (!upstream->merge)
-                       return error(_("No upstream configured for branch '%s'"),
-                                    upstream->name);
-               return error(
+                       die(_("No such branch: '%s'"), cp);
+               if (!upstream->merge) {
+                       die(_("No upstream configured for branch '%s'"),
+                               upstream->name);
+               }
+               die(
                        _("Upstream branch '%s' not stored as a remote-tracking branch"),
                        upstream->merge[0]->src);
        }
@@ -1084,9 +1117,13 @@ int interpret_branch_name(const char *name, struct strbuf *buf)
 int strbuf_branchname(struct strbuf *sb, const char *name)
 {
        int len = strlen(name);
-       if (interpret_branch_name(name, sb) == len)
+       int used = interpret_branch_name(name, sb);
+
+       if (used == len)
                return 0;
-       strbuf_add(sb, name, len);
+       if (used < 0)
+               used = 0;
+       strbuf_add(sb, name + used, len - used);
        return len;
 }
 
@@ -1199,7 +1236,7 @@ static void diagnose_invalid_index_path(int stage,
                                        const char *filename)
 {
        struct stat st;
-       struct cache_entry *ce;
+       const struct cache_entry *ce;
        int pos;
        unsigned namelen = strlen(filename);
        unsigned fullnamelen;
@@ -1293,7 +1330,7 @@ static int get_sha1_with_context_1(const char *name,
         */
        if (name[0] == ':') {
                int stage = 0;
-               struct cache_entry *ce;
+               const struct cache_entry *ce;
                char *new_path = NULL;
                int pos;
                if (!only_to_die && namelen > 2 && name[1] == '/') {