{"thread":{"id":"55874","subject":"[PATCH v2] branch: prioritize upstream in -v","startedAt":"2021-06-07T18:50:48Z","lastAt":"2021-06-07T18:50:48Z","messageCount":1,"participants":["Felipe Contreras"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"426647","messageId":"20210607185043.893205-1-felipe.contreras@gmail.com","threadId":"55874","inReplyTo":null,"subject":"[PATCH v2] branch: prioritize upstream in -v","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2021-06-07T18:50:43Z","receivedAt":"2021-06-07T18:50:48Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The two important pieces of information relevant to -v and -vv are the\nupstream branch, and tracking status (ahead/behind).\n\nCurrently we give priority to the tracking stats (shown with -v) and\ndemote the upstream branch name (shown only with -vv).\n\nHowever, showing \"[ahead 10]\" is not useful to most users, since they\nwill wonder: ahead of what?.\n\nA lot of people set their upstream to the place they push to, not where\nthey base their branch on. In fact, many guides suggest the following to\nset the upstream branch:\n\n  git push --set-upstream github pull-request\n\nEven more, when pushing a fresh branch git itself recommends that:\n\n  % git clone $url .\n  % git checkout -b fix\n  ...\n  % git push\n\n  fatal: The current branch fix has no upstream branch.\n  To push the current branch and set the remote as upstream, use\n\n      git push --set-upstream origin fix\n\nTherefore for many workflows `git branch -v` is not very useful.\n\nInevitably many users will need to know what @{upstream} is.\n\nSo let's make `git branch -v` output what is most useful:\n\n  [myrepo/mybranch]\n\nBefore:\n\n  * mybranch b2489a3735 [ahead 1] Hot fix\n\nAfter:\n\n  * mybranch b2489a3735 [myrepo/mybranch] Hot fix\n\nAn additional benefit is that `git branch -v` is faster: from 2 to 40\ntimes (depending on the number of stale branches).\n\n`git branch -vv` is unaffected.\n\nSuggestions-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n\nSince v1 I updated the title of the commit, and also the entire commit\nmessage prompted by suggestions from Ævar.\n\nIn particupar I added the example git itself shows by default when\npushing a branch with no upstream:\n\n    git push --set-upstream origin fix\n\nThis _obviously_ suggests people have configured upstream branches other\nthan origin/master.\n\nI also updated the documentation, again, as Ævar suggested.\n\nAnd I also left alone the workdir stuff. I think if we are going to show\nupstream branches with -v, it makes sense to show workdirs too. However,\nsince this patch received more pushback than I expected, I decided to\nminimize the changes.\n\nRange-diff against v1:\n1:  ade2eb0aba ! 1:  f309c75ea4 branch: make -v useful\n    @@ Metadata\n     Author: Felipe Contreras <felipe.contreras@gmail.com>\n     \n      ## Commit message ##\n    -    branch: make -v useful\n    +    branch: prioritize upstream in -v\n     \n    -    Currently `git branch -v` shows something like \"[ahead 10]\", but ahead\n    -    of what?\n    +    The two important pieces of information relevant to -v and -vv are the\n    +    upstream branch, and tracking status (ahead/behind).\n     \n    -    We git experts know ahead of what, but not what that what is set to. Just\n    -    like \"[@{upstream}: ahead 10]\" would not be particularly useful to\n    -    anyone that doesn't know, or remembers, what @{upstream} is set to.\n    +    Currently we give priority to the tracking stats (shown with -v) and\n    +    demote the upstream branch name (shown only with -vv).\n     \n    -    On the other hand \"[master: ahead 10]\" is perfectly clear to anyone.\n    +    However, showing \"[ahead 10]\" is not useful to most users, since they\n    +    will wonder: ahead of what?.\n     \n    -    This confusion only gets worse when you see \"[ahead 10, behind 100]\". Is\n    -    it master? Is it next? Is it\n    -    john/experimental-feature-i-based-my-branch-on?\n    +    A lot of people set their upstream to the place they push to, not where\n    +    they base their branch on. In fact, many guides suggest the following to\n    +    set the upstream branch:\n     \n    -    Inevitably most users will need to know what @{upstream} is.\n    +      git push --set-upstream github pull-request\n    +\n    +    Even more, when pushing a fresh branch git itself recommends that:\n    +\n    +      % git clone $url .\n    +      % git checkout -b fix\n    +      ...\n    +      % git push\n    +\n    +      fatal: The current branch fix has no upstream branch.\n    +      To push the current branch and set the remote as upstream, use\n    +\n    +          git push --set-upstream origin fix\n    +\n    +    Therefore for many workflows `git branch -v` is not very useful.\n    +\n    +    Inevitably many users will need to know what @{upstream} is.\n     \n         So let's make `git branch -v` output what is most useful:\n     \n    -      [master]\n    +      [myrepo/mybranch]\n     \n         Before:\n     \n    -      * fc/branch/sane-colors b2489a3735 [ahead 1] branch: make -v useful\n    +      * mybranch b2489a3735 [ahead 1] Hot fix\n     \n         After:\n     \n    -      * fc/branch/sane-colors b2489a3735 [master] branch: make -v useful\n    +      * mybranch b2489a3735 [myrepo/mybranch] Hot fix\n     \n    -    An additional benefit is that `git branch -v` is slightly faster: 30ms\n    -    vs. 60ms on my system.\n    +    An additional benefit is that `git branch -v` is faster: from 2 to 40\n    +    times (depending on the number of stale branches).\n     \n         `git branch -vv` is unaffected.\n     \n    +    Suggestions-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n         Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n     \n    + ## Documentation/git-branch.txt ##\n    +@@ Documentation/git-branch.txt: This option is only applicable in non-verbose mode.\n    + --verbose::\n    + \tWhen in list mode,\n    + \tshow sha1 and commit subject line for each head, along with\n    +-\trelationship to upstream branch (if any). If given twice, print\n    +-\tthe path of the linked worktree (if any) and the name of the upstream\n    ++\tthe upstream branch (if any). If given twice, print\n    ++\tthe path of the linked worktree (if any) and the relationship to the upstream\n    + \tbranch, as well (see also `git remote show <remote>`).  Note that the\n    + \tcurrent worktree's HEAD will not have its path printed (it will always\n    + \tbe your current directory).\n    +@@ Documentation/git-branch.txt: This option is only applicable in non-verbose mode.\n    + \t`branch.<name>.merge` configuration entries to mark the\n    + \tstart-point branch as \"upstream\" from the new branch. This\n    + \tconfiguration will tell git to show the relationship between the\n    +-\ttwo branches in `git status` and `git branch -v`. Furthermore,\n    ++\ttwo branches in `git status` and `git branch -vv`. Furthermore,\n    + \tit directs `git pull` without arguments to pull from the\n    + \tupstream when the new branch is checked out.\n    + +\n    +\n      ## builtin/branch.c ##\n     @@ builtin/branch.c: static char *build_format(struct ref_filter *filter, int maxwidth, const char *r\n    - \t\tstrbuf_addstr(&local, branch_get_color(BRANCH_COLOR_RESET));\n    - \t\tstrbuf_addf(&local, \" %s \", obname.buf);\n    - \n    -+\t\tstrbuf_addf(&local, \"%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)\",\n    -+\t\t\t    branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));\n    - \t\tif (filter->verbose > 1)\n    --\t\t{\n    --\t\t\tstrbuf_addf(&local, \"%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)\",\n    --\t\t\t\t    branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));\n    - \t\t\tstrbuf_addf(&local, \"%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s%%(if)%%(upstream:track)\"\n    - \t\t\t\t    \"%%(then): %%(upstream:track,nobracket)%%(end)] %%(end)%%(contents:subject)\",\n      \t\t\t\t    branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));\n    --\t\t}\n    + \t\t}\n      \t\telse\n     -\t\t\tstrbuf_addf(&local, \"%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)\");\n     +\t\t\tstrbuf_addf(&local, \"%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s] %%(end)%%(contents:subject)\",\n\n Documentation/git-branch.txt |  6 +++---\n builtin/branch.c             |  3 ++-\n t/t3201-branch-contains.sh   |  2 +-\n t/t6040-tracking-info.sh     | 12 ++++++------\n 4 files changed, 12 insertions(+), 11 deletions(-)\n\ndiff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt\nindex 94dc9a54f2..ebf5d69b68 100644\n--- a/Documentation/git-branch.txt\n+++ b/Documentation/git-branch.txt\n@@ -183,8 +183,8 @@ This option is only applicable in non-verbose mode.\n --verbose::\n \tWhen in list mode,\n \tshow sha1 and commit subject line for each head, along with\n-\trelationship to upstream branch (if any). If given twice, print\n-\tthe path of the linked worktree (if any) and the name of the upstream\n+\tthe upstream branch (if any). If given twice, print\n+\tthe path of the linked worktree (if any) and the relationship to the upstream\n \tbranch, as well (see also `git remote show <remote>`).  Note that the\n \tcurrent worktree's HEAD will not have its path printed (it will always\n \tbe your current directory).\n@@ -210,7 +210,7 @@ This option is only applicable in non-verbose mode.\n \t`branch.<name>.merge` configuration entries to mark the\n \tstart-point branch as \"upstream\" from the new branch. This\n \tconfiguration will tell git to show the relationship between the\n-\ttwo branches in `git status` and `git branch -v`. Furthermore,\n+\ttwo branches in `git status` and `git branch -vv`. Furthermore,\n \tit directs `git pull` without arguments to pull from the\n \tupstream when the new branch is checked out.\n +\ndiff --git a/builtin/branch.c b/builtin/branch.c\nindex b23b1d1752..ed3d0946a7 100644\n--- a/builtin/branch.c\n+++ b/builtin/branch.c\n@@ -384,7 +384,8 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r\n \t\t\t\t    branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));\n \t\t}\n \t\telse\n-\t\t\tstrbuf_addf(&local, \"%%(if)%%(upstream:track)%%(then)%%(upstream:track) %%(end)%%(contents:subject)\");\n+\t\t\tstrbuf_addf(&local, \"%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s] %%(end)%%(contents:subject)\",\n+\t\t\t\t    branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));\n \n \t\tstrbuf_addf(&remote, \"%%(align:%d,left)%s%%(refname:lstrip=2)%%(end)%s\"\n \t\t\t    \"%%(if)%%(symref)%%(then) -> %%(symref:short)\"\ndiff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh\nindex 349a810cee..53e2d65e67 100755\n--- a/t/t3201-branch-contains.sh\n+++ b/t/t3201-branch-contains.sh\n@@ -261,7 +261,7 @@ test_expect_success 'branch --merged with --verbose' '\n \tgit branch --verbose --merged topic >actual &&\n \tcat >expect <<-EOF &&\n \t  main  $(git rev-parse --short main) second on main\n-\t* topic $(git rev-parse --short topic ) [ahead 1] foo\n+\t* topic $(git rev-parse --short topic ) [main] foo\n \t  zzz   $(git rev-parse --short zzz   ) second on main\n \tEOF\n \ttest_cmp expect actual\ndiff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh\nindex a313849406..30f80ad61b 100755\n--- a/t/t6040-tracking-info.sh\n+++ b/t/t6040-tracking-info.sh\n@@ -43,12 +43,12 @@ test_expect_success setup '\n \n t6040_script='s/^..\\(b.\\) *[0-9a-f]* \\(.*\\)$/\\1 \\2/p'\n cat >expect <<\\EOF\n-b1 [ahead 1, behind 1] d\n-b2 [ahead 1, behind 1] d\n-b3 [behind 1] b\n-b4 [ahead 2] f\n-b5 [gone] g\n-b6 c\n+b1 [origin/main] d\n+b2 [origin/main] d\n+b3 [origin/main] b\n+b4 [origin/main] f\n+b5 [brokenbase] g\n+b6 [origin/main] c\n EOF\n \n test_expect_success 'branch -v' '\n-- \n2.31.1.2.g0532ba4bf6\n\n"}]}