3

At the moment I use

git branch | grep \* | cut -d ' ' -f2-

But it's too slow in terms of execution time.

Is there a faster way to generate the same output?

And I mean identical output (I haven't seen any cases I dislike), e.g. detached heads

(HEAD detached at SHA)

rebasing

(no branch, rebasing BRANCH)

etc.


I already tried e.g.

cat .git/HEAD | cut -d '/' -f3

but I know that sometimes, e.g. if rebasing, that won't work. Then I would have to check for existence of .git/REBASE_HEAD ? Also there's the problem of locating the .git directory from any subdirectory. In the end I don't know if a solution like this would be faster, at least probably not if I (with my inexperience) am the one to code it.

theonlygusti
  • 11,032
  • 11
  • 64
  • 119
  • Possible duplicate of [How to get the current branch name in Git?](https://stackoverflow.com/questions/6245570/how-to-get-the-current-branch-name-in-git) – Anton Balaniuc Apr 25 '19 at 12:33
  • 1
    @AntonBalaniuc I don't think its a duplicate, because he is asking for the fastest way to get the current branch name, whereas the other question asks for how to get this name – Iago Carvalho Apr 25 '19 at 12:35
  • As a sidenote, on a detached HEAD state, your current command would *not* ouput a branch name. I guess this is out of the scope of your question? – Romain Valeri Apr 25 '19 at 13:24
  • @RomainValeri I'm not very fluent in git. I don't know what a detached HEAD state is. I will look it up now. – theonlygusti Apr 25 '19 at 13:25
  • @theonlygusti Simply put, you can directly checkout a commit, and then there's no current branch until you checkout a branch again. If your script has to encompass all possible cases, I thought it would be worth mentioning. – Romain Valeri Apr 25 '19 at 13:26
  • @RomainValeri my current command outputs `(HEAD detached at 755a114)`. This is desired behaviour – theonlygusti Apr 25 '19 at 13:28
  • @theonlygusti So it suits your needs? Fine then, sorry for the noise. – Romain Valeri Apr 25 '19 at 13:31
  • @RomainValeri no it's good noise, thank you. I like the discussion and learning (although I will delete the comments if you do) – theonlygusti Apr 25 '19 at 13:31

4 Answers4

3

You also can use git symbolic-ref. However, be careful, since this doesn't work when rebasing.

git symbolic-ref --short HEAD

By the way, this is the shorter command I know to get this information (29 chars)

Iago Carvalho
  • 410
  • 1
  • 5
  • 15
  • Doesn't work for example when rebasing. Probably because this error will have to be checked, this will end up being slower – theonlygusti Apr 25 '19 at 13:07
  • @theonlygusti: when you are in the middle of an interactive or failed rebase, you're not on *any* branch. `git branch` will show this too. The branch you *were* on when you started, if any—you may have started on no branch—is recorded in the information about the in-progress rebase; `git status` can retrieve it. (Edit: I see I should have read through all the collapsed comments under the question itself first :-) ) – torek Apr 25 '19 at 15:13
  • 1
    You can get the same effect as the `git branch | grep ... | cut ...` using: `git symbolic-ref -q --short HEAD || echo "(HEAD detached at $(git rev-parse --short HEAD))"`. The `||` means *if the left-side command failed, run the right side one.* The `-q` makes the symbolic-ref command fail quietly (no `fatal` message) and the right side command prints what `git branch` would have for the detached HEAD, using `git rev-parse --short` to get the abbreviated hash. – torek Apr 25 '19 at 15:20
  • @torek I think the question itself also clarifies that, but yes I guess the title is still wrong I'll edit it – theonlygusti Apr 25 '19 at 15:59
  • @torek that's true, thanks for writing that out. Unfortunately that command line is basically the same if the head is attached and it's slower when the head is detached – theonlygusti Apr 25 '19 at 16:15
  • 1
    @theonlygusti That's ... annoying, at least. I presume you're on Windows, where starting processes is notoriously slow. This sort of thing is nearly instantaneous on Linux. – torek Apr 25 '19 at 16:19
  • @torek it is taking 8 milliseconds roughly. I am using zsh inside of kitty on macOS Mojave. – theonlygusti Apr 25 '19 at 16:24
  • @torek can you build a table comparing the execution times of all options here? It will certainly be the chosen answer for this question – Iago Carvalho Apr 25 '19 at 16:34
2

You can also use git rev-parse : (but unfortunately, as for other answers, this does not handle the case of an in-process rebase)

git rev-parse --abbrev-ref HEAD

Both rev-parse and symbolic-ref are plumbing commands, probably very close in terms of execution time.

Romain Valeri
  • 19,645
  • 3
  • 36
  • 61
  • In short, as opposed to plumbing commands, porcelain commands are intended for human consumption, plumbing commands are mainly for scripting purposes. See [here](https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Porcelain) – Romain Valeri Apr 25 '19 at 13:10
  • when rebasing this outputs `HEAD`. I guess I can test for that output and just convert it to `(no branch, rebasing ???)` but maybe this ends up being slower. – theonlygusti Apr 25 '19 at 13:21
2

Unless you have to absolutely use git commands, You can just read the branch name from the actual .git folder.

cat .git/HEAD | cut -d '/' -f3

This breaks, when you are not in any branch ( So does others ), during which it will return the SHA of the commit that you are in ( unlike the others ). I can't think of any other situation, where it may break.

Harish Ganesan
  • 135
  • 1
  • 2
  • 11
  • Doesn't work for all cases, I would like to always have the same output that my `git branch` example would. I think this might be the way to go though – theonlygusti Apr 25 '19 at 13:05
0

I'm surprised it's that slow but you can try this. Might be equally slow.
git status|head -n1|cut -d ' ' -f4

EncryptedWatermelon
  • 4,788
  • 1
  • 12
  • 28