[PATCH v5] branch: introduce --show-current display option

2018-10-25 Thread Daniels Umanovskis
When called with --show-current, git branch will print the current
branch name and terminate. Only the actual name gets printed,
without refs/heads. In detached HEAD state, nothing is output.

Intended both for scripting and interactive/informative use.
Unlike git branch --list, no filtering is needed to just get the
branch name.

Signed-off-by: Daniels Umanovskis 
---

Submitting v5 now that a week has passed since latest maintainer
comments.

This is basically v4 but with small fixes to the test, as proposed
by Junio on pu, and additionally replacing a subshell
with { .. } since Dscho and Eric discovered the negative
performance effects of subshell invocations.

 Documentation/git-branch.txt |  6 -
 builtin/branch.c | 25 ++--
 t/t3203-branch-output.sh | 44 
 3 files changed, 72 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index bf5316ffa9..0babb9b1be 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 
 [verse]
 'git branch' [--color[=] | --no-color] [-r | -a]
-   [--list] [-v [--abbrev= | --no-abbrev]]
+   [--list] [--show-current] [-v [--abbrev= | --no-abbrev]]
[--column[=] | --no-column] [--sort=]
[(--merged | --no-merged) []]
[--contains []]
@@ -160,6 +160,10 @@ This option is only applicable in non-verbose mode.
branch --list 'maint-*'`, list only the branches that match
the pattern(s).
 
+--show-current::
+   Print the name of the current branch. In detached HEAD state,
+   nothing is printed.
+
 -v::
 -vv::
 --verbose::
diff --git a/builtin/branch.c b/builtin/branch.c
index c396c41533..46f91dc06d 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -443,6 +443,21 @@ static void print_ref_list(struct ref_filter *filter, 
struct ref_sorting *sortin
free(to_free);
 }
 
+static void print_current_branch_name(void)
+{
+   int flags;
+   const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
+   const char *shortname;
+   if (!refname)
+   die(_("could not resolve HEAD"));
+   else if (!(flags & REF_ISSYMREF))
+   return;
+   else if (skip_prefix(refname, "refs/heads/", &shortname))
+   puts(shortname);
+   else
+   die(_("HEAD (%s) points outside of refs/heads/"), refname);
+}
+
 static void reject_rebase_or_bisect_branch(const char *target)
 {
struct worktree **worktrees = get_worktrees(0);
@@ -581,6 +596,7 @@ static int edit_branch_description(const char *branch_name)
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
+   int show_current = 0;
int reflog = 0, edit_description = 0;
int quiet = 0, unset_upstream = 0;
const char *new_upstream = NULL;
@@ -620,6 +636,7 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 
1),
OPT_BIT('C', NULL, ©, N_("copy a branch, even if target 
exists"), 2),
OPT_BOOL('l', "list", &list, N_("list branch names")),
+   OPT_BOOL(0, "show-current", &show_current, N_("show current 
branch name")),
OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's 
reflog")),
OPT_BOOL(0, "edit-description", &edit_description,
 N_("edit the description for the branch")),
@@ -662,14 +679,15 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 0);
 
-   if (!delete && !rename && !copy && !edit_description && !new_upstream 
&& !unset_upstream && argc == 0)
+   if (!delete && !rename && !copy && !edit_description && !new_upstream &&
+   !show_current && !unset_upstream && argc == 0)
list = 1;
 
if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || 
filter.points_at.nr ||
filter.no_commit)
list = 1;
 
-   if (!!delete + !!rename + !!copy + !!new_upstream +
+   if (!!delete + !!rename + !!copy + !!new_upstream + !!show_current +
list + unset_upstream > 1)
usage_with_options(builtin_branch_usage, options);
 
@@ -697,6 +715,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
if (!argc)
die(_("branch n

[PATCH 0/2] branch: introduce --current display option

2018-10-09 Thread Daniels Umanovskis
I often find myself needing the current branch name, for which currently 
there's git rev-parse --abrev-ref HEAD. I would expect `git branch` to have an 
option to output the branch name instead.

This is my first patch to Git, so process-related comments (patch formatting, 
et cetera) are quite welcome.

Daniels Umanovskis (2):
  branch: introduce --current display option
  doc/git-branch: Document the --current option

 Documentation/git-branch.txt |  6 +-
 builtin/branch.c | 16 
 t/t3203-branch-output.sh | 18 ++
 3 files changed, 39 insertions(+), 1 deletion(-)

-- 
2.19.1.272.gf84b9b09d.dirty



[PATCH 1/2] branch: introduce --current display option

2018-10-09 Thread Daniels Umanovskis
When called with --current, git branch will print the current
branch name and terminate. It will print HEAD in detached-head state.

Rationale: finding out the current branch is useful interactively,
but especially in scripting. git branch --list prints many branches,
and prepends the current one with an asterisk, meaning sed or other
filtering is necessary to just get the current branch.
git rev-parse --abbrev-ref HEAD is the current way to achieve this
output, but that is not intuitive or easy to understand.

Signed-off-by: Daniels Umanovskis 
---
 builtin/branch.c | 17 +
 t/t3203-branch-output.sh | 18 ++
 2 files changed, 35 insertions(+)

diff --git a/builtin/branch.c b/builtin/branch.c
index c396c4153..e4c6b0490 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -443,6 +443,18 @@ static void print_ref_list(struct ref_filter *filter, 
struct ref_sorting *sortin
free(to_free);
 }
 
+static void print_current_branch_name()
+{
+   struct strbuf out = STRBUF_INIT;
+   const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
+   char *shortname = shorten_unambiguous_ref(refname, 0);
+   strbuf_addf(&out, _("%s"), shortname);
+   fwrite(out.buf, 1, out.len, stdout);
+   putchar('\n');
+   free(shortname);
+   strbuf_release(&out);
+}
+
 static void reject_rebase_or_bisect_branch(const char *target)
 {
struct worktree **worktrees = get_worktrees(0);
@@ -581,6 +593,7 @@ static int edit_branch_description(const char *branch_name)
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
+   int current = 0;
int reflog = 0, edit_description = 0;
int quiet = 0, unset_upstream = 0;
const char *new_upstream = NULL;
@@ -620,6 +633,7 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 
1),
OPT_BIT('C', NULL, ©, N_("copy a branch, even if target 
exists"), 2),
OPT_BOOL('l', "list", &list, N_("list branch names")),
+   OPT_BOOL(0, "current", ¤t, N_("show current branch 
name")),
OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's 
reflog")),
OPT_BOOL(0, "edit-description", &edit_description,
 N_("edit the description for the branch")),
@@ -697,6 +711,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
if (!argc)
die(_("branch name required"));
return delete_branches(argc, argv, delete > 1, filter.kind, 
quiet);
+   } else if (current) {
+   print_current_branch_name();
+   return 0;
} else if (list) {
/*  git branch --local also shows HEAD when it is detached */
if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached)
diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh
index ee6787614..396d81568 100755
--- a/t/t3203-branch-output.sh
+++ b/t/t3203-branch-output.sh
@@ -100,6 +100,24 @@ test_expect_success 'git branch -v pattern does not show 
branch summaries' '
test_must_fail git branch -v branch*
 '
 
+test_expect_success 'git branch `--current` shows current branch' '
+   cat >expect <<-\EOF &&
+   branch-two
+   EOF
+git checkout branch-two &&
+   git branch --current >actual &&
+   test_cmp expect actual
+'
+
+test_expect_success 'git branch `--current` shows detached HEAD properly' '
+   cat >expect <<-\EOF &&
+   HEAD
+   EOF
+git checkout HEAD^0 &&
+   git branch --current >actual &&
+   test_cmp expect actual
+'
+
 test_expect_success 'git branch shows detached HEAD properly' '
cat >expect <

[PATCH 2/2] doc/git-branch: Document the --current option

2018-10-09 Thread Daniels Umanovskis
Signed-off-by: Daniels Umanovskis 
---
 Documentation/git-branch.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index bf5316ffa..a7167df74 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 
 [verse]
 'git branch' [--color[=] | --no-color] [-r | -a]
-   [--list] [-v [--abbrev= | --no-abbrev]]
+   [--list] [--current] [-v [--abbrev= | --no-abbrev]]
[--column[=] | --no-column] [--sort=]
[(--merged | --no-merged) []]
[--contains []]
@@ -160,6 +160,10 @@ This option is only applicable in non-verbose mode.
branch --list 'maint-*'`, list only the branches that match
the pattern(s).
 
+--current::
+   Print the name of the current branch. In detached HEAD state,
+   or if otherwise impossible to resolve the branch name, print
+   "HEAD".
 -v::
 -vv::
 --verbose::
-- 
2.19.1.274.g059d67db4.dirty



Re: [PATCH 1/2] branch: introduce --current display option

2018-10-09 Thread Daniels Umanovskis
Thanks for the feedback!

On 10/9/18 9:54 PM, Stefan Beller wrote:
> How does it play with worktrees? (I would expect it to just work as expected:
> each worktree would print its current branch, but a test might help?)

I'll see about writing a test for that. I've never used git-worktree so
this is a good chance to learn.

> Git used to have (and still has) the approach of dividing its commands
> into high level ("porcelain") commands and low level ("plumbing") commands,
> with the porcelain facing the user and plumbing being good for scripting.
> 
> This patch proposes a radically different approach, which is convenience
> of use.

Right - a couple of points in response. First, it strikes me that "print
current branch" is one of those things that are both for scripting and
for normal/interactive use. Much like the entirety of git-status, which
is very used by itself, and also in scripts with --porcelain. Current
branch is often used in things like your shell prompt, vim statusline,
etc, as well as scripts.

The amount of upvotes on the stackoverflow question "how to get the
current branch name in git?" illustrates my point :)

Second, it seems arguable whether `git ref-parse` is guaranteed to be
scripting-safe, it's not actually a plumbing command, at least if we
trust the main git manpage, which lists git-rev-parse as porcelain anyway.

> Why do we need to add the shortname to a strbuf?
> (and using _( ) that denotes the string should be translated?)
> I would think we could just
> 
> puts(shortname)
> 
> here and leave out all the strbuf out ?
> 
Of course, has to be changed for v2. Pitfalls of learning the code from
just its surroundings, didn't realize that the underscores are for i18n.


Re: [PATCH 0/2] branch: introduce --current display option

2018-10-10 Thread Daniels Umanovskis
On 10/10/18 5:03 PM, Ævar Arnfjörð Bjarmason wrote:
> 
> I'm mildly negative on this because git-rev-parse is plumbing, but
> git-branch is porcelain [..]
> 
> We also list git-rev-parse as porcelain, just under "Porcelain / Ancillary
> Commands / Interrogators".
> 
> Should we just move it to plumbing? I don't know.

>From my perspective as a Git user, not developer, git-rev-parse is
between plumbing and porcelain, but much more plumbing. It's listed as
porcelain but is connected to the plumbing git-rev-list, and for the
most part it does things incomprehensible without understanding Git
internals. Then it also has a bunch of options that are very useful in
scripts but unrelated to revisions, here I mean --git-dir or
--is-inside-work-tree.

I'd be happy to submit a documentation patch for discussion that
formally moves rev-parse to plumbing.

> Also, as much as our current scripting interface can be very confusing
> (you might not think "get current branch" is under rev-parse), I can't
> help but think that adding two different ways to spew out the exact same
> thing to two different commands is heading in the wrong
> direction.

Agreed, so I'm very much inclined to move forward with Junio's preferred
solution on this, which would also act differently by only outputting
the branch when you're really on a branch, and being silent in e.g.
detached HEAD.


[PATCH v2 0/1] branch: introduce --show-current display option

2018-10-10 Thread Daniels Umanovskis
v2 reroll of a previously-discussed patch. Thanks to everyone for their
comments. Based on feedback:

1. Command is now a verb: git branch --show-current.

2. Changed to gitster's suggested implementation: nothing is printed
 if HEAD does not point to a symbolic ref. A fatal
 error if HEAD is a symbolic ref but does not start with refs/heads/.

3. Added a test to show this works with worktrees

A process question to the list. The patch adds a new localizable string
that gets output in case of repository corruption. I happen to speak a
couple of the languages that have po files. Is it accepted practice to
also include po edits in my patch in such a case, or should that be
left to the regular l10n workflow?

Daniels Umanovskis (1):
  branch: introduce --show-current display option

 Documentation/git-branch.txt |  6 +-
 builtin/branch.c | 21 --
 t/t3203-branch-output.sh | 41 
 3 files changed, 65 insertions(+), 3 deletions(-)

-- 
2.19.1.330.g93276587c.dirty



[PATCH v2 1/1] branch: introduce --show-current display option

2018-10-10 Thread Daniels Umanovskis
When called with --show-current, git branch will print the current
branch name and terminate. Only the actual name gets printed,
without refs/heads. In detached HEAD state, nothing is output.

Intended both for scripting and interactive/informative use.
Unlike git branch --list, no filtering is needed to just get the
branch name.

Signed-off-by: Daniels Umanovskis 
---
 Documentation/git-branch.txt |  6 +-
 builtin/branch.c | 21 --
 t/t3203-branch-output.sh | 41 
 3 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index bf5316ffa..0babb9b1b 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 
 [verse]
 'git branch' [--color[=] | --no-color] [-r | -a]
-   [--list] [-v [--abbrev= | --no-abbrev]]
+   [--list] [--show-current] [-v [--abbrev= | --no-abbrev]]
[--column[=] | --no-column] [--sort=]
[(--merged | --no-merged) []]
[--contains []]
@@ -160,6 +160,10 @@ This option is only applicable in non-verbose mode.
branch --list 'maint-*'`, list only the branches that match
the pattern(s).
 
+--show-current::
+   Print the name of the current branch. In detached HEAD state,
+   nothing is printed.
+
 -v::
 -vv::
 --verbose::
diff --git a/builtin/branch.c b/builtin/branch.c
index c396c4153..ab03073b2 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -443,6 +443,17 @@ static void print_ref_list(struct ref_filter *filter, 
struct ref_sorting *sortin
free(to_free);
 }
 
+static void print_current_branch_name()
+{
+   const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, NULL);
+   const char *shortname;
+   if (refname == NULL || !strcmp(refname, "HEAD"))
+   return;
+   if (!skip_prefix(refname, "refs/heads/", &shortname))
+   die(_("unexpected symbolic ref for HEAD: %s"), refname);
+   puts(shortname);
+}
+
 static void reject_rebase_or_bisect_branch(const char *target)
 {
struct worktree **worktrees = get_worktrees(0);
@@ -581,6 +592,7 @@ static int edit_branch_description(const char *branch_name)
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
+   int show_current = 0;
int reflog = 0, edit_description = 0;
int quiet = 0, unset_upstream = 0;
const char *new_upstream = NULL;
@@ -620,6 +632,7 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 
1),
OPT_BIT('C', NULL, ©, N_("copy a branch, even if target 
exists"), 2),
OPT_BOOL('l', "list", &list, N_("list branch names")),
+   OPT_BOOL(0, "show-current", &show_current, N_("show current 
branch name")),
OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's 
reflog")),
OPT_BOOL(0, "edit-description", &edit_description,
 N_("edit the description for the branch")),
@@ -662,14 +675,15 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 0);
 
-   if (!delete && !rename && !copy && !edit_description && !new_upstream 
&& !unset_upstream && argc == 0)
+   if (!delete && !rename && !copy && !edit_description && !new_upstream &&
+   !show_current && !unset_upstream && argc == 0)
list = 1;
 
if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || 
filter.points_at.nr ||
filter.no_commit)
list = 1;
 
-   if (!!delete + !!rename + !!copy + !!new_upstream +
+   if (!!delete + !!rename + !!copy + !!new_upstream + !!show_current +
list + unset_upstream > 1)
usage_with_options(builtin_branch_usage, options);
 
@@ -697,6 +711,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
if (!argc)
die(_("branch name required"));
return delete_branches(argc, argv, delete > 1, filter.kind, 
quiet);
+   } else if (show_current) {
+   print_current_branch_name();
+   return 0;
} else if (list) {
/*  git branch --local also shows HEAD when it is detached */
if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached)
diff --git a/t/t3203-br

[PATCH] doc: move git-rev-parse from porcelain to plumbing

2018-10-10 Thread Daniels Umanovskis
git-rev-parse mostly seems like plumbing, and is more usd in
scripts than in regular use. Online it's often mentioned as
a plumbing command. Nonetheless it's listed under porcelain
interrogators in `man git`. It seems appropriate to formally
move git-rev-parse to plumbing interrogators.

Signed-off-by: Daniels Umanovskis 
---
 command-list.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/command-list.txt b/command-list.txt
index c36ea3c18..e6364e167 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -153,7 +153,7 @@ git-rerere  
ancillaryinterrogators
 git-reset   mainporcelain   worktree
 git-revert  mainporcelain
 git-rev-listplumbinginterrogators
-git-rev-parse   ancillaryinterrogators
+git-rev-parse   plumbinginterrogators
 git-rm  mainporcelain   worktree
 git-send-email  foreignscminterface 
complete
 git-send-pack   synchingrepositories
-- 
2.19.1.330.g93276587c.dirty



Re: [PATCH] doc: move git-rev-parse from porcelain to plumbing

2018-10-10 Thread Daniels Umanovskis
On 10/11/18 12:26 AM, Junio C Hamano wrote:
> Among the remaining ones in the list, cherry and get-tar-commit-id
> are probably better classified as plumbing.  I do not know why
> cherry is marked for completion; perhaps some crazy people use that
> on the command line?

I think cherry could go either way, get-tar-commit-id is definitely
plumbing. Would you like me to fix those two on the same patch then?



Re: [PATCH v2 1/1] branch: introduce --show-current display option

2018-10-11 Thread Daniels Umanovskis
On 10/11/18 5:43 PM, Rafael Ascensão wrote:
> I agree it feels a bit out of place, and still think that
> 
> $ git branch --list HEAD
> 
> would be a good candidate to be taught how to print the current branch.

I am not a fan because it would be yet another inconsistency in the Git
command interface. An argument given after git branch --list means a
pattern for the branches to list. Making HEAD print the current branch
would be an exception to what an argument in that place means. Yes, HEAD
itself is a very special string in git, but I'm not a fan of syntax
where a specific argument value does something very different from any
other value in that place.


Re: [PATCH v2 1/1] branch: introduce --show-current display option

2018-10-11 Thread Daniels Umanovskis
On 10/11/18 8:54 AM, Junio C Hamano wrote:
> Is it a normal situation to have refname==NULL, or is it something
> worth reporting as an error?

Looks like that would be in the case of looping symrefs or file backend
failure, so seems a good idea to die() in that case.

> Without passing the &flag argument, I do not think there is a
> reliable way to ask resolve_ref_unsafe() if "HEAD" is a symbolic
> ref.

If I'm reading the code correctly, resolve_ref_unsafe() will return
"HEAD" or NULL if there's no symbolic reference, so anything else would
indicate a symref, but even in that case checking the flag explicitly is
definitely better to clearly show intent.

Will soon reply with v3 cleaning up the suggested patch accordingly.



[PATCH] doc: move git-cherry to plumbing

2018-10-11 Thread Daniels Umanovskis
Also remove git-cherry from Bash completion because plumbing
commands do not belong there.

Signed-off-by: Daniels Umanovskis 
---

Up to discussion whether cherry should be considered plumbing.
I lean towards considering it a rarely-used porcelain command, but
a case could be made either way so let's see what the list thinks.

 command-list.txt   |  2 +-
 contrib/completion/git-completion.bash | 11 ---
 2 files changed, 1 insertion(+), 12 deletions(-)

diff --git a/command-list.txt b/command-list.txt
index c36ea3c18..bdca6e3d3 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -62,7 +62,7 @@ git-check-mailmap   purehelpers
 git-checkoutmainporcelain   history
 git-checkout-index  plumbingmanipulators
 git-check-ref-formatpurehelpers
-git-cherry  ancillaryinterrogators  
complete
+git-cherry  plumbinginterrogators  complete
 git-cherry-pick mainporcelain
 git-citool  mainporcelain
 git-clean   mainporcelain
diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index d63d2dffd..12f7ce0c5 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1340,17 +1340,6 @@ _git_checkout ()
esac
 }
 
-_git_cherry ()
-{
-   case "$cur" in
-   --*)
-   __gitcomp_builtin cherry
-   return
-   esac
-
-   __git_complete_refs
-}
-
 __git_cherry_pick_inprogress_options="--continue --quit --abort"
 
 _git_cherry_pick ()
-- 
2.19.1.330.g93276587c.dirty



[PATCH] doc: move git-get-tar-commit-id to plumbing

2018-10-11 Thread Daniels Umanovskis
This is definitely a low-level command, it's hard to argue
against it belonging in plumbing.

Signed-off-by: Daniels Umanovskis 
---
 command-list.txt | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/command-list.txt b/command-list.txt
index c36ea3c18..966705358 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -96,7 +96,7 @@ git-for-each-refplumbinginterrogators
 git-format-patchmainporcelain
 git-fsckancillaryinterrogators  
complete
 git-gc  mainporcelain
-git-get-tar-commit-id   ancillaryinterrogators
+git-get-tar-commit-id   plumbinginterrogators
 git-grepmainporcelain   info
 git-gui mainporcelain
 git-hash-object plumbingmanipulators
-- 
2.19.1.330.g93276587c.dirty



Re: [PATCH v2 1/1] branch: introduce --show-current display option

2018-10-11 Thread Daniels Umanovskis
On 10/11/18 10:35 PM, Rafael Ascensão wrote:
> The output of the proposed command is also a bit inconsistent with the
> usual output given by git branch, specifically the space alignment on
> the left, color and * marker.

The proposed command therefore takes a new switch. It's definitely not
perfect, but doesn't give the existing --list new and different behavior.

> At this stage it's closer to what I would expect from
> $git rev-parse --abbrev-ref HEAD;

The proposal is largely to have similar output to that command, yes. I
expect that "show current branch" is something that's available in the
branch command, even completely disregarding questions of whether it's
API stable, etc.


[PATCH v3] branch: introduce --show-current display option

2018-10-11 Thread Daniels Umanovskis
When called with --show-current, git branch will print the current
branch name and terminate. Only the actual name gets printed,
without refs/heads. In detached HEAD state, nothing is output.

Intended both for scripting and interactive/informative use.
Unlike git branch --list, no filtering is needed to just get the
branch name.

Signed-off-by: Daniels Umanovskis 
---

Cleaned up per suggestions, explicitly passing flags to clearly
denote intent. If you consider the patch good conceptually, this
implementation should hopefully be good enough to include.

 Documentation/git-branch.txt |  6 +-
 builtin/branch.c | 25 --
 t/t3203-branch-output.sh | 41 
 3 files changed, 69 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index bf5316ffa..0babb9b1b 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 
 [verse]
 'git branch' [--color[=] | --no-color] [-r | -a]
-   [--list] [-v [--abbrev= | --no-abbrev]]
+   [--list] [--show-current] [-v [--abbrev= | --no-abbrev]]
[--column[=] | --no-column] [--sort=]
[(--merged | --no-merged) []]
[--contains []]
@@ -160,6 +160,10 @@ This option is only applicable in non-verbose mode.
branch --list 'maint-*'`, list only the branches that match
the pattern(s).
 
+--show-current::
+   Print the name of the current branch. In detached HEAD state,
+   nothing is printed.
+
 -v::
 -vv::
 --verbose::
diff --git a/builtin/branch.c b/builtin/branch.c
index c396c4153..46f91dc06 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -443,6 +443,21 @@ static void print_ref_list(struct ref_filter *filter, 
struct ref_sorting *sortin
free(to_free);
 }
 
+static void print_current_branch_name(void)
+{
+   int flags;
+   const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
+   const char *shortname;
+   if (!refname)
+   die(_("could not resolve HEAD"));
+   else if (!(flags & REF_ISSYMREF))
+   return;
+   else if (skip_prefix(refname, "refs/heads/", &shortname))
+   puts(shortname);
+   else
+   die(_("HEAD (%s) points outside of refs/heads/"), refname);
+}
+
 static void reject_rebase_or_bisect_branch(const char *target)
 {
struct worktree **worktrees = get_worktrees(0);
@@ -581,6 +596,7 @@ static int edit_branch_description(const char *branch_name)
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
+   int show_current = 0;
int reflog = 0, edit_description = 0;
int quiet = 0, unset_upstream = 0;
const char *new_upstream = NULL;
@@ -620,6 +636,7 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 
1),
OPT_BIT('C', NULL, ©, N_("copy a branch, even if target 
exists"), 2),
OPT_BOOL('l', "list", &list, N_("list branch names")),
+   OPT_BOOL(0, "show-current", &show_current, N_("show current 
branch name")),
OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's 
reflog")),
OPT_BOOL(0, "edit-description", &edit_description,
 N_("edit the description for the branch")),
@@ -662,14 +679,15 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 0);
 
-   if (!delete && !rename && !copy && !edit_description && !new_upstream 
&& !unset_upstream && argc == 0)
+   if (!delete && !rename && !copy && !edit_description && !new_upstream &&
+   !show_current && !unset_upstream && argc == 0)
list = 1;
 
if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || 
filter.points_at.nr ||
filter.no_commit)
list = 1;
 
-   if (!!delete + !!rename + !!copy + !!new_upstream +
+   if (!!delete + !!rename + !!copy + !!new_upstream + !!show_current +
list + unset_upstream > 1)
usage_with_options(builtin_branch_usage, options);
 
@@ -697,6 +715,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
if (!argc)
die(_("branch name required"));
return delete_branches(argc, argv, delete > 1, filter.kind, 
quiet);
+

Re: [PATCH v2 1/1] branch: introduce --show-current display option

2018-10-11 Thread Daniels Umanovskis
On 10/12/18 12:56 AM, SZEDER Gábor wrote:
> Ah, OK, just noticed v3 which has already fixed this.
> 
Yeah - squashed the wrong commits locally for v2. Thanks for pointing
this out anyway!


Re: [PATCH v3] branch: introduce --show-current display option

2018-10-11 Thread Daniels Umanovskis
On 10/12/18 1:15 AM, Junio C Hamano wrote:
> It is a bit curious why you remove the branch but not the tag after
> this test.  [..]
> 
> So two equally valid choices are to remove "branch -d" and then
> either:
> 
>  (1) leave both branch and tag after this test in the test
>  repository
> 
>  (2) use test_when_finished [..]

Thanks for this explanation! You're right, I removed the branch because
it otherwise breaks subsequent tests, while the tag doesn't matter. I'll
go take a look at how test_when_finished can be used.

> Please do *not* cd around without being in a subshell.  

Understood, thanks for explaining this as well.


[PATCH v4] branch: introduce --show-current display option

2018-10-12 Thread Daniels Umanovskis
When called with --show-current, git branch will print the current
branch name and terminate. Only the actual name gets printed,
without refs/heads. In detached HEAD state, nothing is output.

Intended both for scripting and interactive/informative use.
Unlike git branch --list, no filtering is needed to just get the
branch name.

Signed-off-by: Daniels Umanovskis 
---

Compared to v3, fixed up test cases according to Junio's input

 Documentation/git-branch.txt |  6 +-
 builtin/branch.c | 25 +++--
 t/t3203-branch-output.sh | 43 +++
 3 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt
index bf5316ffa..0babb9b1b 100644
--- a/Documentation/git-branch.txt
+++ b/Documentation/git-branch.txt
@@ -9,7 +9,7 @@ SYNOPSIS
 
 [verse]
 'git branch' [--color[=] | --no-color] [-r | -a]
-   [--list] [-v [--abbrev= | --no-abbrev]]
+   [--list] [--show-current] [-v [--abbrev= | --no-abbrev]]
[--column[=] | --no-column] [--sort=]
[(--merged | --no-merged) []]
[--contains []]
@@ -160,6 +160,10 @@ This option is only applicable in non-verbose mode.
branch --list 'maint-*'`, list only the branches that match
the pattern(s).
 
+--show-current::
+   Print the name of the current branch. In detached HEAD state,
+   nothing is printed.
+
 -v::
 -vv::
 --verbose::
diff --git a/builtin/branch.c b/builtin/branch.c
index c396c4153..46f91dc06 100644
--- a/builtin/branch.c
+++ b/builtin/branch.c
@@ -443,6 +443,21 @@ static void print_ref_list(struct ref_filter *filter, 
struct ref_sorting *sortin
free(to_free);
 }
 
+static void print_current_branch_name(void)
+{
+   int flags;
+   const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags);
+   const char *shortname;
+   if (!refname)
+   die(_("could not resolve HEAD"));
+   else if (!(flags & REF_ISSYMREF))
+   return;
+   else if (skip_prefix(refname, "refs/heads/", &shortname))
+   puts(shortname);
+   else
+   die(_("HEAD (%s) points outside of refs/heads/"), refname);
+}
+
 static void reject_rebase_or_bisect_branch(const char *target)
 {
struct worktree **worktrees = get_worktrees(0);
@@ -581,6 +596,7 @@ static int edit_branch_description(const char *branch_name)
 int cmd_branch(int argc, const char **argv, const char *prefix)
 {
int delete = 0, rename = 0, copy = 0, force = 0, list = 0;
+   int show_current = 0;
int reflog = 0, edit_description = 0;
int quiet = 0, unset_upstream = 0;
const char *new_upstream = NULL;
@@ -620,6 +636,7 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 
1),
OPT_BIT('C', NULL, ©, N_("copy a branch, even if target 
exists"), 2),
OPT_BOOL('l', "list", &list, N_("list branch names")),
+   OPT_BOOL(0, "show-current", &show_current, N_("show current 
branch name")),
OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's 
reflog")),
OPT_BOOL(0, "edit-description", &edit_description,
 N_("edit the description for the branch")),
@@ -662,14 +679,15 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
argc = parse_options(argc, argv, prefix, options, builtin_branch_usage,
 0);
 
-   if (!delete && !rename && !copy && !edit_description && !new_upstream 
&& !unset_upstream && argc == 0)
+   if (!delete && !rename && !copy && !edit_description && !new_upstream &&
+   !show_current && !unset_upstream && argc == 0)
list = 1;
 
if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || 
filter.points_at.nr ||
filter.no_commit)
list = 1;
 
-   if (!!delete + !!rename + !!copy + !!new_upstream +
+   if (!!delete + !!rename + !!copy + !!new_upstream + !!show_current +
list + unset_upstream > 1)
usage_with_options(builtin_branch_usage, options);
 
@@ -697,6 +715,9 @@ int cmd_branch(int argc, const char **argv, const char 
*prefix)
if (!argc)
die(_("branch name required"));
return delete_branches(argc, argv, delete > 1, filter.kind, 
quiet);
+   } else if (show_current) {
+   print_current_branch_name();
+   return 0;
  

Re: [PATCH v4] branch: introduce --show-current display option

2018-10-17 Thread Daniels Umanovskis
On 10/17/18 11:39 AM, Rafael Ascensão wrote:
> On Fri, Oct 12, 2018 at 03:33:21PM +0200, Daniels Umanovskis wrote:
>> Intended both for scripting and interactive/informative use.
>> Unlike git branch --list, no filtering is needed to just get the
>> branch name.
> 
> Are we going forward with advertising this as a scriptable alternative?

That's probably up to the maintainers, but I would not explicitly point
it out as a script command, so my patch doesn't mention scripting use in
the documentation for it. In reality it's useful for "soft scripting"
like setting the shell $PS1, which doesn't require API stability
guarantees the way proper scripts do.