TL;DR: I think you are misinterpreting the role of a pre-receive hook and the HEAD
of the repository in which the pre-receive hook runs.
Description
It's not entirely clear to me what you mean by "working branch name". However, it is true that all repositories have a HEAD
, and git symbolic-ref --short HEAD
will print the name of the branch to which HEAD
points (the "current branch"), even if that branch does not exist yet; or fail if it does not point to a branch name (i.e., is a detached HEAD).
That is:
$ mkdir tt
$ cd tt
$ git init
Initialized empty Git repository in .../tt/.git
$ git symbolic-ref --short HEAD
master
even though:
$ git branch
(note that there is no output)
$ git rev-parse HEAD
HEAD
fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions, like this:
'git <command> [<revision>...] -- [<file>...]'
(git rev-parse HEAD
fails)
$ git status
On branch master
No commits yet
nothing to commit (create/copy files and use "git add" to track)
(the current branch is master
, but there are no commits).
So git symbolic-ref --short HEAD
is probably the thing you're thinking about. (Note that all of the above will continue to work, or fail, the same way in a new --bare
repository, except for git status
, which will say fatal: This operation must be run in a work tree
.)
The main reason this makes little sense is that you also mention a pre-receive hook, and pre-receive hooks are mainly useful in centralized-server "bare" repositories that receive and accept push requests. Remember that a bare repository is a repository that has no work-tree. In a bare repository, the name of the branch to which HEAD
points is almost entirely useless. It has one actual function: it determines which branch a git clone
of that repository will check out, provided the person running git clone
does not specify a particular name to check out.1 In a normal, not-bare repository, HEAD
would be the name of the branch that fills the work-tree of that not-bare repository; but since the bare repository does not have a work-tree, HEAD
does no such thing.
But a pre-receive hook has, in general, no business consulting the current branch anyway. A pre-receive hook is run with its standard input connected to a stream that will supply one or more lines of input. Each line will have the form:
old-hash new-hash reference-name
e.g.,
3b136a71d875174d7539bf98080b85eaf415ba73 95ec6b1b3393eb6e26da40c565520a8db9796e9f refs/heads/foobranch
0000000000000000000000000000000000000000 0452b4b5786778d5d87f5c90a94fab8936502e20 refs/tags/v2.1.0
which in this case indicates that the sending Git would like the receiving Git to update branch foobranch
from its current value of 3b136a71d875174d7539bf98080b85eaf415ba73
to the new value 95ec6b1b3393eb6e26da40c565520a8db9796e9f
, and create the tag v2.1.0
pointing to object 0452b4b5786778d5d87f5c90a94fab8936502e20
.
None of this depends on the current branch in any way. These update requests are provided by the Git that is doing the git push
. Since the receiving repository is (presumably, though you can check if you like) --bare
, it has no work-tree and creating the tag, or replacing the value of foobranch
, will therefore not affect that non-existent work-tree in any way.
1That is, when someone else makes a clone of this bare repository, that someone else can say -b <branch-or-tag>
, but if that someone else doesn't say -b <branch-or-tag>
, that someone else's Git will ask the bare-repository Git what branch its HEAD
represents, and then set things up as if the someone else had specified that as the -b
argument.