diff mbox series

[v2] branch: prioritize upstream in -v

Message ID 20210607185043.893205-1-felipe.contreras@gmail.com (mailing list archive)
State New, archived
Headers show
Series [v2] branch: prioritize upstream in -v | expand

Commit Message

Felipe Contreras June 7, 2021, 6:50 p.m. UTC
The two important pieces of information relevant to -v and -vv are the
upstream branch, and tracking status (ahead/behind).

Currently we give priority to the tracking stats (shown with -v) and
demote the upstream branch name (shown only with -vv).

However, showing "[ahead 10]" is not useful to most users, since they
will wonder: ahead of what?.

A lot of people set their upstream to the place they push to, not where
they base their branch on. In fact, many guides suggest the following to
set the upstream branch:

  git push --set-upstream github pull-request

Even more, when pushing a fresh branch git itself recommends that:

  % git clone $url .
  % git checkout -b fix
  ...
  % git push

  fatal: The current branch fix has no upstream branch.
  To push the current branch and set the remote as upstream, use

      git push --set-upstream origin fix

Therefore for many workflows `git branch -v` is not very useful.

Inevitably many users will need to know what @{upstream} is.

So let's make `git branch -v` output what is most useful:

  [myrepo/mybranch]

Before:

  * mybranch b2489a3735 [ahead 1] Hot fix

After:

  * mybranch b2489a3735 [myrepo/mybranch] Hot fix

An additional benefit is that `git branch -v` is faster: from 2 to 40
times (depending on the number of stale branches).

`git branch -vv` is unaffected.

Suggestions-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
---

Since v1 I updated the title of the commit, and also the entire commit
message prompted by suggestions from Ævar.

In particupar I added the example git itself shows by default when
pushing a branch with no upstream:

    git push --set-upstream origin fix

This _obviously_ suggests people have configured upstream branches other
than origin/master.

I also updated the documentation, again, as Ævar suggested.

And I also left alone the workdir stuff. I think if we are going to show
upstream branches with -v, it makes sense to show workdirs too. However,
since this patch received more pushback than I expected, I decided to
minimize the changes.

Range-diff against v1:
1:  ade2eb0aba ! 1:  f309c75ea4 branch: make -v useful
    @@ Metadata
     Author: Felipe Contreras <felipe.contreras@gmail.com>
     
      ## Commit message ##
    -    branch: make -v useful
    +    branch: prioritize upstream in -v
     
    -    Currently `git branch -v` shows something like "[ahead 10]", but ahead
    -    of what?
    +    The two important pieces of information relevant to -v and -vv are the
    +    upstream branch, and tracking status (ahead/behind).
     
    -    We git experts know ahead of what, but not what that what is set to. Just
    -    like "[@{upstream}: ahead 10]" would not be particularly useful to
    -    anyone that doesn't know, or remembers, what @{upstream} is set to.
    +    Currently we give priority to the tracking stats (shown with -v) and
    +    demote the upstream branch name (shown only with -vv).
     
    -    On the other hand "[master: ahead 10]" is perfectly clear to anyone.
    +    However, showing "[ahead 10]" is not useful to most users, since they
    +    will wonder: ahead of what?.
     
    -    This confusion only gets worse when you see "[ahead 10, behind 100]". Is
    -    it master? Is it next? Is it
    -    john/experimental-feature-i-based-my-branch-on?
    +    A lot of people set their upstream to the place they push to, not where
    +    they base their branch on. In fact, many guides suggest the following to
    +    set the upstream branch:
     
    -    Inevitably most users will need to know what @{upstream} is.
    +      git push --set-upstream github pull-request
    +
    +    Even more, when pushing a fresh branch git itself recommends that:
    +
    +      % git clone $url .
    +      % git checkout -b fix
    +      ...
    +      % git push
    +
    +      fatal: The current branch fix has no upstream branch.
    +      To push the current branch and set the remote as upstream, use
    +
    +          git push --set-upstream origin fix
    +
    +    Therefore for many workflows `git branch -v` is not very useful.
    +
    +    Inevitably many users will need to know what @{upstream} is.
     
         So let's make `git branch -v` output what is most useful:
     
    -      [master]
    +      [myrepo/mybranch]
     
         Before:
     
    -      * fc/branch/sane-colors b2489a3735 [ahead 1] branch: make -v useful
    +      * mybranch b2489a3735 [ahead 1] Hot fix
     
         After:
     
    -      * fc/branch/sane-colors b2489a3735 [master] branch: make -v useful
    +      * mybranch b2489a3735 [myrepo/mybranch] Hot fix
     
    -    An additional benefit is that `git branch -v` is slightly faster: 30ms
    -    vs. 60ms on my system.
    +    An additional benefit is that `git branch -v` is faster: from 2 to 40
    +    times (depending on the number of stale branches).
     
         `git branch -vv` is unaffected.
     
    +    Suggestions-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
         Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>
     
    + ## Documentation/git-branch.txt ##
    +@@ Documentation/git-branch.txt: This option is only applicable in non-verbose mode.
    + --verbose::
    + 	When in list mode,
    + 	show sha1 and commit subject line for each head, along with
    +-	relationship to upstream branch (if any). If given twice, print
    +-	the path of the linked worktree (if any) and the name of the upstream
    ++	the upstream branch (if any). If given twice, print
    ++	the path of the linked worktree (if any) and the relationship to the upstream
    + 	branch, as well (see also `git remote show <remote>`).  Note that the
    + 	current worktree's HEAD will not have its path printed (it will always
    + 	be your current directory).
    +@@ Documentation/git-branch.txt: This option is only applicable in non-verbose mode.
    + 	`branch.<name>.merge` configuration entries to mark the
    + 	start-point branch as "upstream" from the new branch. This
    + 	configuration will tell git to show the relationship between the
    +-	two branches in `git status` and `git branch -v`. Furthermore,
    ++	two branches in `git status` and `git branch -vv`. Furthermore,
    + 	it directs `git pull` without arguments to pull from the
    + 	upstream when the new branch is checked out.
    + +
    +
      ## builtin/branch.c ##
     @@ builtin/branch.c: static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
    - 		strbuf_addstr(&local, branch_get_color(BRANCH_COLOR_RESET));
    - 		strbuf_addf(&local, " %s ", obname.buf);
    - 
    -+		strbuf_addf(&local, "%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)",
    -+			    branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));
    - 		if (filter->verbose > 1)
    --		{
    --			strbuf_addf(&local, "%%(if:notequals=*)%%(HEAD)%%(then)%%(if)%%(worktreepath)%%(then)(%s%%(worktreepath)%s) %%(end)%%(end)",
    --				    branch_get_color(BRANCH_COLOR_WORKTREE), branch_get_color(BRANCH_COLOR_RESET));
    - 			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(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s] %%(end)%%(contents:subject)",

 Documentation/git-branch.txt |  6 +++---
 builtin/branch.c             |  3 ++-
 t/t3201-branch-contains.sh   |  2 +-
 t/t6040-tracking-info.sh     | 12 ++++++------
 4 files changed, 12 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index 94dc9a54f2..ebf5d69b68 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -183,8 +183,8 @@  This option is only applicable in non-verbose mode.
 --verbose::
 	When in list mode,
 	show sha1 and commit subject line for each head, along with
-	relationship to upstream branch (if any). If given twice, print
-	the path of the linked worktree (if any) and the name of the upstream
+	the upstream branch (if any). If given twice, print
+	the path of the linked worktree (if any) and the relationship to the upstream
 	branch, as well (see also `git remote show <remote>`).  Note that the
 	current worktree's HEAD will not have its path printed (it will always
 	be your current directory).
@@ -210,7 +210,7 @@  This option is only applicable in non-verbose mode.
 	`branch.<name>.merge` configuration entries to mark the
 	start-point branch as "upstream" from the new branch. This
 	configuration will tell git to show the relationship between the
-	two branches in `git status` and `git branch -v`. Furthermore,
+	two branches in `git status` and `git branch -vv`. Furthermore,
 	it directs `git pull` without arguments to pull from the
 	upstream when the new branch is checked out.
 +
diff --git a/builtin/branch.c b/builtin/branch.c
index b23b1d1752..ed3d0946a7 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -384,7 +384,8 @@  static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
 				    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(&local, "%%(if)%%(upstream)%%(then)[%s%%(upstream:short)%s] %%(end)%%(contents:subject)",
+				    branch_get_color(BRANCH_COLOR_UPSTREAM), branch_get_color(BRANCH_COLOR_RESET));
 
 		strbuf_addf(&remote, "%%(align:%d,left)%s%%(refname:lstrip=2)%%(end)%s"
 			    "%%(if)%%(symref)%%(then) -> %%(symref:short)"
diff --git a/t/t3201-branch-contains.sh b/t/t3201-branch-contains.sh
index 349a810cee..53e2d65e67 100755
--- a/t/t3201-branch-contains.sh
+++ b/t/t3201-branch-contains.sh
@@ -261,7 +261,7 @@  test_expect_success 'branch --merged with --verbose' '
 	git branch --verbose --merged topic >actual &&
 	cat >expect <<-EOF &&
 	  main  $(git rev-parse --short main) second on main
-	* topic $(git rev-parse --short topic ) [ahead 1] foo
+	* topic $(git rev-parse --short topic ) [main] foo
 	  zzz   $(git rev-parse --short zzz   ) second on main
 	EOF
 	test_cmp expect actual
diff --git a/t/t6040-tracking-info.sh b/t/t6040-tracking-info.sh
index a313849406..30f80ad61b 100755
--- a/t/t6040-tracking-info.sh
+++ b/t/t6040-tracking-info.sh
@@ -43,12 +43,12 @@  test_expect_success setup '
 
 t6040_script='s/^..\(b.\) *[0-9a-f]* \(.*\)$/\1 \2/p'
 cat >expect <<\EOF
-b1 [ahead 1, behind 1] d
-b2 [ahead 1, behind 1] d
-b3 [behind 1] b
-b4 [ahead 2] f
-b5 [gone] g
-b6 c
+b1 [origin/main] d
+b2 [origin/main] d
+b3 [origin/main] b
+b4 [origin/main] f
+b5 [brokenbase] g
+b6 [origin/main] c
 EOF
 
 test_expect_success 'branch -v' '