How to download individual files from a Github repository – CloudSavvy IT

While Github is most often used to host large code projects, it also acts as a pretty good file host, and sometimes you just want to download a file or two without cloning the entire repo. Github supports this, both from the site and the command line.

Download a single file from the Github site

If you are fine with your web browser, you can download individual files quite easily. Go to the file you want to download and click “Raw:”

This will open a page with a direct link to the file. You can copy / paste from here, but in most browsers you should be able to right-click and select “Save As” to download the file directly.

For code files it can try to save as .txt, which you have to correct manually before or after download.

Downloads from the command line

Page files served from raw.githubusercontent.com, you can download them directly through wget or curl. They are stored in accessible places, so if you know the username, repository and file path, you can download any file on any branch as such:

wget https://raw.githubusercontent.com/username/repository/branch/path/filename.md

If you prefer the Gits API, you can interact with it more directly and download files when you are not sure of the exact file location. You must create a personal access token to use the API with which you can replace “ACCESS_TOKEN” in this script.

curl -H 'Authorization: token ACCESS_TOKEN ' -H 
'Accept: application/vnd.github.v3.raw' -O -L 
https://api.github.com/repos/username/repository/contents/path/filename.md

That /repos/{user}/{repo}/contents endpoint will do different things depending on whether the path points to a folder or a file. If it is a file, it will return metadata about this file:

{
  "type": "file",
  "encoding": "base64",
  "size": 5362,
  "name": "README.md",
  "path": "README.md",
  "content": "encoded content ...",
  "sha": "3d21ec53a331a6f037a91c368710b99387d012c1",
  "url": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
  "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
  "html_url": "https://github.com/octokit/octokit.rb/blob/master/README.md",
  "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/README.md",
  "_links": {
    "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/3d21ec53a331a6f037a91c368710b99387d012c1",
    "self": "https://api.github.com/repos/octokit/octokit.rb/contents/README.md",
    "html": "https://github.com/octokit/octokit.rb/blob/master/README.md"
  }
}

If it is a folder, it will return all files and subfolders in an array:

[
  {
    "type": "file",
    "size": 625,
    "name": "octokit.rb",
    "path": "lib/octokit.rb",
    "sha": "fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
    "url": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit.rb",
    "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
    "html_url": "https://github.com/octokit/octokit.rb/blob/master/lib/octokit.rb",
    "download_url": "https://raw.githubusercontent.com/octokit/octokit.rb/master/lib/octokit.rb",
    "_links": {
      "self": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit.rb",
      "git": "https://api.github.com/repos/octokit/octokit.rb/git/blobs/fff6fe3a23bf1c8ea0692b4a883af99bee26fd3b",
      "html": "https://github.com/octokit/octokit.rb/blob/master/lib/octokit.rb"
    }
  },
  {
    "type": "dir",
    "size": 0,
    "name": "octokit",
    "path": "lib/octokit",
    "sha": "a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
    "url": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit",
    "git_url": "https://api.github.com/repos/octokit/octokit.rb/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
    "html_url": "https://github.com/octokit/octokit.rb/tree/master/lib/octokit",
    "download_url": null,
    "_links": {
      "self": "https://api.github.com/repos/octokit/octokit.rb/contents/lib/octokit",
      "git": "https://api.github.com/repos/octokit/octokit.rb/git/trees/a84d88e7554fc1fa21bcbc4efae3c782a70d2b9d",
      "html": "https://github.com/octokit/octokit.rb/tree/master/lib/octokit"
    }
  }
]

You can then use a JSON parser like jq to extract the URL and download it. To get the depot file list recursive, you need to retrieve the root tree.

RELATED: How to work with JSON on the command line

Leave a Comment