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

Re: [PATCH 3/3] for-each-ref: introduce %(upstream:track[short])

From
Phil Hord <phil.hord@gmail.com>
Date
Sep 27, 2013, 14:03 UTC
Message-ID
<CABURp0rrMV2Em=acG80KqqByo1nurC5azU5UBWB0L5p3Zcra8A@mail.gmail.com>
In-Reply-To
<1380283828-25420-4-git-send-email-artagnon@gmail.com>

On Fri, Sep 27, 2013 at 8:10 AM, Ramkumar Ramachandra <artagnon@gmail.com> wrote:

Show 9 quoted lines
> Introduce %(upstream:track) to display "[ahead M, behind N]" and
> %(upstream:trackshort) to display "=", ">", "<", or "<>"
> appropriately (inspired by contrib/completion/git-prompt.sh).
>
> Now you can use the following format in for-each-ref:
>
>   %C(green)%(refname:short)%C(reset)%(upstream:trackshort)
>
> to display refs with terse tracking information.
Thanks.  I like this.
>
> Note that :track and :trackshort only work with "upstream", and error
> out when used with anything else.

I think I would like to use %(refname:track) myself, but this does not detract from this change.

Show 33 quoted lines
>
> Signed-off-by: Ramkumar Ramachandra <artagnon@gmail.com>
> ---
>  Documentation/git-for-each-ref.txt |  6 +++++-
>  builtin/for-each-ref.c             | 44 ++++++++++++++++++++++++++++++++++++--
>  2 files changed, 47 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt
> index f1d4e9e..682eaa8 100644
> --- a/Documentation/git-for-each-ref.txt
> +++ b/Documentation/git-for-each-ref.txt
> @@ -93,7 +93,11 @@ objectname::
>  upstream::
>         The name of a local ref which can be considered ``upstream''
>         from the displayed ref. Respects `:short` in the same way as
> -       `refname` above.
> +       `refname` above.  Additionally respects `:track` to show
> +       "[ahead N, behind M]" and `:trackshort` to show the terse
> +       version (like the prompt) ">", "<", "<>", or "=".  Has no
> +       effect if the ref does not have tracking information
> +       associated with it.
>
>  HEAD::
>         Used to indicate the currently checked out branch.  Is '*' if
> diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
> index e54b5d8..10843bb 100644
> --- a/builtin/for-each-ref.c
> +++ b/builtin/for-each-ref.c
> @@ -631,6 +631,7 @@ static void populate_value(struct refinfo *ref)
>         int eaten, i;
>         unsigned long size;
>         const unsigned char *tagged;
> +       int upstream_present = 0;

This flag is out of place. It should be in the same scope as 'branch' since the code which depends on this flag also depends on '!!branch'.

However, I don't think it is even necessary. The only way to reach the places where this flag is tested is when (name="upstream") and (upstream exists). In all other cases, the parser loops before reaching the track/trackshort code or else it doesn't enter it.

Show 55 quoted lines
>
>         ref->value = xcalloc(sizeof(struct atom_value), used_atom_cnt);
>
> @@ -648,6 +649,7 @@ static void populate_value(struct refinfo *ref)
>                 int deref = 0;
>                 const char *refname;
>                 const char *formatp;
> +               struct branch *branch;
>
>                 if (*name == '*') {
>                         deref = 1;
> @@ -659,7 +661,6 @@ static void populate_value(struct refinfo *ref)
>                 else if (!prefixcmp(name, "symref"))
>                         refname = ref->symref ? ref->symref : "";
>                 else if (!prefixcmp(name, "upstream")) {
> -                       struct branch *branch;
>                         /* only local branches may have an upstream */
>                         if (prefixcmp(ref->refname, "refs/heads/"))
>                                 continue;
> @@ -669,6 +670,7 @@ static void populate_value(struct refinfo *ref)
>                             !branch->merge[0]->dst)
>                                 continue;
>                         refname = branch->merge[0]->dst;
> +                       upstream_present = 1;
>                 }
>                 else if (!strcmp(name, "flag")) {
>                         char buf[256], *cp = buf;
> @@ -686,6 +688,7 @@ static void populate_value(struct refinfo *ref)
>                 } else if (!strcmp(name, "HEAD")) {
>                         const char *head;
>                         unsigned char sha1[20];
> +
>                         head = resolve_ref_unsafe("HEAD", sha1, 1, NULL);
>                         if (!strcmp(ref->refname, head))
>                                 v->s = "*";
> @@ -698,11 +701,48 @@ static void populate_value(struct refinfo *ref)
>                 formatp = strchr(name, ':');
>                 /* look for "short" refname format */
>                 if (formatp) {
> +                       int num_ours, num_theirs;
> +
>                         formatp++;
>                         if (!strcmp(formatp, "short"))
>                                 refname = shorten_unambiguous_ref(refname,
>                                                       warn_ambiguous_refs);
> -                       else
> +                       else if (!strcmp(formatp, "track") &&
> +                               !prefixcmp(name, "upstream")) {
> +                               char buf[40];
> +
> +                               if (!upstream_present)
> +                                       continue;
> +                               stat_tracking_info(branch, &num_ours, &num_theirs);
> +                               if (!num_ours && !num_theirs)
> +                                       v->s = "";
Is this the same as 'continue'?
Show 37 quoted lines
> +                               else if (!num_ours) {
> +                                       sprintf(buf, "[behind %d]", num_theirs);
> +                                       v->s = xstrdup(buf);
> +                               } else if (!num_theirs) {
> +                                       sprintf(buf, "[ahead %d]", num_ours);
> +                                       v->s = xstrdup(buf);
> +                               } else {
> +                                       sprintf(buf, "[ahead %d, behind %d]",
> +                                               num_ours, num_theirs);
> +                                       v->s = xstrdup(buf);
> +                               }
> +                               continue;
> +                       } else if (!strcmp(formatp, "trackshort") &&
> +                               !prefixcmp(name, "upstream")) {
> +                               if (!upstream_present)
> +                                       continue;
> +                               stat_tracking_info(branch, &num_ours, &num_theirs);
> +                               if (!num_ours && !num_theirs)
> +                                       v->s = "=";
> +                               else if (!num_ours)
> +                                       v->s = "<";
> +                               else if (!num_theirs)
> +                                       v->s = ">";
> +                               else
> +                                       v->s = "<>";
> +                               continue;
> +                       } else
>                                 die("unknown %.*s format %s",
>                                     (int)(formatp - name), name, formatp);
>                 }
> --
> 1.8.4.478.g55109e3
>
> --
> To unsubscribe from this list: send the line "unsubscribe git" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous: Ramkumar RamachandraNext: Ramkumar Ramachandra
Message 6 of 13 in “Juggling between hot branches”
  1. 0/3 Juggling between hot branchesRamkumar Ramachandra, Sep 27, 2013
  2. 1/3 for-each-ref: introduce %C(...) for colorRamkumar Ramachandra, Sep 27, 2013
  3. Phil HordSep 27, 2013
  4. 2/3 for-each-ref: introduce %(HEAD) asterisk markerRamkumar Ramachandra, Sep 27, 2013
  5. 3/3 for-each-ref: introduce %(upstream:track[short])Ramkumar Ramachandra, Sep 27, 2013
  6. Phil HordSep 27, 2013
  7. Ramkumar RamachandraSep 27, 2013
  8. Johannes SixtSep 27, 2013
  9. Ramkumar RamachandraSep 27, 2013
  10. Jonathan NiederSep 27, 2013
  11. Philip OakleySep 27, 2013
  12. Ramkumar RamachandraSep 27, 2013
  13. Philip OakleySep 27, 2013

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.