The purpose of this series is to make "for-each-ref --format" powerful
enough to display what "branch -v" and "branch -vv" do so that we
could get rid of those display code and use for-each-ref code instead.
The benefits are clear: share more code, branch can also borrow
--sort and --format from for-each-ref, which should satisty users who
are not happy with what -v and -vv provides.
This version has not gotten there yet. I just want to post quick and
dirty changes and try to address some design issues.
Originally I wanted to introduce --pretty with git-log's pretty syntax
to for-each-ref, deprecating --format. But because --format has to be
there forever, we cannot remove its code, and the code change to make
pretty code ready for displaying refs may not be small. So I went with
enhancing --format syntax instead.
This series introduces:
- %(current), which either shows "*" if the ref is pointed by HEAD
or a space. Junio called it %(headness). I don't like that.
I don't like %(current) either but we have to start somewhere.
Name suggestion? %(marker)??
- %(tracking[:upstream]) gives us the exact output that branch -v[v]
does. %(upstream) does not include []. We can't change its
semantics.
- %(color:...) is pretty much the same as %C family in pretty code.
I haven't added code for %(color:foo) == %C(foo) yet. There's a
potential ambiguity here: %C(red) == %Cred or %C(red)??
- %(...:aligned) to do left aligning. I'm not entirely sure about
this. We might be able to share code with %>, %< and %>< from
pretty.c. But we need improvements there too because in
for-each-ref case, we could calculate column width but %< would
require the user to specify the width.
Do people expect fancy layout with for-each-ref (and branch)? If so
we might need to have %(align) or something instead of the simple
left alignment case in %(...:aligned)
- We may need an equivalent of the space following % in pretty
format. If the specifier produces something, then prepend a space,
otherwise produce nothing. Do it like %C( tracking) vs
%C(tracking)??
You can try this after applying the series, which should give you the
about close to 'branch -v'. %(tracking) coloring does not work though.
git for-each-ref --format='%(current) %(color:auto)%(refname:short:aligned)%(color:reset) %%(objectname:short) %(tracking) %(subject)' 'refs/heads/*'
Nguyễn Thái Ngọc Duy (9):
quote.c: make sq_quote_print a slight wrapper of sq_quote_buf
for-each-ref: convert to use *_quote_buf instead of _quote_print
for-each-ref: avoid printing each element directly to stdout
for-each-ref: add %(current) for current branch marker
for-each-ref: add %(tracking[:upstream]) for tracking info
for-each-ref: add %(color:...)
for-each-ref: prepoplulate all atoms before show_ref()
for-each-ref: merge show_ref into show_refs
for-each-ref: support %(...:aligned) for left alignment
branch.h | 11 ++++
builtin/branch.c | 16 ++----
builtin/for-each-ref.c | 146 ++++++++++++++++++++++++++++++++++++++++++-------
quote.c | 61 +++++++++------------
quote.h | 6 +-
5 files changed, 170 insertions(+), 70 deletions(-)
--
1.8.2.83.gc99314b
@@ -454,72 +454,72 @@ int unquote_c_style(struct strbuf *sb, const char *quoted, const char **endp)/* quoting as a string literal for other languages */-voidperl_quote_print(FILE*stream,constchar*src)+voidperl_quote_buf(structstrbuf*sb,constchar*src){constcharsq='\'';constcharbq='\\';charc;-fputc(sq,stream);+strbuf_addch(sb,sq);while((c=*src++)){if(c==sq||c==bq)-fputc(bq,stream);-fputc(c,stream);+strbuf_addch(sb,bq);+strbuf_addch(sb,c);}-fputc(sq,stream);+strbuf_addch(sb,sq);}-voidpython_quote_print(FILE*stream,constchar*src)+voidpython_quote_buf(structstrbuf*sb,constchar*src){constcharsq='\'';constcharbq='\\';constcharnl='\n';charc;-fputc(sq,stream);+strbuf_addch(sb,sq);while((c=*src++)){if(c==nl){-fputc(bq,stream);-fputc('n',stream);+strbuf_addch(sb,bq);+strbuf_addch(sb,'n');continue;}if(c==sq||c==bq)-fputc(bq,stream);-fputc(c,stream);+strbuf_addch(sb,bq);+strbuf_addch(sb,c);}-fputc(sq,stream);+strbuf_addch(sb,sq);}-voidtcl_quote_print(FILE*stream,constchar*src)+voidtcl_quote_buf(structstrbuf*sb,constchar*src){charc;-fputc('"',stream);+strbuf_addch(sb,'"');while((c=*src++)){switch(c){case'[':case']':case'{':case'}':case'$':case'\\':case'"':-fputc('\\',stream);+strbuf_addch(sb,'\\');default:-fputc(c,stream);+strbuf_addch(sb,c);break;case'\f':-fputs("\\f",stream);+strbuf_addstr(sb,"\\f");break;case'\r':-fputs("\\r",stream);+strbuf_addstr(sb,"\\r");break;case'\n':-fputs("\\n",stream);+strbuf_addstr(sb,"\\n");break;case'\t':-fputs("\\t",stream);+strbuf_addstr(sb,"\\t");break;case'\v':-fputs("\\v",stream);+strbuf_addstr(sb,"\\v");break;}}-fputc('"',stream);+strbuf_addch(sb,'"');}
@@ -69,8 +69,8 @@ extern char *quote_path_relative(const char *in, int len,structstrbuf*out,constchar*prefix);/* quoting as a string literal for other languages */-externvoidperl_quote_print(FILE*stream,constchar*src);-externvoidpython_quote_print(FILE*stream,constchar*src);-externvoidtcl_quote_print(FILE*stream,constchar*src);+externvoidperl_quote_buf(structstrbuf*sb,constchar*src);+externvoidpython_quote_buf(structstrbuf*sb,constchar*src);+externvoidtcl_quote_buf(structstrbuf*sb,constchar*src);#endif
By the time show_ref() is called, atom values for all refs are
ready. This can be taken advantage of later.
Signed-off-by: Nguyễn Thái Ngọc Duy <redacted>
---
builtin/for-each-ref.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
The purpose of this series is to make "for-each-ref --format" powerful
enough to display what "branch -v" and "branch -vv" do so that we
could get rid of those display code and use for-each-ref code instead.
Damn, you beat me to it. I just introduced color, and was working on
alignment. See $gmane/224692.
Yes, I think this is the direction we should be taking. Poorly
thought-out stuff like -v and -vv should be deprecated.
This series introduces:
- %(current), which either shows "*" if the ref is pointed by HEAD
or a space. Junio called it %(headness). I don't like that.
I don't like %(current) either but we have to start somewhere.
Name suggestion? %(marker)??
How about %(HEAD)?
- %(tracking[:upstream]) gives us the exact output that branch -v[v]
does. %(upstream) does not include []. We can't change its
semantics.
There's already an atom called "upstream", and "upstream:short" works.
Why not introduce "upstream:diff" for "[ahead x, behind y]" and
"upstream:shortdiff" for "<>" (like in the prompt)?
- %(color:...) is pretty much the same as %C family in pretty code.
I haven't added code for %(color:foo) == %C(foo) yet. There's a
potential ambiguity here: %C(red) == %Cred or %C(red)??
I'd vote for dropping %C<name> altogether and just go with %C(<name>).
Why do we need %(color:<name>) at all?
- %(...:aligned) to do left aligning. I'm not entirely sure about
this. We might be able to share code with %>, %< and %>< from
pretty.c. But we need improvements there too because in
for-each-ref case, we could calculate column width but %< would
require the user to specify the width.
Yeah, I think we should go with the %> and %< you introduced in
pretty.c. Yes, I want to be able to specify width.
Do people expect fancy layout with for-each-ref (and branch)? If so
we might need to have %(align) or something instead of the simple
left alignment case in %(...:aligned)
Why should we deviate from the pretty case? What is different here?
- We may need an equivalent of the space following % in pretty
format. If the specifier produces something, then prepend a space,
otherwise produce nothing. Do it like %C( tracking) vs
%C(tracking)??
Yeah, sounds good.
You can try this after applying the series, which should give you the
about close to 'branch -v'. %(tracking) coloring does not work though.
Why doesn't %(tracking) coloring work?
Nguyễn Thái Ngọc Duy (9):
I'll have a look at this.
Also, I think it'll help to have a --pretty="format:<string>"
equivalent to --format="<string>" so that we can introduce pretty
names like oneline, short, medium, full. We can eventually deprecate
--format for consistency.
No, I intentionally did not make color an atom in $gmane/224692. It
doesn't print any information about the branch, like the other atoms
do: have it augment the final printing.
quoted hunk
/*
@@ -707,6 +711,21 @@ static void populate_value(struct refinfo *ref) v->s = sb.buf; continue; }+ else if (!prefixcmp(name, "color:")) {+ const char *color = name + 6;+ ref->auto_color = 0;+ if (!prefixcmp(color, "red"))+ v->s = GIT_COLOR_RED;+ else if (!prefixcmp(color, "green"))+ v->s = GIT_COLOR_GREEN;+ else if (!prefixcmp(color, "blue"))+ v->s = GIT_COLOR_BLUE;+ else if (!prefixcmp(color, "reset"))+ v->s = GIT_COLOR_RESET;+ else if (!prefixcmp(color, "auto"))+ ref->auto_color = 1;+ continue;+ }
So I can't have %(color:yellow)? :(
Why are you parsing it here when you can use color_parse_name()?
Why?! Why are you denying me the pleasure of using %<, %<|, %>, %>|,
%>>, %>>|, %<>, and %<>| that you invented in pretty? The code is
already there: you just have to hook it up.
From: Felipe Contreras <hidden> Date: 2016-06-15 22:57:19
On Sun, May 19, 2013 at 6:11 AM, Ramkumar Ramachandra
[off-list ref] wrote:
Yes, I think this is the direction we should be taking. Poorly
thought-out stuff like -v and -vv should be deprecated.
Of course not. They are useful and user-friendly.
The only question is what should be the format by default.
Also, I think it'll help to have a --pretty="format:<string>"
equivalent to --format="<string>" so that we can introduce pretty
names like oneline, short, medium, full. We can eventually deprecate
--format for consistency.
I don't see the point of --pretty. I think there should be shortcuts,
something like --hash for the SHA1s only, and --names for the refs
only, or something like that.
--
Felipe Contreras
You just threw the upstream atom (and "upstream:short") out the window :|
Huh? Those don't print the tracking information, do they?
"tracking:upstream" prints the upstream, but other things as well I
suppose.
--
Felipe Contreras
Why?! Why are you denying me the pleasure of using %<, %<|, %>, %>|,
%>>, %>>|, %<>, and %<>| that you invented in pretty? The code is
already there: you just have to hook it up.
Because for-each-ref only understands %(...) not %<|, i.e. % followed
by a (. We need more changes in for-each-ref code to make it accept
%<|, I think. Also %<|(N) needs "N". In case of "branch -v" that
should be calculated automatically, so we need a syntax to say "align
to the left, use the smallest width that fits all". I guess "%<|(*)"?
--
Duy
You just threw the upstream atom (and "upstream:short") out the window :|
Huh? Those don't print the tracking information, do they?
"tracking:upstream" prints the upstream, but other things as well I
suppose.
Exactly. I already explained why %(upstream) can't be used in 00/09.
"tracking" may not be perfect. Somebody might want
"tracking:upstream:short". It does not look quite nice.
--
Duy
Exactly. I already explained why %(upstream) can't be used in 00/09.
"tracking" may not be perfect. Somebody might want
"tracking:upstream:short". It does not look quite nice.
Which is why I suggested keeping upstream, upstream:short, and
introducing upstream:diff and upstream:shortdiff (or :tracking if you
prefer that) in [0/9].
On Sun, May 19, 2013 at 6:11 PM, Ramkumar Ramachandra
[off-list ref] wrote:
Nguyễn Thái Ngọc Duy wrote:
quoted
The purpose of this series is to make "for-each-ref --format" powerful
enough to display what "branch -v" and "branch -vv" do so that we
could get rid of those display code and use for-each-ref code instead.
Damn, you beat me to it. I just introduced color, and was working on
alignment. See $gmane/224692.
Hmm.. I missed that mail (or I wouldn't have worked on this already).
Do you want to take over?
quoted
- %(tracking[:upstream]) gives us the exact output that branch -v[v]
does. %(upstream) does not include []. We can't change its
semantics.
There's already an atom called "upstream", and "upstream:short" works.
Why not introduce "upstream:diff" for "[ahead x, behind y]" and
"upstream:shortdiff" for "<>" (like in the prompt)?
"branch -vv" shows [upstream: ahead x, behind y]. We need a syntax to
cover that too.
quoted
- %(color:...) is pretty much the same as %C family in pretty code.
I haven't added code for %(color:foo) == %C(foo) yet. There's a
potential ambiguity here: %C(red) == %Cred or %C(red)??
I'd vote for dropping %C<name> altogether and just go with %C(<name>).
Why do we need %(color:<name>) at all?
pretty and for-each-ref format seem to be on the opposite: one is
terse, one verbose. Unless you are going to introduce a lot of new
specifiers (and in the worst case, bring all pretty specifiers over,
unify underlying code), I think we should stick with %(xx) convention.
quoted
- %(...:aligned) to do left aligning. I'm not entirely sure about
this. We might be able to share code with %>, %< and %>< from
pretty.c. But we need improvements there too because in
for-each-ref case, we could calculate column width but %< would
require the user to specify the width.
Yeah, I think we should go with the %> and %< you introduced in
pretty.c. Yes, I want to be able to specify width.
I still think we should follow %(...), e.g. %(left:N), %(right:N) as
equivalent of %< and %>...
quoted
Do people expect fancy layout with for-each-ref (and branch)? If so
we might need to have %(align) or something instead of the simple
left alignment case in %(...:aligned)
Why should we deviate from the pretty case? What is different here?
Laziness plays a big factor :) So again, you want to take over? ;)
quoted
- We may need an equivalent of the space following % in pretty
format. If the specifier produces something, then prepend a space,
otherwise produce nothing. Do it like %C( tracking) vs
%C(tracking)??
Yeah, sounds good.
quoted
You can try this after applying the series, which should give you the
about close to 'branch -v'. %(tracking) coloring does not work though.
Why doesn't %(tracking) coloring work?
it uses builtin/branch.c:branch_use_color. Eventually
fill_tracking_info() should be moved to for-each-ref.c and pass
branch_use_color in as an argument. But for now, I just leave it
broken.
--
Duy
On Sun, May 19, 2013 at 6:17 PM, Ramkumar Ramachandra
[off-list ref] wrote:
quoted
[PATCH 3/9] for-each-ref: avoid printing each element directly to stdout
Why did you do this? Atoms are designed to be independent of each
other. I'll keep reading: might find out in a later patch.
Sorry for the lack of explanation in the message. I wanted to discuss
about syntax more than code. As you see later down the series, we'll
need to process an atom for all refs, then output all refs in the end.
We can't do that wihout buffering.
--
Duy
From: Felipe Contreras <hidden> Date: 2016-06-15 22:57:19
On Sun, May 19, 2013 at 6:48 AM, Ramkumar Ramachandra
[off-list ref] wrote:
Duy Nguyen wrote:
quoted
Exactly. I already explained why %(upstream) can't be used in 00/09.
"tracking" may not be perfect. Somebody might want
"tracking:upstream:short". It does not look quite nice.
Which is why I suggested keeping upstream, upstream:short, and
introducing upstream:diff and upstream:shortdiff (or :tracking if you
prefer that) in [0/9].
Yeah, but there won't be any upstream in %(tracking). Besides, if we
manage to get downstream, we could do %(tracking:downstream). I think
%(tracking) and %(short:tracking) make sense.
--
Felipe Contreras
Hmm.. I missed that mail (or I wouldn't have worked on this already).
Do you want to take over?
Oh, we can collaborate on one beautiful series :)
"branch -vv" shows [upstream: ahead x, behind y]. We need a syntax to
cover that too.
Can't we construct that using [%(upstream:short): %(upstream:diff)]?
It's nothing fundamental.
pretty and for-each-ref format seem to be on the opposite: one is
terse, one verbose. Unless you are going to introduce a lot of new
specifiers (and in the worst case, bring all pretty specifiers over,
unify underlying code), I think we should stick with %(xx) convention.
We can stick to using the existing %(...) atoms: there's no need to go
as far as %an versus %aN. The atoms cannot be consistent with
pretty-formats anyway, because pretty-formats has completely different
atoms. For the _new_ stuff like color and alignment, we can be
consistent with pretty-formats, no?
quoted
Why should we deviate from the pretty case? What is different here?
Laziness plays a big factor :) So again, you want to take over? ;)
It's just a matter of modifying the parsing/printing layer, instead of
introducing new atoms in the current parser. Doesn't $gmane/224692
demonstrate that the former can, in fact, be easier?
it uses builtin/branch.c:branch_use_color. Eventually
fill_tracking_info() should be moved to for-each-ref.c and pass
branch_use_color in as an argument. But for now, I just leave it
broken.
Auto-color can come later: it's not that urgent. What's more
important is that we give users the flexibility to set their own
colors now.
Can you give me a pull URL to your series, so we can start
collaborating? Mine's at gh:artagnon/git (branch: hot-branch).
On Sun, May 19, 2013 at 7:08 PM, Ramkumar Ramachandra
[off-list ref] wrote:
quoted
"branch -vv" shows [upstream: ahead x, behind y]. We need a syntax to
cover that too.
Can't we construct that using [%(upstream:short): %(upstream:diff)]?
It's nothing fundamental.
If there is no upstream, [] should not be shown. We don't have
conditional specifiers so [] should be produced by one of the
specifiers. But yes it's nothing fundamental.
quoted
pretty and for-each-ref format seem to be on the opposite: one is
terse, one verbose. Unless you are going to introduce a lot of new
specifiers (and in the worst case, bring all pretty specifiers over,
unify underlying code), I think we should stick with %(xx) convention.
We can stick to using the existing %(...) atoms: there's no need to go
as far as %an versus %aN. The atoms cannot be consistent with
pretty-formats anyway, because pretty-formats has completely different
atoms. For the _new_ stuff like color and alignment, we can be
consistent with pretty-formats, no?
I don't think you can easily borrow parsing code from pretty-formats
(but I may be wrong). Anyway new stuff with new syntax would look
alien in for-each-ref format lines. Either we bring --pretty to
for-each-ref, leaving all for-each-ref atoms behind in --format, or we
should follow %(..) convention if we add new stuff to --format.
quoted
quoted
Why should we deviate from the pretty case? What is different here?
Laziness plays a big factor :) So again, you want to take over? ;)
It's just a matter of modifying the parsing/printing layer, instead of
introducing new atoms in the current parser. Doesn't $gmane/224692
demonstrate that the former can, in fact, be easier?
Yes it looks so.
quoted
it uses builtin/branch.c:branch_use_color. Eventually
fill_tracking_info() should be moved to for-each-ref.c and pass
branch_use_color in as an argument. But for now, I just leave it
broken.
Auto-color can come later: it's not that urgent. What's more
important is that we give users the flexibility to set their own
colors now.
Can you give me a pull URL to your series, so we can start
collaborating? Mine's at gh:artagnon/git (branch: hot-branch).
I don't think you can easily borrow parsing code from pretty-formats
(but I may be wrong). Anyway new stuff with new syntax would look
alien in for-each-ref format lines. Either we bring --pretty to
for-each-ref, leaving all for-each-ref atoms behind in --format, or we
should follow %(..) convention if we add new stuff to --format.
Why so extremist? pretty-formats has %(...), %C(...) as well as %...,
so why shouldn't we? Our format is undocumented, and I doubt anyone
even uses it; we're not breaking anyone's expectations. I'm just
saying that our format can be a little reminiscent of pretty-formats,
nothing more. There's no need to borrow parsing code: we can do it
ourselves, I think. There is no need to go to the other extreme and
throw out the existing --format and start out with a --pretty from
scratch either: the current code isn't so bad that we can't build on
top of it. Sure, we can eventually deprecate --format and move to
--pretty for consistency (but that's a long-term goal).
From: Junio C Hamano <hidden> Date: 2016-06-15 22:57:20
Nguyễn Thái Ngọc Duy [off-list ref] writes:
Originally I wanted to introduce --pretty with git-log's pretty syntax
to for-each-ref, deprecating --format.
If you are going to unify the two mechanisms, I think the "--format"
option of "for-each-ref" needs to become a superset of what the
"--pretty" option of "log/rev-list" can express and shared between
the two. The former has to handle anything that can be at the tip
of a ref, including commits, so it needs to be able to do anything
the latter can.