How to sparsely checkout only one single file from a git repository?

How do I checkout just one file from a git repo?


Solution 1:

Originally, I mentioned in 2012 git archive (see Jared Forsyth's answer and Robert Knight's answer), since git1.7.9.5 (March 2012), Paul Brannan's answer:

git archive --format=tar --remote=origin HEAD:path/to/directory -- filename | tar -O -xf -

But: in 2013, that was no longer possible for remote https://github.com URLs.
See the old page "Can I archive a repository?"

The current (2018) page "About archiving content and data on GitHub" recommends using third-party services like GHTorrent or GH Archive.


So you can also deal with local copies/clone:

You could alternatively do the following if you have a local copy of the bare repository as mentioned in this answer,

git --no-pager --git-dir /path/to/bar/repo.git show branch:path/to/file >file

Or you must clone first the repo, meaning you get the full history: - in the .git repo - in the working tree.

  • But then you can do a sparse checkout (if you are using Git1.7+),:
    • enable the sparse checkout option (git config core.sparsecheckout true)
    • adding what you want to see in the .git/info/sparse-checkout file
    • re-reading the working tree to only display what you need

To re-read the working tree:

$ git read-tree -m -u HEAD

That way, you end up with a working tree including precisely what you want (even if it is only one file)


Richard Gomes points (in the comments) to "How do I clone, fetch or sparse checkout a single directory or a list of directories from git repository?"

A bash function which avoids downloading the history, which retrieves a single branch and which retrieves a list of files or directories you need.

Solution 2:

First clone the repo with the -n option, which suppresses the default checkout of all files, and the --depth 1 option, which means it only gets the most recent revision of each file

git clone -n git://path/to/the_repo.git --depth 1

Then check out just the file you want like so:

cd the_repo
git checkout HEAD name_of_file

Solution 3:

If you already have a copy of the git repo, you can always checkout a version of a file using a git log to find out the hash-id (for example 3cdc61015724f9965575ba954c8cd4232c8b42e4) and then you simply type:

git checkout hash-id path-to-file

Here is an actual example:

git checkout 3cdc61015724f9965575ba954c8cd4232c8b42e4 /var/www/css/page.css

Solution 4:

Normally it's not possible to download just one file from git without downloading the whole repository as suggested in the first answer. It's because Git doesn't store files as you think (as CVS/SVN do), but it generates them based on the entire history of the project.

But there are some workarounds for specific cases. Examples below with placeholders for user, project, branch, filename.

GitHub

wget https://raw.githubusercontent.com/user/project/branch/filename

GitLab

wget https://gitlab.com/user/project/raw/branch/filename

GitWeb

If you're using Git on the Server - GitWeb, then you may try in example (change it into the right path):

wget "http://example.com/gitweb/?p=example;a=blob_plain;f=README.txt;hb=HEAD"

GitWeb at drupalcode.org

Example:

wget "http://drupalcode.org/project/ads.git/blob_plain/refs/heads/master:/README.md"

googlesource.com

There is an undocumented feature that allows you to download base64-encoded versions of raw files:

curl "https://chromium.googlesource.com/chromium/src/net/+/master/http/transport_security_state_static.json?format=TEXT" | base64 --decode

In other cases check if your Git repository is using any web interfaces.

If it's not using any web interface, you may consider to push your code to external services such as GitHub, Bitbucket, etc. and use it as a mirror.

If you don't have wget installed, try curl -O (url) alternatively.

Solution 5:

Minimal Guide

git checkout -- <filename>


Ref: https://git-scm.com/docs/git-checkout

Dup: Undo working copy modifications of one file in Git?