April 29, 2022 From rOpenSci (https://deploy-preview-488--ropensci.netlify.app/blog/2022/04/29/don-t-lose-your-head-over-default-branches/). Except where otherwise noted, content on this site is licensed under the CC-BY license.
Did you know that GitHub lets you refer to the default branch of any repository by substituting the branch name with HEAD
in the url? This is a very useful trick to write robust code that works regardless of whether the default branch is called main
or master
, and will keep working when the default branch gets renamed at some point.
While git has no “default” branch, online code platforms such as GitHub need to define a default for the branch that someone sees when they look at code online. While the community standard for the default branch is now becoming main instead of master1, and while the switch for any repo is rather easy and is well supported by usethis, for a while (forever) there will still be repos with different default branches in the wild.2 Especially as nothing prevents you from using any other name for the default branch (although this could trip up collaborators).3
So, what to deal with the existence of different possible default branches?
usethis::git_default_branch()
, is very handy.gert::git_remote_ls()
will help show you remote references. The symref for ref contains the default branch name.gert::git_remote_ls() |>
head() # another useful thing named head
#> ref symref
#> 1 HEAD refs/heads/main
#> 2 refs/heads/1password <NA>
#> 3 refs/heads/2fa <NA>
#> 4 refs/heads/email <NA>
#> 5 refs/heads/fix_author_links <NA>
#> 6 refs/heads/footnotes <NA>
#> oid
#> 1 2ef29132be682883d1c12a957c38e1fa6599898f
#> 2 e4f3ef36c453dd2ede5a091c7d3f5f32c609caca
#> 3 7461f15e81651d5bbf6dcab078801cfa35e2f039
#> 4 6f8c849ef325dc597e819bffbd8829afa05ae414
#> 5 2f328db8fc6ce94caa50ddde7a0b021178818d8f
#> 6 f552c2dcac79228e929e65975c52484f5655577c
gert::git_remote_info()
shows the head for a given remote:
gert::git_remote_info("origin")
#> $name
#> [1] "origin"
#>
#> $url
#> [1] "git@github.com:ropensci/roweb3.git"
#>
#> $push_url
#> NULL
#>
#> $head
#> [1] "refs/remotes/origin/main"
#>
#> $fetch
#> [1] "+refs/heads/*:refs/remotes/origin/*"
#>
#> $push
#> character(0)
https://github.com/<owner>/<repo>/tree/<default-branch>/<path>
where you need to know what the default branch is, you can link to https://github.com/<owner>/<repo>/tree/HEAD/<path>
that will always point to the latest version of the path in the default branch. Similarly, for raw content (to download), you can use links à la https://github.com/<owner>/<repo>/raw/HEAD/<path>
.In conclusion, master or main? Hit the nail on the HEAD. 😉
For more context on Terminology, Power and Oppressive Language see for instance https://tools.ietf.org/id/draft-knodel-terminology-00.html ↩︎
Actually, this post was the occasion to change the default branch for the source of this website! ↩︎
Some repos only have a branch called gh-pages
(e.g. everything under https://github.com/ropensci-docs), in which case that is the default branch. ↩︎