From: Karthik Nayak <karthik.188@gmail.com>
To: Git <git@vger.kernel.org>
Cc: Christian Couder <christian.couder@gmail.com>,
Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>,
Junio C Hamano <gitster@pobox.com>
Subject: [PATCH v5 00/11] port tag.c to use ref-filter APIs
Date: Mon, 27 Jul 2015 12:56:08 +0530 [thread overview]
Message-ID: <CAOLa=ZTtAepdO5U8zo62VBn_z4-LcKoguPxVGaAnNZULEwzrQQ@mail.gmail.com> (raw)
This is part of my GSoC project to unify git tag -l, git branch -l,
git for-each-ref. This patch series is continued from: Git (next)
https://github.com/git/git/commit/bf5418f49ff0cebc6e5ce04ad1417e1a47c81b61
Version 4 can be found here
http://article.gmane.org/gmane.comp.version-control.git/274579
Changes in this version (interdiff at the end):
* Change the way ref_formatting_state is used and the sequence of its
usage in the
series.
* Separate the introduction of ref_formatting_state from its usage.
* Removed the inefficient removal of path in match_pattern().
* Improve coding style in the implementation of sorting based on version.
* Changed the tests for sorting based on version, to use
'for-each-ref' rather than 'tag.c'
which already has a working sort based on version.
* Other small grammatical changes.
* Change the atom name from 'align' to 'padright'.
[PATCH v5 01/11] ref-filter: introduce 'ref_formatting_state'
[PATCH v5 02/11] ref-filter: make `color` use `ref_formatting_state`
[PATCH v5 03/11] ref-filter: add option to pad atoms to the right
[PATCH v5 04/11] ref-filter: add option to filter only tags
[PATCH v5 05/11] ref-filter: support printing N lines from tag
[PATCH v5 06/11] ref-filter: add support to sort by version
[PATCH v5 07/11] ref-filter: add option to match literal pattern
[PATCH v5 08/11] tag.c: use 'ref-filter' data structures
[PATCH v5 09/11] tag.c: use 'ref-filter' APIs
[PATCH v5 10/11] tag.c: implement '--format' option
[PATCH v5 11/11] tag.c: implement '--merged' and '--no-merged'
Interdiff:
diff --git a/Documentation/git-for-each-ref.txt
b/Documentation/git-for-each-ref.txt
index 224dc8c..2b60aee 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -127,6 +127,12 @@ color::
Change output color. Followed by `:<colorname>`, where names
are described in `color.branch.*`.
+padright::
+ Pad succeeding atom to the right. Followed by `:<value>`,
+ where `value` states the total length of atom including the
+ padding. If the `value` is greater than the atom length, then
+ no padding is performed.
+
In addition to the above, for commit and tag objects, the header
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
be used to specify the value in the header field.
diff --git a/builtin/tag.c b/builtin/tag.c
index 8a7f684..fc01117 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -41,13 +41,11 @@ static int list_tags(struct ref_filter *filter,
struct ref_sorting *sorting, con
filter->lines = 0;
if (filter->lines)
- format = "%(align:16)%(refname:short)";
+ format = "%(padright:16)%(refname:short)";
else if (!format)
format = "%(refname:short)";
verify_ref_format(format);
- if (!sorting)
- sorting = ref_default_sorting();
filter_refs(&array, filter, FILTER_REFS_TAGS);
ref_array_sort(sorting, &array);
@@ -134,7 +132,7 @@ static int parse_sorting_string(const char *arg,
struct ref_sorting **sorting_ta
if (*arg == '-') {
s->reverse = 1;
arg++;
- }
+ }
if (skip_prefix(arg, "version:", &arg) ||
skip_prefix(arg, "v:", &arg))
s->version = 1;
diff --git a/ref-filter.c b/ref-filter.c
index c686c03..597b189 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -56,7 +56,7 @@ static struct {
{ "flag" },
{ "HEAD" },
{ "color" },
- { "align" },
+ { "padright" },
};
/*
@@ -601,8 +601,7 @@ static inline char *copy_advance(char *dst, const char *src)
/*
* Parse the object referred by ref, and grab needed value.
*/
-static void populate_value(struct ref_formatting_state *state,
- struct ref_array_item *ref)
+static void populate_value(struct ref_array_item *ref)
{
void *buf;
struct object *obj;
@@ -664,8 +663,9 @@ static void populate_value(struct
ref_formatting_state *state,
if (color_parse(name + 6, color) < 0)
die(_("unable to parse format"));
- state->color = xstrdup(color);
+ v->s = xstrdup(color);
v->pseudo_atom = 1;
+ v->color = 1;
continue;
} else if (!strcmp(name, "flag")) {
char buf[256], *cp = buf;
@@ -693,17 +693,17 @@ static void populate_value(struct
ref_formatting_state *state,
else
v->s = " ";
continue;
- } else if (starts_with(name, "align:")) {
+ } else if (starts_with(name, "padright:")) {
const char *valp = NULL;
- skip_prefix(name, "align:", &valp);
+ skip_prefix(name, "padright:", &valp);
if (!valp[0])
- die(_("no value given with 'align:'"));
- if (strtoul_ui(valp, 10, &state->pad_to_right))
- die(_("positive integer expected after ':' in align:%u\n"),
- state->pad_to_right);
+ die(_("no value given with 'padright:'"));
+ if (strtoul_ui(valp, 10, (unsigned int *)&v->ul))
+ die(_("positive integer expected after ':' in padright:%u\n"),
+ (unsigned int)v->ul);
v->pseudo_atom = 1;
- v->s = "";
+ v->pad_to_right = 1;
continue;
} else
continue;
@@ -827,15 +827,10 @@ static void populate_value(struct
ref_formatting_state *state,
* Given a ref, return the value for the atom. This lazily gets value
* out of the object by calling populate value.
*/
-static void get_ref_atom_value(struct ref_formatting_state *state,
- struct ref_array_item *ref, int atom, struct atom_value **v)
+static void get_ref_atom_value(struct ref_array_item *ref, int atom,
struct atom_value **v)
{
- /*
- * If the atom is a pseudo_atom then we re-populate the value
- * into the ref_formatting_state stucture.
- */
- if (!ref->value || ref->value[atom].pseudo_atom) {
- populate_value(state, ref);
+ if (!ref->value) {
+ populate_value(ref);
fill_missing_values(ref->value);
}
*v = &ref->value[atom];
@@ -957,17 +952,18 @@ static int commit_contains(struct ref_filter
*filter, struct commit *commit)
*/
static int match_pattern(const char **patterns, const char *refname)
{
+ /*
+ * When no '--format' option is given we need to skip the prefix
+ * for matching refs of tags and branches.
+ */
+ if (skip_prefix(refname, "refs/tags/", &refname))
+ ;
+ else if (skip_prefix(refname, "refs/heads/", &refname))
+ ;
+ else if (skip_prefix(refname, "refs/remotes/", &refname))
+ ;
+
for (; *patterns; patterns++) {
- /*
- * When no '--format' option is given we need to skip the prefix
- * for listing tags and branches.
- */
- if (!starts_with(*pattern, "refs/tags/"))
- skip_prefix(refname, "refs/tags/", &refname);
- else if (!starts_with(*pattern, "refs/heads/"))
- skip_prefix(refname, "refs/heads/", &refname);
- else if (!starts_with(refname, "refs/remotes/"))
- skip_prefix(refname, "refs/remotes/", &refname);
if (!wildmatch(*patterns, refname, 0, NULL))
return 1;
}
@@ -978,7 +974,7 @@ static int match_pattern(const char **patterns,
const char *refname)
* Return 1 if the refname matches one of the patterns, otherwise 0.
* A pattern can be path prefix (e.g. a refname "refs/heads/master"
* matches a pattern "refs/heads/") or a wildcard (e.g. the same ref
- * matches "refs/heads/m*", too).
+ * matches "refs/heads/m*",too).
*/
static int match_name_as_path(const char **pattern, const char *refname)
{
@@ -1210,22 +1206,21 @@ static int cmp_ref_sorting(struct ref_sorting
*s, struct ref_array_item *a, stru
struct atom_value *va, *vb;
int cmp;
cmp_type cmp_type = used_atom_type[s->atom];
- struct ref_formatting_state state;
- memset(&state, 0, sizeof(state));
-
- get_ref_atom_value(&state, a, s->atom, &va);
- get_ref_atom_value(&state, b, s->atom, &vb);
+ get_ref_atom_value(a, s->atom, &va);
+ get_ref_atom_value(b, s->atom, &vb);
if (s->version)
cmp = versioncmp(va->s, vb->s);
else if (cmp_type == FIELD_STR)
cmp = strcmp(va->s, vb->s);
- else if (va->ul < vb->ul)
- cmp = -1;
- else if (va->ul == vb->ul)
- cmp = 0;
- else
- cmp = 1;
+ else {
+ if (va->ul < vb->ul)
+ cmp = -1;
+ else if (va->ul == vb->ul)
+ cmp = 0;
+ else
+ cmp = 1;
+ }
return (s->reverse) ? -cmp : cmp;
}
@@ -1251,20 +1246,20 @@ void ref_array_sort(struct ref_sorting
*sorting, struct ref_array *array)
qsort(array->items, array->nr, sizeof(struct ref_array_item *),
compare_refs);
}
-static void ref_formatting(struct ref_formatting_state *state, struct
atom_value *v,
- struct strbuf *value)
+static void ref_formatting(struct ref_formatting_state *state,
+ struct atom_value *v, struct strbuf *value)
{
if (state->color) {
strbuf_addstr(value, state->color);
- free((void *)state->color);
+ free(state->color);
state->color = NULL;
}
if (state->pad_to_right) {
if (!is_utf8(v->s))
strbuf_addf(value, "%-*s", state->pad_to_right, v->s);
else {
- int len = strlen(v->s) - utf8_strwidth(v->s);
- strbuf_addf(value, "%-*s", state->pad_to_right + len, v->s);
+ int utf8_compensation = strlen(v->s) - utf8_strwidth(v->s);
+ strbuf_addf(value, "%-*s", state->pad_to_right +
utf8_compensation, v->s);
}
return;
}
@@ -1276,8 +1271,6 @@ static void print_value(struct
ref_formatting_state *state, struct atom_value *v
struct strbuf value = STRBUF_INIT;
struct strbuf formatted = STRBUF_INIT;
- if (v->pseudo_atom)
- return;
ref_formatting(state, v, &value);
switch (state->quote_style) {
@@ -1341,6 +1334,15 @@ static void emit(const char *cp, const char *ep)
}
}
+static void apply_pseudo_state(struct ref_formatting_state *state,
+ struct atom_value *v)
+{
+ if (v->color)
+ state->color = (char *)v->s;
+ if (v->pad_to_right)
+ state->pad_to_right = v->ul;
+}
+
/*
* If 'lines' is greater than 0, print that many lines from the given
* object_id 'oid'.
@@ -1399,9 +1401,11 @@ void show_ref_array_item(struct ref_array_item
*info, const char *format,
ep = strchr(sp, ')');
if (cp < sp)
emit(cp, sp);
- get_ref_atom_value(&state, info,
- parse_ref_filter_atom(sp + 2, ep), &atomv);
- print_value(&state, atomv);
+ get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv);
+ if (atomv->pseudo_atom)
+ apply_pseudo_state(&state, atomv);
+ else
+ print_value(&state, atomv);
}
if (*cp) {
sp = cp + strlen(cp);
@@ -1413,8 +1417,7 @@ void show_ref_array_item(struct ref_array_item
*info, const char *format,
if (color_parse("reset", color) < 0)
die("BUG: couldn't parse 'reset' as a color");
- resetv.s = "";
- state.color = xstrdup(color);
+ resetv.s = color;
print_value(&state, &resetv);
}
if (lines > 0) {
diff --git a/ref-filter.h b/ref-filter.h
index f1933e0..a27745f 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -20,7 +20,15 @@
struct atom_value {
const char *s;
unsigned long ul; /* used for sorting when not FIELD_STR */
- unsigned int pseudo_atom : 1; /* atoms which aren't placeholders
for ref attributes */
+ unsigned int pseudo_atom : 1, /* atoms which aren't placeholders
for ref attributes */
+ color : 1,
+ pad_to_right : 1;
+};
+
+struct ref_formatting_state {
+ int quote_style;
+ char *color;
+ unsigned int pad_to_right;
};
struct ref_sorting {
@@ -30,12 +38,6 @@ struct ref_sorting {
version : 1;
};
-struct ref_formatting_state {
- unsigned int pad_to_right; /*pad atoms to the right*/
- int quote_style;
- const char *color;
-};
-
struct ref_array_item {
unsigned char objectname[20];
int flag;
diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
index 5017032..de872db 100755
--- a/t/t6302-for-each-ref-filter.sh
+++ b/t/t6302-for-each-ref-filter.sh
@@ -81,6 +81,22 @@ test_expect_success 'filtering with --contains' '
test_cmp expect actual
'
+test_expect_success 'padding to the right using `padright`' '
+ cat >expect <<-\EOF &&
+ refs/heads/master |
+ refs/heads/side |
+ refs/odd/spot |
+ refs/tags/double-tag |
+ refs/tags/four |
+ refs/tags/one |
+ refs/tags/signed-tag |
+ refs/tags/three |
+ refs/tags/two |
+ EOF
+ git for-each-ref --format="%(padright:25)%(refname)|" >actual &&
+ test_cmp expect actual
+'
+
test_expect_success 'setup for version sort' '
test_commit foo1.3 &&
test_commit foo1.6 &&
@@ -88,7 +104,7 @@ test_expect_success 'setup for version sort' '
'
test_expect_success 'version sort' '
- git tag -l --sort=version:refname | grep "foo" >actual &&
+ git for-each-ref --sort=version:refname
--format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
cat >expect <<-\EOF &&
foo1.3
foo1.6
@@ -98,7 +114,7 @@ test_expect_success 'version sort' '
'
test_expect_success 'version sort (shortened)' '
- git tag -l --sort=v:refname | grep "foo" >actual &&
+ git for-each-ref --sort=v:refname --format="%(refname:short)"
refs/tags/ | grep "foo" >actual &&
cat >expect <<-\EOF &&
foo1.3
foo1.6
@@ -108,7 +124,7 @@ test_expect_success 'version sort (shortened)' '
'
test_expect_success 'reverse version sort' '
- git tag -l --sort=-version:refname | grep "foo" >actual &&
+ git for-each-ref --sort=-version:refname
--format="%(refname:short)" refs/tags/ | grep "foo" >actual &&
cat >expect <<-\EOF &&
foo1.10
foo1.6
diff --git a/v3-0001-ref-filter-add-option-to-align-atoms-to-the-left.patch
b/v3-0001-ref-filter-add-option-to-align-atoms-to-the-left.patch
deleted file mode 100644
index 350acae..0000000
--- a/v3-0001-ref-filter-add-option-to-align-atoms-to-the-left.patch
+++ /dev/null
@@ -1,124 +0,0 @@
-From 3a07ca1f56f74ca54b7f3c30e3dfd9fe2fed1cc3 Mon Sep 17 00:00:00 2001
-From: Karthik Nayak <karthik.188@gmail.com>
-Date: Wed, 10 Jun 2015 17:19:55 +0530
-Subject: [PATCH v3 1/9] ref-filter: add option to align atoms to the left
-
-Add a new atom "align" and support %(align:X) where X is a number.
-This will align the preceeding atom value to the left followed by
-spaces for a total length of X characters. If X is less than the item
-size, the entire atom value is printed.
-
-Helped-by: Duy Nguyen <pclouds@gmail.com>
-Mentored-by: Christian Couder <christian.couder@gmail.com>
-Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
-Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
----
- ref-filter.c | 41 +++++++++++++++++++++++++++++++++++++++--
- ref-filter.h | 1 +
- 2 files changed, 40 insertions(+), 2 deletions(-)
-
-diff --git a/ref-filter.c b/ref-filter.c
-index 7561727..93f59aa 100644
---- a/ref-filter.c
-+++ b/ref-filter.c
-@@ -10,6 +10,8 @@
- #include "quote.h"
- #include "ref-filter.h"
- #include "revision.h"
-+#include "utf8.h"
-+#include "git-compat-util.h"
-
- typedef enum { FIELD_STR, FIELD_ULONG, FIELD_TIME } cmp_type;
-
-@@ -53,6 +55,7 @@ static struct {
- { "flag" },
- { "HEAD" },
- { "color" },
-+ { "align" },
- };
-
- /*
-@@ -620,7 +623,7 @@ static void populate_value(struct ref_array_item *ref)
- const char *name = used_atom[i];
- struct atom_value *v = &ref->value[i];
- int deref = 0;
-- const char *refname;
-+ const char *refname = NULL;
- const char *formatp;
- struct branch *branch = NULL;
-
-@@ -687,6 +690,17 @@ static void populate_value(struct ref_array_item *ref)
- else
- v->s = " ";
- continue;
-+ } else if (starts_with(name, "align:")) {
-+ const char *valp = NULL;
-+
-+ skip_prefix(name, "align:", &valp);
-+ if (!valp[0])
-+ die(_("no value given with 'align:'"));
-+ strtoul_ui(valp, 10, &ref->align_value);
-+ if (ref->align_value < 1)
-+ die(_("value should be greater than zero:
align:%u"), ref->align_value);
-+ v->s = "";
-+ continue;
- } else
- continue;
-
-@@ -1254,17 +1268,40 @@ static void emit(const char *cp, const char *ep)
- }
- }
-
-+static void assign_formating(struct ref_array_item *ref, int
parsed_atom, struct atom_value *v)
-+{
-+ if (ref->align_value && !starts_with(used_atom[parsed_atom], "align")) {
-+ unsigned int len = 0;
-+
-+ if (*v->s)
-+ len = utf8_strwidth(v->s);
-+ if (ref->align_value > len) {
-+ struct strbuf buf = STRBUF_INIT;
-+ if (*v->s)
-+ strbuf_addstr(&buf, v->s);
-+ if (*v->s && v->s[0] == '\0')
-+ free((char *)v->s);
-+ strbuf_addchars(&buf, ' ', ref->align_value - len);
-+ v->s = strbuf_detach(&buf, NULL);
-+ }
-+ ref->align_value = 0;
-+ }
-+}
-+
- void show_ref_array_item(struct ref_array_item *info, const char
*format, int quote_style)
- {
- const char *cp, *sp, *ep;
-
- for (cp = format; *cp && (sp = find_next(cp)); cp = ep + 1) {
- struct atom_value *atomv;
-+ int parsed_atom;
-
- ep = strchr(sp, ')');
- if (cp < sp)
- emit(cp, sp);
-- get_ref_atom_value(info, parse_ref_filter_atom(sp + 2, ep), &atomv);
-+ parsed_atom = parse_ref_filter_atom(sp + 2, ep);
-+ get_ref_atom_value(info, parsed_atom, &atomv);
-+ assign_formating(info, parsed_atom, atomv);
- print_value(atomv, quote_style);
- }
- if (*cp) {
-diff --git a/ref-filter.h b/ref-filter.h
-index 6bf27d8..12ffbc5 100644
---- a/ref-filter.h
-+++ b/ref-filter.h
-@@ -30,6 +30,7 @@ struct ref_sorting {
- struct ref_array_item {
- unsigned char objectname[20];
- int flag;
-+ unsigned int align_value;
- const char *symref;
- struct commit *commit;
- struct atom_value *value;
---
-2.4.6
-
Thanks to everyone for suggestions on the previous version.
--
Regards,
Karthik Nayak
next reply other threads:[~2015-07-27 7:26 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-07-27 7:26 Karthik Nayak [this message]
2015-07-27 7:27 ` [PATCH v5 01/11] ref-filter: introduce 'ref_formatting_state' Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 02/11] ref-filter: make `color` use `ref_formatting_state` Karthik Nayak
2015-07-27 12:47 ` Matthieu Moy
2015-07-27 14:28 ` Junio C Hamano
2015-07-27 17:23 ` Karthik Nayak
2015-07-27 16:02 ` Karthik Nayak
2015-07-27 13:06 ` Matthieu Moy
2015-07-27 17:16 ` Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 03/11] ref-filter: add option to pad atoms to the right Karthik Nayak
2015-07-27 12:50 ` Matthieu Moy
2015-07-27 15:45 ` Junio C Hamano
2015-07-27 15:54 ` Matthieu Moy
2015-07-27 18:42 ` Karthik Nayak
2015-07-27 18:47 ` Matthieu Moy
2015-07-27 18:54 ` Karthik Nayak
2015-07-27 18:56 ` Junio C Hamano
2015-07-27 18:43 ` Karthik Nayak
2015-07-28 21:41 ` Eric Sunshine
2015-07-29 16:16 ` Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 04/11] ref-filter: add option to filter only tags Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 05/11] ref-filter: support printing N lines from tag annotation Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 06/11] ref-filter: add support to sort by version Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 07/11] ref-filter: add option to match literal pattern Karthik Nayak
2015-07-27 12:54 ` Matthieu Moy
2015-07-27 15:57 ` Karthik Nayak
2015-07-27 15:59 ` Karthik Nayak
2015-07-27 16:06 ` Matthieu Moy
2015-07-27 16:48 ` Karthik Nayak
2015-07-28 21:49 ` Eric Sunshine
2015-07-29 16:17 ` Karthik Nayak
2015-07-30 11:21 ` Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 08/11] tag.c: use 'ref-filter' data structures Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 09/11] tag.c: use 'ref-filter' APIs Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 10/11] tag.c: implement '--format' option Karthik Nayak
2015-07-27 7:27 ` [PATCH v5 11/11] tag.c: implement '--merged' and '--no-merged' options Karthik Nayak
2015-07-27 12:42 ` [PATCH v5 01/11] ref-filter: introduce 'ref_formatting_state' Matthieu Moy
2015-07-27 15:28 ` Karthik Nayak
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='CAOLa=ZTtAepdO5U8zo62VBn_z4-LcKoguPxVGaAnNZULEwzrQQ@mail.gmail.com' \
--to=karthik.188@gmail.com \
--cc=Matthieu.Moy@grenoble-inp.fr \
--cc=christian.couder@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).