Similar to version:refname sorting refs by versions, icase:refname
will sort by refnames are usually, but strcasecmp will be used instead
of strcmp. This may be helpful sometimes when people name their
branches <group>-<details> but somebody names it <group>-, some goes
with <Group>-, or even <GROUP>-

Syntax is a big problem. This patch does not support
icase:version:refname or version:icase:refname, for example. If
version sorting learns about this thing, I think I prefer
iversion:refname...

Or perhaps we can. I'm losing touch with for-each-ref "pretty"
formats, I'm not quite sure what's the guideline here.

Another option is just use a symbol, like '-' or '*' to mark
case-insensitivity. But that does not look very descriptive. I don't
see any symbol suggesting this case stuff.

What do you think?

Signed-off-by: Nguyễn Thái Ngọc Duy <pclo...@gmail.com>
---
 Documentation/git-for-each-ref.txt | 3 ++-
 ref-filter.c                       | 8 ++++++--
 ref-filter.h                       | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-for-each-ref.txt 
b/Documentation/git-for-each-ref.txt
index f57e69bc83..e41005cf0e 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -171,7 +171,8 @@ For sorting purposes, fields with numeric values sort in 
numeric order
 All other fields are used to sort in their byte-value order.
 
 There is also an option to sort by versions, this can be done by using
-the fieldname `version:refname` or its alias `v:refname`.
+the fieldname `version:refname` or its alias `v:refname`. Prefixing
+"icase:" (e.g. `icase:refname`) makes sorting case-insensitive.
 
 In any case, a field name that refers to a field inapplicable to
 the object referred by the ref does not cause an error.  It
diff --git a/ref-filter.c b/ref-filter.c
index d4c2931f3a..fd63b9c710 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1542,12 +1542,12 @@ static int cmp_ref_sorting(struct ref_sorting *s, 
struct ref_array_item *a, stru
        if (s->version)
                cmp = versioncmp(va->s, vb->s);
        else if (cmp_type == FIELD_STR)
-               cmp = strcmp(va->s, vb->s);
+               cmp = s->strcmp(va->s, vb->s);
        else {
                if (va->ul < vb->ul)
                        cmp = -1;
                else if (va->ul == vb->ul)
-                       cmp = strcmp(a->refname, b->refname);
+                       cmp = s->strcmp(a->refname, b->refname);
                else
                        cmp = 1;
        }
@@ -1646,6 +1646,7 @@ struct ref_sorting *ref_default_sorting(void)
 
        sorting->next = NULL;
        sorting->atom = parse_ref_filter_atom(cstr_name, cstr_name + 
strlen(cstr_name));
+       sorting->strcmp = strcmp;
        return sorting;
 }
 
@@ -1660,6 +1661,7 @@ int parse_opt_ref_sorting(const struct option *opt, const 
char *arg, int unset)
 
        s = xcalloc(1, sizeof(*s));
        s->next = *sorting_tail;
+       s->strcmp = strcmp;
        *sorting_tail = s;
 
        if (*arg == '-') {
@@ -1669,6 +1671,8 @@ int parse_opt_ref_sorting(const struct option *opt, const 
char *arg, int unset)
        if (skip_prefix(arg, "version:", &arg) ||
            skip_prefix(arg, "v:", &arg))
                s->version = 1;
+       else if (skip_prefix(arg, "icase:", &arg))
+               s->strcmp = strcasecmp;
        len = strlen(arg);
        s->atom = parse_ref_filter_atom(arg, arg+len);
        return 0;
diff --git a/ref-filter.h b/ref-filter.h
index 14d435e2cc..ea2db565f1 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -30,6 +30,7 @@ struct ref_sorting {
        int atom; /* index into used_atom array (internal) */
        unsigned reverse : 1,
                version : 1;
+       int (*strcmp)(const char *, const char *);
 };
 
 struct ref_array_item {
-- 
2.11.0.rc0.161.g80d5b92

Reply via email to