tags:

views:

40

answers:

1

I've been using Git reasonably successfully (perhaps that's an optimistic evaluation) for going on 2 years now, but have admittedly been doing so somewhat blindly. For whatever reason, I've begun to get much more curious about the internals and have been digging into remote tracking branches of late. They make sense on the whole, but I'm left with this question:

When I clone a repository and all of the remote tracking branches are created, what is the "cloned repository's currently active branch" (quoted from the git-clone documentation)?

If I were cloning from a colleague's repository, I suppose this would be the tracking branch of whichever local branch has the * in front of it in the git branch results, but what if I were cloning from Github? Is it just the branch that I've selected in the interface? Initial tests indicate that this is not the case.

Thanks.

A: 

A Git repository’s currently active branch is the branch to which its HEAD points.

Internally, HEAD is just a file that lives at the top of the repository’s GIT_DIR (the .git directory of a non-bare repository, or the top of a bare repository). If HEAD looks like ref: refs/some/thing, then it is interpreted as a symref (symbolic reference) to the named ref (usually a branch under refs/heads/). If HEAD contains a 40-byte ASCII hex representation of an object name (SHA-1), then we say it is a “detached HEAD” (since it is not “attached” to a normal branch) and it works like a normal ref (i.e. it works like any other branch).

As you supposed, git branch will show the currently active branch with an asterisk before it. This works in regular (non-bare) and bare repositories.

In regular (non-bare) repositories (those with working trees) HEAD is automatically maintained by normal uses of git checkout:

git checkout other-branch
# HEAD is now a symref to refs/heads/other-branch

Bare repositories (usually used on servers) have no working tree, so git checkout will not work. To update a bare repository’s HEAD, you have to use git symbolic-ref:

git symbolic-ref -m 'new default branch' HEAD refs/heads/other-branch
# HEAD is now a symref to refs/heads/other-branch

In both cases you have to have direct access to the repository to update HEAD to change the currently active branch. Like most hosting providers, GitHub do not provide direct access to repositories. It does, however, provide a web interface that lets users change the HEAD of their repositories (they refer to it as the “default branch”).

Chris Johnsen