Karthik Nayak <karthik.188@xxxxxxxxx> writes: > 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 get_format() which gets the format required for printing of > refs. Make amendments to print_ref_list() to reflect these changes. Is it get_format() still? > > Change calc_maxwidth() to also account for the length of HEAD ref, by > calling ref-filter:get_head_discription(). > > Mentored-by: Christian Couder <christian.couder@xxxxxxxxx> > Mentored-by: Matthieu Moy <matthieu.moy@xxxxxxxxxxxxxxx> > Signed-off-by: Karthik Nayak <karthik.188@xxxxxxxxx> > --- > builtin/branch.c | 261 ++++++++++++----------------------------------- > t/t6040-tracking-info.sh | 2 +- > 2 files changed, 66 insertions(+), 197 deletions(-) > > diff --git a/builtin/branch.c b/builtin/branch.c > index 67ef9f1..4d8b570 100644 > --- a/builtin/branch.c > +++ b/builtin/branch.c > @@ -35,12 +35,12 @@ static unsigned char head_sha1[20]; > > static int branch_use_color = -1; > static char branch_colors[][COLOR_MAXLEN] = { > - GIT_COLOR_RESET, > - GIT_COLOR_NORMAL, /* PLAIN */ > - GIT_COLOR_RED, /* REMOTE */ > - GIT_COLOR_NORMAL, /* LOCAL */ > - GIT_COLOR_GREEN, /* CURRENT */ > - GIT_COLOR_BLUE, /* UPSTREAM */ > + "%(color:reset)", > + "%(color:reset)", /* PLAIN */ > + "%(color:red)", /* REMOTE */ > + "%(color:reset)", /* LOCAL */ > + "%(color:green)", /* CURRENT */ > + "%(color:blue)", /* UPSTREAM */ > }; > enum color_branch { > BRANCH_COLOR_RESET = 0, > @@ -271,192 +271,6 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, > return(ret); > } > > -static void fill_tracking_info(struct strbuf *stat, const char *branch_name, > - int show_upstream_ref) > -{ > - int ours, theirs; > - char *ref = NULL; > - struct branch *branch = branch_get(branch_name); > - const char *upstream; > - struct strbuf fancy = STRBUF_INIT; > - int upstream_is_gone = 0; > - int added_decoration = 1; > - > - if (stat_tracking_info(branch, &ours, &theirs, &upstream) < 0) { > - if (!upstream) > - return; > - upstream_is_gone = 1; > - } > - > - if (show_upstream_ref) { > - ref = shorten_unambiguous_ref(upstream, 0); > - if (want_color(branch_use_color)) > - strbuf_addf(&fancy, "%s%s%s", > - branch_get_color(BRANCH_COLOR_UPSTREAM), > - ref, branch_get_color(BRANCH_COLOR_RESET)); > - else > - strbuf_addstr(&fancy, ref); > - } > - > - if (upstream_is_gone) { > - if (show_upstream_ref) > - strbuf_addf(stat, _("[%s: gone]"), fancy.buf); > - else > - added_decoration = 0; > - } else if (!ours && !theirs) { > - if (show_upstream_ref) > - strbuf_addf(stat, _("[%s]"), fancy.buf); > - else > - added_decoration = 0; > - } else if (!ours) { > - if (show_upstream_ref) > - strbuf_addf(stat, _("[%s: behind %d]"), fancy.buf, theirs); > - else > - strbuf_addf(stat, _("[behind %d]"), theirs); > - > - } else if (!theirs) { > - if (show_upstream_ref) > - strbuf_addf(stat, _("[%s: ahead %d]"), fancy.buf, ours); > - else > - strbuf_addf(stat, _("[ahead %d]"), ours); > - } else { > - if (show_upstream_ref) > - strbuf_addf(stat, _("[%s: ahead %d, behind %d]"), > - fancy.buf, ours, theirs); > - else > - strbuf_addf(stat, _("[ahead %d, behind %d]"), > - ours, theirs); > - } > - strbuf_release(&fancy); > - if (added_decoration) > - strbuf_addch(stat, ' '); > - free(ref); > -} > - > -static void add_verbose_info(struct strbuf *out, struct ref_array_item *item, > - struct ref_filter *filter, const char *refname) > -{ > - struct strbuf subject = STRBUF_INIT, stat = STRBUF_INIT; > - const char *sub = _(" **** invalid ref ****"); > - struct commit *commit = item->commit; > - > - if (!parse_commit(commit)) { > - pp_commit_easy(CMIT_FMT_ONELINE, commit, &subject); > - sub = subject.buf; > - } > - > - if (item->kind == FILTER_REFS_BRANCHES) > - fill_tracking_info(&stat, refname, filter->verbose > 1); > - > - strbuf_addf(out, " %s %s%s", > - find_unique_abbrev(item->commit->object.sha1, filter->abbrev), > - stat.buf, sub); > - strbuf_release(&stat); > - strbuf_release(&subject); > -} > - > -/* > - * This is duplicated in ref-filter.c, will be removed when we adopt > - * ref-filter's printing APIs. > - */ > -static char *get_head_description(void) > -{ > - struct strbuf desc = STRBUF_INIT; > - struct wt_status_state state; > - memset(&state, 0, sizeof(state)); > - wt_status_get_state(&state, 1); > - if (state.rebase_in_progress || > - state.rebase_interactive_in_progress) > - strbuf_addf(&desc, _("(no branch, rebasing %s)"), > - state.branch); > - else if (state.bisect_in_progress) > - strbuf_addf(&desc, _("(no branch, bisect started on %s)"), > - state.branch); > - else if (state.detached_from) { > - /* TRANSLATORS: make sure these match _("HEAD detached at ") > - and _("HEAD detached from ") in wt-status.c */ > - if (state.detached_at) > - strbuf_addf(&desc, _("(HEAD detached at %s)"), > - state.detached_from); > - else > - strbuf_addf(&desc, _("(HEAD detached from %s)"), > - state.detached_from); > - } > - else > - strbuf_addstr(&desc, _("(no branch)")); > - free(state.branch); > - free(state.onto); > - free(state.detached_from); > - return strbuf_detach(&desc, NULL); > -} > - > -static void format_and_print_ref_item(struct ref_array_item *item, int maxwidth, > - struct ref_filter *filter, const char *remote_prefix) > -{ > - char c; > - int current = 0; > - int color; > - struct strbuf out = STRBUF_INIT, name = STRBUF_INIT; > - const char *prefix = ""; > - const char *desc = item->refname; > - char *to_free = NULL; > - > - switch (item->kind) { > - case FILTER_REFS_BRANCHES: > - skip_prefix(desc, "refs/heads/", &desc); > - if (!filter->detached && !strcmp(desc, head)) > - current = 1; > - else > - color = BRANCH_COLOR_LOCAL; > - break; > - case FILTER_REFS_REMOTES: > - skip_prefix(desc, "refs/remotes/", &desc); > - color = BRANCH_COLOR_REMOTE; > - prefix = remote_prefix; > - break; > - case FILTER_REFS_DETACHED_HEAD: > - desc = to_free = get_head_description(); > - current = 1; > - break; > - default: > - color = BRANCH_COLOR_PLAIN; > - break; > - } > - > - c = ' '; > - if (current) { > - c = '*'; > - color = BRANCH_COLOR_CURRENT; > - } > - > - strbuf_addf(&name, "%s%s", prefix, desc); > - if (filter->verbose) { > - int utf8_compensation = strlen(name.buf) - utf8_strwidth(name.buf); > - strbuf_addf(&out, "%c %s%-*s%s", c, branch_get_color(color), > - maxwidth + utf8_compensation, name.buf, > - branch_get_color(BRANCH_COLOR_RESET)); > - } else > - strbuf_addf(&out, "%c %s%s%s", c, branch_get_color(color), > - name.buf, branch_get_color(BRANCH_COLOR_RESET)); > - > - if (item->symref) { > - skip_prefix(item->symref, "refs/remotes/", &desc); > - strbuf_addf(&out, " -> %s", desc); > - } > - else if (filter->verbose) > - /* " f7c0c00 [ahead 58, behind 197] vcs-svn: drop obj_pool.h" */ > - add_verbose_info(&out, item, filter, desc); > - if (column_active(colopts)) { > - assert(!filter->verbose && "--column and --verbose are incompatible"); > - string_list_append(&output, out.buf); > - } else { > - printf("%s\n", out.buf); > - } > - strbuf_release(&name); > - strbuf_release(&out); > - free(to_free); > -} > - > static int calc_maxwidth(struct ref_array *refs, int remote_bonus) > { > int i, max = 0; > @@ -467,7 +281,10 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus) > > skip_prefix(it->refname, "refs/heads/", &desc); > skip_prefix(it->refname, "refs/remotes/", &desc); > - w = utf8_strwidth(desc); > + if (it->kind == FILTER_REFS_DETACHED_HEAD) > + w = strlen(get_head_description()); > + else > + w = utf8_strwidth(desc); > > if (it->kind == FILTER_REFS_REMOTES) > w += remote_bonus; > @@ -477,12 +294,51 @@ static int calc_maxwidth(struct ref_array *refs, int remote_bonus) > return max; > } > > +static char *build_format(struct ref_filter *filter, int maxwidth, const char *remote_prefix) > +{ > + struct strbuf fmt = STRBUF_INIT; > + struct strbuf local = STRBUF_INIT; > + struct strbuf remote = STRBUF_INIT; > + > + strbuf_addf(&fmt, "%%(if)%%(HEAD)%%(then)* %s%%(else) %%(end)", branch_get_color(BRANCH_COLOR_CURRENT)); > + > + if (filter->verbose) { > + strbuf_addf(&local, "%%(align:%d,left)%%(refname:short)%%(end)", maxwidth); > + strbuf_addf(&local, "%s", branch_get_color(BRANCH_COLOR_RESET)); > + strbuf_addf(&local, " %%(objectname:short=7) "); > + > + if (filter->verbose > 1) > + strbuf_addf(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)" > + "%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)", > + branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET)); > + else > + strbuf_addf(&local, "%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)"); > + > + strbuf_addf(&remote, "%s%%(align:%d,left)%s%%(refname:short)%%(end)%s%%(if)%%(symref)%%(then) -> %%(symref:short)" > + "%%(else) %%(objectname:short=7) %%(contents:subject)%%(end)", > + branch_get_color(BRANCH_COLOR_REMOTE), maxwidth, > + remote_prefix, branch_get_color(BRANCH_COLOR_RESET)); > + } else { > + strbuf_addf(&local, "%%(refname:short)%s", branch_get_color(BRANCH_COLOR_RESET)); > + strbuf_addf(&remote, "%s%s%%(refname:short)%s%%(if)%%(symref)%%(then) -> %%(symref:short)%%(end)", > + branch_get_color(BRANCH_COLOR_REMOTE), remote_prefix, branch_get_color(BRANCH_COLOR_RESET)); > + } > + > + strbuf_addf(&fmt, "%%(if:notequals=remotes)%%(refname:base)%%(then)%s%%(else)%s%%(end)", local.buf, remote.buf); > + > + strbuf_release(&local); > + strbuf_release(&remote); > + return strbuf_detach(&fmt, NULL); > +} > + > static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting) > { > int i; > struct ref_array array; > int maxwidth = 0; > const char *remote_prefix = ""; > + struct strbuf out = STRBUF_INIT; > + char *format; > > /* > * If we are listing more than just remote branches, > @@ -494,12 +350,14 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin > > memset(&array, 0, sizeof(array)); > > - verify_ref_format("%(refname)%(symref)"); > filter_refs(&array, filter, filter->kind | FILTER_REFS_INCLUDE_BROKEN); > > if (filter->verbose) > maxwidth = calc_maxwidth(&array, strlen(remote_prefix)); > > + format = build_format(filter, maxwidth, remote_prefix); > + verify_ref_format(format); > + > /* > * If no sorting parameter is given then we default to sorting > * by 'refname'. This would give us an alphabetically sorted > @@ -511,10 +369,21 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin > sorting = ref_default_sorting(); > ref_array_sort(sorting, &array); > > - for (i = 0; i < array.nr; i++) > - format_and_print_ref_item(array.items[i], maxwidth, filter, remote_prefix); > + for (i = 0; i < array.nr; i++) { > + format_ref_array_item(array.items[i], format, 0, &out); > + if (column_active(colopts)) { > + assert(!filter->verbose && "--column and --verbose are incompatible"); > + /* format to a string_list to let print_columns() do its job */ > + string_list_append(&output, out.buf); > + } else { > + fwrite(out.buf, 1, out.len, stdout); > + putchar('\n'); > + } > + strbuf_release(&out); > + } > > ref_array_clear(&array); > + free(format); > } > > static void rename_branch(const char *oldname, const char *newname, int force) > diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh > index 3d5c238..97a0765 100755 > --- a/t/t6040-tracking-info.sh > +++ b/t/t6040-tracking-info.sh > @@ -44,7 +44,7 @@ b1 [ahead 1, behind 1] d > b2 [ahead 1, behind 1] d > b3 [behind 1] b > b4 [ahead 2] f > -b5 g > +b5 [gone] g > b6 c > EOF -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html