]> git.ipfire.org Git - thirdparty/git.git/blobdiff - ref-filter.c
t3905: use test_cmp() to check file contents
[thirdparty/git.git] / ref-filter.c
index aa260bfd0995564e085f69b5b1c7ecaf4b49f359..fd994e18744cebd22e68fd1d969fb0f621d2362e 100644 (file)
@@ -1536,36 +1536,27 @@ char *get_head_description(void)
        struct wt_status_state state;
        memset(&state, 0, sizeof(state));
        wt_status_get_state(the_repository, &state, 1);
-
-       /*
-        * The ( character must be hard-coded and not part of a localizable
-        * string, since the description is used as a sort key and compared
-        * with ref names.
-        */
-       strbuf_addch(&desc, '(');
        if (state.rebase_in_progress ||
            state.rebase_interactive_in_progress) {
                if (state.branch)
-                       strbuf_addf(&desc, _("no branch, rebasing %s"),
+                       strbuf_addf(&desc, _("(no branch, rebasing %s)"),
                                    state.branch);
                else
-                       strbuf_addf(&desc, _("no branch, rebasing detached HEAD %s"),
+                       strbuf_addf(&desc, _("(no branch, rebasing detached HEAD %s)"),
                                    state.detached_from);
        } else if (state.bisect_in_progress)
-               strbuf_addf(&desc, _("no branch, bisect started on %s"),
+               strbuf_addf(&desc, _("(no branch, bisect started on %s)"),
                            state.branch);
        else if (state.detached_from) {
                if (state.detached_at)
-                       strbuf_addstr(&desc, HEAD_DETACHED_AT);
+                       strbuf_addf(&desc, _("(HEAD detached at %s)"),
+                               state.detached_from);
                else
-                       strbuf_addstr(&desc, HEAD_DETACHED_FROM);
-               strbuf_addstr(&desc, state.detached_from);
-       }
-       else
-               strbuf_addstr(&desc, _("no branch"));
-       strbuf_addch(&desc, ')');
+                       strbuf_addf(&desc, _("(HEAD detached from %s)"),
+                               state.detached_from);
+       } else
+               strbuf_addstr(&desc, _("(no branch)"));
 
-       wt_status_state_free_buffers(&state);
        return strbuf_detach(&desc, NULL);
 }
 
@@ -1929,64 +1920,6 @@ static int filter_pattern_match(struct ref_filter *filter, const char *refname)
        return match_pattern(filter, refname);
 }
 
-static int qsort_strcmp(const void *va, const void *vb)
-{
-       const char *a = *(const char **)va;
-       const char *b = *(const char **)vb;
-
-       return strcmp(a, b);
-}
-
-static void find_longest_prefixes_1(struct string_list *out,
-                                 struct strbuf *prefix,
-                                 const char **patterns, size_t nr)
-{
-       size_t i;
-
-       for (i = 0; i < nr; i++) {
-               char c = patterns[i][prefix->len];
-               if (!c || is_glob_special(c)) {
-                       string_list_append(out, prefix->buf);
-                       return;
-               }
-       }
-
-       i = 0;
-       while (i < nr) {
-               size_t end;
-
-               /*
-               * Set "end" to the index of the element _after_ the last one
-               * in our group.
-               */
-               for (end = i + 1; end < nr; end++) {
-                       if (patterns[i][prefix->len] != patterns[end][prefix->len])
-                               break;
-               }
-
-               strbuf_addch(prefix, patterns[i][prefix->len]);
-               find_longest_prefixes_1(out, prefix, patterns + i, end - i);
-               strbuf_setlen(prefix, prefix->len - 1);
-
-               i = end;
-       }
-}
-
-static void find_longest_prefixes(struct string_list *out,
-                                 const char **patterns)
-{
-       struct strvec sorted = STRVEC_INIT;
-       struct strbuf prefix = STRBUF_INIT;
-
-       strvec_pushv(&sorted, patterns);
-       QSORT(sorted.v, sorted.nr, qsort_strcmp);
-
-       find_longest_prefixes_1(out, &prefix, sorted.v, sorted.nr);
-
-       strvec_clear(&sorted);
-       strbuf_release(&prefix);
-}
-
 /*
  * This is the same as for_each_fullref_in(), but it tries to iterate
  * only over the patterns we'll care about. Note that it _doesn't_ do a full
@@ -1997,10 +1930,6 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
                                       void *cb_data,
                                       int broken)
 {
-       struct string_list prefixes = STRING_LIST_INIT_DUP;
-       struct string_list_item *prefix;
-       int ret;
-
        if (!filter->match_as_path) {
                /*
                 * in this case, the patterns are applied after
@@ -2024,16 +1953,8 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
                return for_each_fullref_in("", cb, cb_data, broken);
        }
 
-       find_longest_prefixes(&prefixes, filter->name_patterns);
-
-       for_each_string_list_item(prefix, &prefixes) {
-               ret = for_each_fullref_in(prefix->string, cb, cb_data, broken);
-               if (ret)
-                       break;
-       }
-
-       string_list_clear(&prefixes, 0);
-       return ret;
+       return for_each_fullref_in_prefixes(NULL, filter->name_patterns,
+                                           cb, cb_data, broken);
 }
 
 /*
@@ -2350,12 +2271,24 @@ int filter_refs(struct ref_array *array, struct ref_filter *filter, unsigned int
        return ret;
 }
 
+static int compare_detached_head(struct ref_array_item *a, struct ref_array_item *b)
+{
+       if (!(a->kind ^ b->kind))
+               BUG("ref_kind_from_refname() should only mark one ref as HEAD");
+       if (a->kind & FILTER_REFS_DETACHED_HEAD)
+               return -1;
+       else if (b->kind & FILTER_REFS_DETACHED_HEAD)
+               return 1;
+       BUG("should have died in the xor check above");
+       return 0;
+}
+
 static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, struct ref_array_item *b)
 {
        struct atom_value *va, *vb;
        int cmp;
+       int cmp_detached_head = 0;
        cmp_type cmp_type = used_atom[s->atom].type;
-       int (*cmp_fn)(const char *, const char *);
        struct strbuf err = STRBUF_INIT;
 
        if (get_ref_atom_value(a, s->atom, &va, &err))
@@ -2363,12 +2296,18 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
        if (get_ref_atom_value(b, s->atom, &vb, &err))
                die("%s", err.buf);
        strbuf_release(&err);
-       cmp_fn = s->ignore_case ? strcasecmp : strcmp;
-       if (s->version)
+       if (s->sort_flags & REF_SORTING_DETACHED_HEAD_FIRST &&
+           ((a->kind | b->kind) & FILTER_REFS_DETACHED_HEAD)) {
+               cmp = compare_detached_head(a, b);
+               cmp_detached_head = 1;
+       } else if (s->sort_flags & REF_SORTING_VERSION) {
                cmp = versioncmp(va->s, vb->s);
-       else if (cmp_type == FIELD_STR)
+       } else if (cmp_type == FIELD_STR) {
+               int (*cmp_fn)(const char *, const char *);
+               cmp_fn = s->sort_flags & REF_SORTING_ICASE
+                       ? strcasecmp : strcmp;
                cmp = cmp_fn(va->s, vb->s);
-       else {
+       else {
                if (va->value < vb->value)
                        cmp = -1;
                else if (va->value == vb->value)
@@ -2377,7 +2316,8 @@ static int cmp_ref_sorting(struct ref_sorting *s, struct ref_array_item *a, stru
                        cmp = 1;
        }
 
-       return (s->reverse) ? -cmp : cmp;
+       return (s->sort_flags & REF_SORTING_REVERSE && !cmp_detached_head)
+               ? -cmp : cmp;
 }
 
 static int compare_refs(const void *a_, const void *b_, void *ref_sorting)
@@ -2392,15 +2332,20 @@ static int compare_refs(const void *a_, const void *b_, void *ref_sorting)
                        return cmp;
        }
        s = ref_sorting;
-       return s && s->ignore_case ?
+       return s && s->sort_flags & REF_SORTING_ICASE ?
                strcasecmp(a->refname, b->refname) :
                strcmp(a->refname, b->refname);
 }
 
-void ref_sorting_icase_all(struct ref_sorting *sorting, int flag)
+void ref_sorting_set_sort_flags_all(struct ref_sorting *sorting,
+                                   unsigned int mask, int on)
 {
-       for (; sorting; sorting = sorting->next)
-               sorting->ignore_case = !!flag;
+       for (; sorting; sorting = sorting->next) {
+               if (on)
+                       sorting->sort_flags |= mask;
+               else
+                       sorting->sort_flags &= ~mask;
+       }
 }
 
 void ref_array_sort(struct ref_sorting *sorting, struct ref_array *array)
@@ -2537,12 +2482,12 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *arg)
        *sorting_tail = s;
 
        if (*arg == '-') {
-               s->reverse = 1;
+               s->sort_flags |= REF_SORTING_REVERSE;
                arg++;
        }
        if (skip_prefix(arg, "version:", &arg) ||
            skip_prefix(arg, "v:", &arg))
-               s->version = 1;
+               s->sort_flags |= REF_SORTING_VERSION;
        s->atom = parse_sorting_atom(arg);
 }