Sometimes it’s handy to use curl or wget to download a single file from a GitHub repository. Maybe it’s needed on a server where Git is not installed or it’s not desirable to clone or pull a repo for one file. Or perhaps cloning / pulling the repo locally and copying to the server isn’t ideal or copying and pasting file contents.

For private repositories, authentication adds a little additional work for this – typically the use of an OAuth token and adding an accept header.

GitHub Enterprise

My use case for this was against GitHub Enterprise so I started with a token (with repo scope) I had previously created at http://github.my-company.com/settings/tokens.

My bash curl command then looked as follows, replacing the my- portions with the appropriate values.

curl -H "Authorization: token $TOKEN" \
  -H 'Accept: application/vnd.github.v3.raw' \
  -o my-file.ext \
  -L http://github.my-company.com/api/v3/repos/my-org/my-repo/contents/my-file-path.ext?ref=my-branch

Setting the Token

For my local machine I might set the $TOKEN variable via a dot-file. My initial use case was on a server with a shared account so I didn’t want to leave my token hanging around. For that I set the token variable at the command line, immediately removed that command from bash history, then unset the variable after the curl command. In this case I’m relying on the HISTCMD shell variable set in various Linux distributions to keep track of what the next history entry number will be.

TOKEN=my-token; history -d $((HISTCMD-1)) > /dev/null
# curl
unset TOKEN

Private GitHub Repositories

For a private GitHub.com repo this is largely the same but the URL changes slighty.

curl -H "Authorization: token $TOKEN" \
  -H 'Accept: application/vnd.github.v3.raw' \
  -o my-file.ext \
  -L https://api.github.com/repos/my-username/my-repo/contents/my-file-path.ext?ref=my-branch

Public GitHub Repositories

Downloading from a public GitHub repository can simply use the same URL GitHub.com provides when browsing the repo and clicking the Raw button on a file.

curl https://raw.githubusercontent.com/thnk2wn/rasp-cat-siren/master/siren/Dockerfile \
  -o Dockerfile

In Closing

It may be helpful initially to leave off the file output (-o my-file.ext) just to verify the URL is correct (or tack on && cat my-file.ext) otherwise you might miss that the file just contains Not Found if the wrong URL is supplied.

Some steps may differ depending on GitHub configuration – for example, if two-factor authentication is turned on. https://docs.github.com/en/rest can be referenced for further customization.

The GitHub CLI may be another option to look into. At this point in its Beta, I don’t see an equivalent there at first glance.