checkout: require worktree unconditionally
[gitweb.git] / sha1_name.c
index c2c938c4e161fc6849a87a7a19336712f36f74ff..5b004f513b999b31b7968b22dde955c859704853 100644 (file)
@@ -432,7 +432,8 @@ static inline int upstream_mark(const char *string, int len)
 static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
 static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf);
 
-static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
+static int get_sha1_basic(const char *str, int len, unsigned char *sha1,
+                         unsigned int flags)
 {
        static const char *warn_msg = "refname '%.*s' is ambiguous.";
        static const char *object_name_msg = N_(
@@ -511,7 +512,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
        if (!refs_found)
                return -1;
 
-       if (warn_ambiguous_refs &&
+       if (warn_ambiguous_refs && !(flags & GET_SHA1_QUIETLY) &&
            (refs_found > 1 ||
             !get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))
                warning(warn_msg, len, str);
@@ -540,10 +541,12 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                        char *tmp = xstrndup(str + at + 2, reflog_len);
                        at_time = approxidate_careful(tmp, &errors);
                        free(tmp);
-                       if (errors)
+                       if (errors) {
+                               free(real_ref);
                                return -1;
+                       }
                }
-               if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
+               if (read_ref_at(real_ref, flags, at_time, nth, sha1, NULL,
                                &co_time, &co_tz, &co_cnt)) {
                        if (!len) {
                                if (starts_with(real_ref, "refs/heads/")) {
@@ -555,11 +558,16 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
                                        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 {
+                       if (at_time) {
+                               if (!(flags & GET_SHA1_QUIETLY)) {
+                                       warning("Log for '%.*s' only goes "
+                                               "back to %s.", len, str,
+                                               show_date(co_time, co_tz, DATE_RFC2822));
+                               }
+                       } else {
+                               if (flags & GET_SHA1_QUIETLY) {
+                                       exit(128);
+                               }
                                die("Log for '%.*s' only has %d entries.",
                                    len, str, co_cnt);
                        }
@@ -799,7 +807,7 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
        if (!ret)
                return 0;
 
-       ret = get_sha1_basic(name, len, sha1);
+       ret = get_sha1_basic(name, len, sha1, lookup_flags);
        if (!ret)
                return 0;
 
@@ -837,7 +845,7 @@ static int handle_one_ref(const char *path,
        }
        if (object->type != OBJ_COMMIT)
                return 0;
-       commit_list_insert_by_date((struct commit *)object, list);
+       commit_list_insert((struct commit *)object, list);
        return 0;
 }
 
@@ -901,10 +909,8 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1,
        const char *match = NULL, *target = NULL;
        size_t len;
 
-       if (starts_with(message, "checkout: moving from ")) {
-               match = message + strlen("checkout: moving from ");
+       if (skip_prefix(message, "checkout: moving from ", &match))
                target = strstr(match, " to ");
-       }
 
        if (!match || !target)
                return 0;
@@ -948,7 +954,7 @@ static int interpret_nth_prior_checkout(const char *name, int namelen,
        retval = 0;
        if (0 < for_each_reflog_ent_reverse("HEAD", grab_nth_branch_switch, &cb)) {
                strbuf_reset(buf);
-               strbuf_add(buf, cb.buf.buf, cb.buf.len);
+               strbuf_addbuf(buf, &cb.buf);
                retval = brace - name + 1;
        }
 
@@ -1242,10 +1248,7 @@ static void diagnose_invalid_sha1_path(const char *prefix,
                die("Path '%s' exists on disk, but not in '%.*s'.",
                    filename, object_name_len, object_name);
        if (errno == ENOENT || errno == ENOTDIR) {
-               char *fullname = xmalloc(strlen(filename)
-                                            + strlen(prefix) + 1);
-               strcpy(fullname, prefix);
-               strcat(fullname, filename);
+               char *fullname = xstrfmt("%s%s", prefix, filename);
 
                if (!get_tree_entry(tree_sha1, fullname,
                                    sha1, &mode)) {
@@ -1369,6 +1372,7 @@ static int get_sha1_with_context_1(const char *name,
                if (!only_to_die && namelen > 2 && name[1] == '/') {
                        struct commit_list *list = NULL;
                        for_each_ref(handle_one_ref, &list);
+                       commit_list_sort_by_date(&list);
                        return get_sha1_oneline(name + 2, sha1, list);
                }
                if (namelen < 3 ||