git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v17 00/14] port tag.c to use ref-filter APIs

From
Karthik Nayak <karthik.188@gmail.com>
Date
Sep 10, 2015, 15:48 UTC
Message-ID
<1441900110-4015-1-git-send-email-Karthik.188@gmail.com>

This is part of the series of unifying the code used by "git tag -l, git branch -l, git for-each-ref".

The previous version can be found here (version 16): article.gmane.org/gmane.comp.version-control.git/277394

Changes in this version:
* The arguments of the %(align) atom are interchangeable.
* Small grammatical changes.
* Small changes in the tests to reflect changes in the align
atom code.
Karthik Nayak (14):
  ref-filter: move `struct atom_value` to ref-filter.c
  ref-filter: introduce ref_formatting_state and ref_formatting_stack
  utf8: add function to align a string into given strbuf
  ref-filter: introduce handler function for each atom
  ref-filter: introduce match_atom_name()
  ref-filter: implement an `align` atom
  ref-filter: add option to filter out tags, branches and remotes
  ref-filter: add support for %(contents:lines=X)
  ref-filter: add support to sort by version
  ref-filter: add option to match literal pattern
  tag.c: use 'ref-filter' data structures
  tag.c: use 'ref-filter' APIs
  tag.c: implement '--format' option
  tag.c: implement '--merged' and '--no-merged' options
 Documentation/git-for-each-ref.txt |  17 +-
 Documentation/git-tag.txt          |  27 ++-
 builtin/for-each-ref.c             |   1 +
 builtin/tag.c                      | 369 ++++++---------------------------
 ref-filter.c                       | 412 ++++++++++++++++++++++++++++++++-----
 ref-filter.h                       |  25 ++-
 refs.c                             |   9 +
 refs.h                             |   1 +
 t/t6302-for-each-ref-filter.sh     | 174 ++++++++++++++++
 t/t7004-tag.sh                     |  47 ++++-
 utf8.c                             |  21 ++
 utf8.h                             |  15 ++
 12 files changed, 742 insertions(+), 376 deletions(-)
diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
index c5154bb..16b4ac5 100644
--- a/Documentation/git-for-each-ref.txt
+++ b/Documentation/git-for-each-ref.txt
@@ -128,14 +128,15 @@ color::
 	are described in `color.branch.*`.
 
 align::
-	Left-, middle-, or right-align the content between %(align:...)
-	and %(end). Followed by `:<width>,<position>`, where the
-	`<position>` is either left, right or middle and `<width>` is
-	the total length of the content with alignment. If the
-	contents length is more than the width then no alignment is
-	performed. If used with '--quote' everything in between
-	%(align:...) and %(end) is quoted, but if nested then only the
-	topmost level performs quoting.
+	Left-, middle-, or right-align the content between
+	%(align:...) and %(end). The "align:" is followed by `<width>`
+	and `<position>` in any order separated by a comma, where the
+	`<position>` is either left, right or middle, default being
+	left and `<width>` is the total length of the content with
+	alignment. If the contents length is more than the width then
+	no alignment is performed. If used with '--quote' everything
+	in between %(align:...) and %(end) is quoted, but if nested
+	then only the topmost level performs quoting.
 
 In addition to the above, for commit and tag objects, the header
 field names (`tree`, `parent`, `object`, `type`, and `tag`) can
diff --git a/builtin/tag.c b/builtin/tag.c
index f55dfda..081fe84 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -42,10 +42,11 @@ static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting, con
 		filter->lines = 0;
 
 	if (!format) {
-		if (filter->lines)
-			format = to_free = xstrfmt("%%(align:15,left)%%(refname:short)%%(end) "
-						   "%%(contents:lines=%d)", filter->lines);
-		else
+		if (filter->lines) {
+			format = xstrfmt("%s %%(contents:lines=%d)",
+					 "%(align:15)%%(refname:short)%%(end)", filter->lines);
+			to_free = format;
+		} else
 			format = "%(refname:short)";
 	}
 
diff --git a/ref-filter.c b/ref-filter.c
index e3024d3..59716db 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -274,7 +274,7 @@ static int match_atom_name(const char *name, const char *atom_name, const char *
 	}
 	if (body[0] != ':')
 		return 0; /* "atom_namefoo" is not "atom_name" or "atom_name:..." */
-	*val = body + 1; /* "atomname:val" */
+	*val = body + 1; /* "atom_name:val" */
 	return 1;
 }
 
@@ -884,43 +884,40 @@ static void populate_value(struct ref_array_item *ref)
 			continue;
 		} else if (match_atom_name(name, "align", &valp)) {
 			struct align *align = &v->u.align;
-			struct strbuf **s;
+			struct strbuf **s, **to_free;
+			int width = -1;
 
 			if (!valp)
-				die(_("expected format: %%(align:<width>, <position>)"));
+				die(_("expected format: %%(align:<width>,<position>)"));
 
 			/*
 			 * TODO: Implement a function similar to strbuf_split_str()
-			 * which would strip the terminator at the end.
+			 * which would omit the separator from the end of each value.
 			 */
-			s = strbuf_split_str(valp, ',', 0);
-
-			/* If the position is given trim the ',' from the first strbuf */
-			if (s[1])
-				strbuf_setlen(s[0], s[0]->len - 1);
-			if (s[2])
-				die(_("align:<width>,<position> followed by garbage: %s"), s[2]->buf);
-
-			if (strtoul_ui(s[0]->buf, 10, &align->width))
-				die(_("positive width expected align:%s"), s[0]->buf);
-
-			/*
-			 * TODO: Implement a more general check, so that the values
-			 * do not always have to be in a specific order.
-			 */
-			if (!s[1])
-				align->position = ALIGN_LEFT;
-			else if (!strcmp(s[1]->buf, "left"))
-				align->position = ALIGN_LEFT;
-			else if (!strcmp(s[1]->buf, "right"))
-				align->position = ALIGN_RIGHT;
-			else if (!strcmp(s[1]->buf, "middle"))
-				align->position = ALIGN_MIDDLE;
-			else
-				die(_("improper format entered align:%s"), s[1]->buf);
-
-			strbuf_list_free(s);
+			s = to_free = strbuf_split_str(valp, ',', 0);
+
+			align->position = ALIGN_LEFT;
+
+			while (*s) {
+				if (s[1])
+					strbuf_setlen(s[0], s[0]->len - 1);
+				if (!strtoul_ui(s[0]->buf, 10, (unsigned int *)&width))
+					;
+				else if (!strcmp(s[0]->buf, "left"))
+					align->position = ALIGN_LEFT;
+				else if (!strcmp(s[0]->buf, "right"))
+					align->position = ALIGN_RIGHT;
+				else if (!strcmp(s[0]->buf, "middle"))
+					align->position = ALIGN_MIDDLE;
+				else
+					die(_("improper format entered align:%s"), s[0]->buf);
+				s++;
+			}
 
+			if (width < 0)
+				die(_("positive width expected with the %%(align) atom"));
+			align->width = width;
+			strbuf_list_free(to_free);
 			v->handler = align_atom_handler;
 			continue;
 		} else if (!strcmp(name, "end")) {
diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh
index 4bc1055..fe4796c 100755
--- a/t/t6302-for-each-ref-filter.sh
+++ b/t/t6302-for-each-ref-filter.sh
@@ -85,7 +85,7 @@ test_expect_success '%(color) must fail' '
 	test_must_fail git for-each-ref --format="%(color)%(refname)"
 '
 
-test_expect_success 'left alignment' '
+test_expect_success 'left alignment is default' '
 	cat >expect <<-\EOF &&
 	refname is refs/heads/master  |refs/heads/master
 	refname is refs/heads/side    |refs/heads/side
@@ -97,7 +97,7 @@ test_expect_success 'left alignment' '
 	refname is refs/tags/three    |refs/tags/three
 	refname is refs/tags/two      |refs/tags/two
 	EOF
-	git for-each-ref --format="%(align:30,left)refname is %(refname)%(end)|%(refname)" >actual &&
+	git for-each-ref --format="%(align:30)refname is %(refname)%(end)|%(refname)" >actual &&
 	test_cmp expect actual
 '
 
@@ -113,7 +113,7 @@ test_expect_success 'middle alignment' '
 	|  refname is refs/tags/three  |refs/tags/three
 	|   refname is refs/tags/two   |refs/tags/two
 	EOF
-	git for-each-ref --format="|%(align:30,middle)refname is %(refname)%(end)|%(refname)" >actual &&
+	git for-each-ref --format="|%(align:middle,30)refname is %(refname)%(end)|%(refname)" >actual &&
 	test_cmp expect actual
 '
 
@@ -137,17 +137,17 @@ test_expect_success 'right alignment' '
 
 test_expect_success 'alignment with format quote' "
 	cat >expect <<-\EOF &&
-	|'       master| A U Thor       '|
-	|'        side| A U Thor        '|
-	|'      odd/spot| A U Thor      '|
-	|'         double-tag|          '|
-	|'        four| A U Thor        '|
-	|'        one| A U Thor         '|
-	|'         signed-tag|          '|
-	|'       three| A U Thor        '|
-	|'        two| A U Thor         '|
+	|'      '\''master| A U Thor'\''      '|
+	|'       '\''side| A U Thor'\''       '|
+	|'     '\''odd/spot| A U Thor'\''     '|
+	|'        '\''double-tag| '\''        '|
+	|'       '\''four| A U Thor'\''       '|
+	|'       '\''one| A U Thor'\''        '|
+	|'        '\''signed-tag| '\''        '|
+	|'      '\''three| A U Thor'\''       '|
+	|'       '\''two| A U Thor'\''        '|
 	EOF
-	git for-each-ref --shell --format='|%(align:30,middle)%(refname:short)| %(authorname)%(end)|' >actual &&
+	git for-each-ref --shell --format=\"|%(align:30,middle)'%(refname:short)| %(authorname)'%(end)|\" >actual &&
 	test_cmp expect actual
 "
 
-- 
2.5.1
Next: Karthik Nayak
Message 1 of 56 in “port tag.c to use ref-filter APIs”
  1. 00/14 port tag.c to use ref-filter APIsKarthik Nayak, Sep 10, 2015
  2. 01/14 ref-filter: move `struct atom_value` to ref-filter.cKarthik Nayak, Sep 10, 2015
  3. 02/14 ref-filter: introduce ref_formatting_state and ref_formatting_stackKarthik Nayak, Sep 10, 2015
  4. 03/14 utf8: add function to align a string into given strbufKarthik Nayak, Sep 10, 2015
  5. 04/14 ref-filter: introduce handler function for each atomKarthik Nayak, Sep 10, 2015
  6. 05/14 ref-filter: introduce match_atom_name()Karthik Nayak, Sep 10, 2015
  7. Matthieu MoySep 10, 2015
  8. Junio C HamanoSep 10, 2015
  9. Matthieu MoySep 10, 2015
  10. Junio C HamanoSep 10, 2015
  11. Matthieu MoySep 10, 2015
  12. Junio C HamanoSep 10, 2015
  13. Karthik NayakSep 10, 2015
  14. Junio C HamanoSep 10, 2015
  15. Karthik NayakSep 10, 2015
  16. Junio C HamanoSep 10, 2015
  17. Karthik NayakSep 10, 2015
  18. 05/14 ref-filter: introduce match_atom_name()Karthik Nayak, Sep 11, 2015
  19. 06/14 ref-filter: implement an `align` atomKarthik Nayak, Sep 11, 2015
  20. 06/14 ref-filter: implement an `align` atomKarthik Nayak, Sep 10, 2015
  21. Matthieu MoySep 10, 2015
  22. Junio C HamanoSep 10, 2015
  23. 06/14 ref-filter: implement an `align` atomKarthik Nayak, Sep 11, 2015
  24. 07/14 ref-filter: add option to filter out tags, branches and remotesKarthik Nayak, Sep 10, 2015
  25. 08/14 ref-filter: add support for %(contents:lines=X)Karthik Nayak, Sep 10, 2015
  26. Junio C HamanoSep 10, 2015
  27. Karthik NayakSep 10, 2015
  28. 08/14 ref-filter: add support for %(contents:lines=X)Karthik Nayak, Sep 11, 2015
  29. 09/14 ref-filter: add support to sort by versionKarthik Nayak, Sep 10, 2015
  30. 10/14 ref-filter: add option to match literal patternKarthik Nayak, Sep 10, 2015
  31. 11/14 tag.c: use 'ref-filter' data structuresKarthik Nayak, Sep 10, 2015
  32. 12/14 tag.c: use 'ref-filter' APIsKarthik Nayak, Sep 10, 2015
  33. 12/14 tag.c: use 'ref-filter' APIsKarthik Nayak, Sep 11, 2015
  34. 13/14 tag.c: implement '--format' optionKarthik Nayak, Sep 10, 2015
  35. Junio C HamanoSep 10, 2015
  36. Karthik NayakSep 10, 2015
  37. 13/14 tag.c: implement '--format' optionKarthik Nayak, Sep 11, 2015
  38. 14/14 tag.c: implement '--merged' and '--no-merged' optionsKarthik Nayak, Sep 10, 2015
  39. John KeepingSep 17, 2015
  40. Junio C HamanoSep 17, 2015
  41. Matthieu MoySep 18, 2015
  42. John KeepingSep 18, 2015
  43. Matthieu MoySep 18, 2015
  44. Karthik NayakSep 18, 2015
  45. Matthieu MoySep 18, 2015
  46. Karthik NayakSep 18, 2015
  47. Matthieu MoySep 18, 2015
  48. Karthik NayakSep 18, 2015
  49. Matthieu MoySep 18, 2015
  50. Matthieu MoySep 10, 2015
  51. Karthik NayakSep 11, 2015
  52. Eric SunshineSep 11, 2015
  53. Junio C HamanoSep 11, 2015
  54. Karthik NayakSep 11, 2015
  55. Matthieu MoySep 12, 2015
  56. Karthik NayakSep 13, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.