Skip to content

Commit c56529d

Browse files
KarthikNayakgitster
authored andcommitted
branch: use ref-filter printing APIs
Port branch.c to use ref-filter APIs for printing. This clears out most of the code used in branch.c for printing and replaces them with calls made to the ref-filter library. Introduce build_format() which gets the format required for printing of refs. Make amendments to print_ref_list() to reflect these changes. Change calc_maxwidth() to also account for the length of HEAD ref, by calling ref-filter:get_head_discription(). Also change the test in t6040 to reflect the changes. Before this patch, all cross-prefix symrefs weren't shortened. Since we're using ref-filter APIs, we shorten all symrefs by default. We also allow the user to change the format if needed with the introduction of the '--format' option in the next patch. Mentored-by: Christian Couder <[email protected]> Mentored-by: Matthieu Moy <[email protected]> Signed-off-by: Karthik Nayak <[email protected]>
1 parent 87d273e commit c56529d

File tree

3 files changed

+70
-168
lines changed

3 files changed

+70
-168
lines changed

builtin/branch.c

Lines changed: 68 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,12 @@ static unsigned char head_sha1[20];
3636

3737
static int branch_use_color = -1;
3838
static char branch_colors[][COLOR_MAXLEN] = {
39-
GIT_COLOR_RESET,
40-
GIT_COLOR_NORMAL, /* PLAIN */
41-
GIT_COLOR_RED, /* REMOTE */
42-
GIT_COLOR_NORMAL, /* LOCAL */
43-
GIT_COLOR_GREEN, /* CURRENT */
44-
GIT_COLOR_BLUE, /* UPSTREAM */
39+
"%(color:reset)",
40+
"%(color:reset)", /* PLAIN */
41+
"%(color:red)", /* REMOTE */
42+
"%(color:reset)", /* LOCAL */
43+
"%(color:green)", /* CURRENT */
44+
"%(color:blue)", /* UPSTREAM */
4545
};
4646
enum color_branch {
4747
BRANCH_COLOR_RESET = 0,
@@ -277,162 +277,6 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
277277
return(ret);
278278
}
279279

280-
static void fill_tracking_info(struct strbuf *stat, const char *branch_name,
281-
int show_upstream_ref)
282-
{
283-
int ours, theirs;
284-
char *ref = NULL;
285-
struct branch *branch = branch_get(branch_name);
286-
const char *upstream;
287-
struct strbuf fancy = STRBUF_INIT;
288-
int upstream_is_gone = 0;
289-
int added_decoration = 1;
290-
291-
if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) {
292-
if (!upstream)
293-
return;
294-
upstream_is_gone = 1;
295-
}
296-
297-
if (show_upstream_ref) {
298-
ref = shorten_unambiguous_ref(upstream, 0);
299-
if (want_color(branch_use_color))
300-
strbuf_addf(&fancy, "%s%s%s",
301-
branch_get_color(BRANCH_COLOR_UPSTREAM),
302-
ref, branch_get_color(BRANCH_COLOR_RESET));
303-
else
304-
strbuf_addstr(&fancy, ref);
305-
}
306-
307-
if (upstream_is_gone) {
308-
if (show_upstream_ref)
309-
strbuf_addf(stat, _("[%s: gone]"), fancy.buf);
310-
else
311-
added_decoration = 0;
312-
} else if (!ours && !theirs) {
313-
if (show_upstream_ref)
314-
strbuf_addf(stat, _("[%s]"), fancy.buf);
315-
else
316-
added_decoration = 0;
317-
} else if (!ours) {
318-
if (show_upstream_ref)
319-
strbuf_addf(stat, _("[%s: behind %d]"), fancy.buf, theirs);
320-
else
321-
strbuf_addf(stat, _("[behind %d]"), theirs);
322-
323-
} else if (!theirs) {
324-
if (show_upstream_ref)
325-
strbuf_addf(stat, _("[%s: ahead %d]"), fancy.buf, ours);
326-
else
327-
strbuf_addf(stat, _("[ahead %d]"), ours);
328-
} else {
329-
if (show_upstream_ref)
330-
strbuf_addf(stat, _("[%s: ahead %d, behind %d]"),
331-
fancy.buf, ours, theirs);
332-
else
333-
strbuf_addf(stat, _("[ahead %d, behind %d]"),
334-
ours, theirs);
335-
}
336-
strbuf_release(&fancy);
337-
if (added_decoration)
338-
strbuf_addch(stat, ' ');
339-
free(ref);
340-
}
341-
342-
static void add_verbose_info(struct strbuf *out, struct ref_array_item *item,
343-
struct ref_filter *filter, const char *refname)
344-
{
345-
struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT;
346-
const char *sub = _(" **** invalid ref ****");
347-
struct commit *commit = item->commit;
348-
349-
if (!parse_commit(commit)) {
350-
pp_commit_easy(CMIT_FMT_ONELINE, commit, &subject);
351-
sub = subject.buf;
352-
}
353-
354-
if (item->kind == FILTER_REFS_BRANCHES)
355-
fill_tracking_info(&stat, refname, filter->verbose > 1);
356-
357-
strbuf_addf(out, " %s %s%s",
358-
find_unique_abbrev(item->commit->object.oid.hash, filter->abbrev),
359-
stat.buf, sub);
360-
strbuf_release(&stat);
361-
strbuf_release(&subject);
362-
}
363-
364-
static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth,
365-
struct ref_filter *filter, const char *remote_prefix)
366-
{
367-
char c;
368-
int current = 0;
369-
int color;
370-
struct strbuf out = STRBUF_INIT, name = STRBUF_INIT;
371-
const char *prefix_to_show = "";
372-
const char *prefix_to_skip = NULL;
373-
const char *desc = item->refname;
374-
char *to_free = NULL;
375-
376-
switch (item->kind) {
377-
case FILTER_REFS_BRANCHES:
378-
prefix_to_skip = "refs/heads/";
379-
skip_prefix(desc, prefix_to_skip, &desc);
380-
if (!filter->detached && !strcmp(desc, head))
381-
current = 1;
382-
else
383-
color = BRANCH_COLOR_LOCAL;
384-
break;
385-
case FILTER_REFS_REMOTES:
386-
prefix_to_skip = "refs/remotes/";
387-
skip_prefix(desc, prefix_to_skip, &desc);
388-
color = BRANCH_COLOR_REMOTE;
389-
prefix_to_show = remote_prefix;
390-
break;
391-
case FILTER_REFS_DETACHED_HEAD:
392-
desc = to_free = get_head_description();
393-
current = 1;
394-
break;
395-
default:
396-
color = BRANCH_COLOR_PLAIN;
397-
break;
398-
}
399-
400-
c = ' ';
401-
if (current) {
402-
c = '*';
403-
color = BRANCH_COLOR_CURRENT;
404-
}
405-
406-
strbuf_addf(&name, "%s%s", prefix_to_show, desc);
407-
if (filter->verbose) {
408-
int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf);
409-
strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color),
410-
maxwidth + utf8_compensation, name.buf,
411-
branch_get_color(BRANCH_COLOR_RESET));
412-
} else
413-
strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color),
414-
name.buf, branch_get_color(BRANCH_COLOR_RESET));
415-
416-
if (item->symref) {
417-
const char *symref = item->symref;
418-
if (prefix_to_skip)
419-
skip_prefix(symref, prefix_to_skip, &symref);
420-
strbuf_addf(&out, " -> %s", symref);
421-
}
422-
else if (filter->verbose)
423-
/* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */
424-
add_verbose_info(&out, item, filter, desc);
425-
if (column_active(colopts)) {
426-
assert(!filter->verbose && "--column and --verbose are incompatible");
427-
string_list_append(&output, out.buf);
428-
} else {
429-
printf("%s\n", out.buf);
430-
}
431-
strbuf_release(&name);
432-
strbuf_release(&out);
433-
free(to_free);
434-
}
435-
436280
static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
437281
{
438282
int i, max = 0;
@@ -443,7 +287,12 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
443287

444288
skip_prefix(it->refname, "refs/heads/", &desc);
445289
skip_prefix(it->refname, "refs/remotes/", &desc);
446-
w = utf8_strwidth(desc);
290+
if (it->kind == FILTER_REFS_DETACHED_HEAD) {
291+
char *head_desc = get_head_description();
292+
w = utf8_strwidth(head_desc);
293+
free(head_desc);
294+
} else
295+
w = utf8_strwidth(desc);
447296

448297
if (it->kind == FILTER_REFS_REMOTES)
449298
w += remote_bonus;
@@ -453,12 +302,52 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus)
453302
return max;
454303
}
455304

305+
static char *build_format(struct ref_filter *filter, int maxwidth, const char *remote_prefix)
306+
{
307+
struct strbuf fmt = STRBUF_INIT;
308+
struct strbuf local = STRBUF_INIT;
309+
struct strbuf remote = STRBUF_INIT;
310+
311+
strbuf_addf(&fmt, "%%(if)%%(HEAD)%%(then)* %s%%(else) %%(end)", branch_get_color(BRANCH_COLOR_CURRENT));
312+
313+
if (filter->verbose) {
314+
strbuf_addf(&local, "%%(align:%d,left)%%(refname:strip=2)%%(end)", maxwidth);
315+
strbuf_addf(&local, "%s", branch_get_color(BRANCH_COLOR_RESET));
316+
strbuf_addf(&local, " %%(objectname:short=7) ");
317+
318+
if (filter->verbose > 1)
319+
strbuf_addf(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)"
320+
"%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)",
321+
branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));
322+
else
323+
strbuf_addf(&local, "%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)");
324+
325+
strbuf_addf(&remote, "%s%%(align:%d,left)%s%%(refname:strip=2)%%(end)%s%%(if)%%(symref)%%(then) -> %%(symref:short)"
326+
"%%(else) %%(objectname:short=7) %%(contents:subject)%%(end)",
327+
branch_get_color(BRANCH_COLOR_REMOTE), maxwidth,
328+
remote_prefix, branch_get_color(BRANCH_COLOR_RESET));
329+
} else {
330+
strbuf_addf(&local, "%%(refname:strip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)",
331+
branch_get_color(BRANCH_COLOR_RESET));
332+
strbuf_addf(&remote, "%s%s%%(refname:strip=2)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)",
333+
branch_get_color(BRANCH_COLOR_REMOTE), remote_prefix, branch_get_color(BRANCH_COLOR_RESET));
334+
}
335+
336+
strbuf_addf(&fmt, "%%(if:notequals=remotes)%%(refname:base)%%(then)%s%%(else)%s%%(end)", local.buf, remote.buf);
337+
338+
strbuf_release(&local);
339+
strbuf_release(&remote);
340+
return strbuf_detach(&fmt, NULL);
341+
}
342+
456343
static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting)
457344
{
458345
int i;
459346
struct ref_array array;
460347
int maxwidth = 0;
461348
const char *remote_prefix = "";
349+
struct strbuf out = STRBUF_INIT;
350+
char *format;
462351

463352
/*
464353
* If we are listing more than just remote branches,
@@ -470,12 +359,14 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
470359

471360
memset(&array, 0, sizeof(array));
472361

473-
verify_ref_format("%(refname)%(symref)");
474362
filter_refs(&array, filter, filter->kind | FILTER_REFS_INCLUDE_BROKEN);
475363

476364
if (filter->verbose)
477365
maxwidth = calc_maxwidth(&array, strlen(remote_prefix));
478366

367+
format = build_format(filter, maxwidth, remote_prefix);
368+
verify_ref_format(format);
369+
479370
/*
480371
* If no sorting parameter is given then we default to sorting
481372
* by 'refname'. This would give us an alphabetically sorted
@@ -487,10 +378,21 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
487378
sorting = ref_default_sorting();
488379
ref_array_sort(sorting, &array);
489380

490-
for (i = 0; i < array.nr; i++)
491-
format_and_print_ref_item(array.items[i], maxwidth, filter, remote_prefix);
381+
for (i = 0; i < array.nr; i++) {
382+
format_ref_array_item(array.items[i], format, 0, &out);
383+
if (column_active(colopts)) {
384+
assert(!filter->verbose && "--column and --verbose are incompatible");
385+
/* format to a string_list to let print_columns() do its job */
386+
string_list_append(&output, out.buf);
387+
} else {
388+
fwrite(out.buf, 1, out.len, stdout);
389+
putchar('\n');
390+
}
391+
strbuf_release(&out);
392+
}
492393

493394
ref_array_clear(&array);
395+
free(format);
494396
}
495397

496398
static void rename_branch(const char *oldname, const char *newname, int force)

t/t3203-branch-output.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ test_expect_success 'local-branch symrefs shortened properly' '
189189
git symbolic-ref refs/heads/ref-to-remote refs/remotes/origin/branch-one &&
190190
cat >expect <<-\EOF &&
191191
ref-to-branch -> branch-one
192-
ref-to-remote -> refs/remotes/origin/branch-one
192+
ref-to-remote -> origin/branch-one
193193
EOF
194194
git branch >actual.raw &&
195195
grep ref-to <actual.raw >actual &&

t/t6040-tracking-info.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ b1 [ahead 1, behind 1] d
4444
b2 [ahead 1, behind 1] d
4545
b3 [behind 1] b
4646
b4 [ahead 2] f
47-
b5 g
47+
b5 [gone] g
4848
b6 c
4949
EOF
5050

0 commit comments

Comments
 (0)