Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I clone a subdirectory only of a Git repository?

I have my Git repository which, at the root, has two sub directories:

/finisht /static 

When this was in SVN, /finisht was checked out in one place, while /static was checked out elsewhere, like so:

svn co svn+ssh://[email protected]/home/admin/repos/finisht/static static 

Is there a way to do this with Git?

like image 482
Nick Sergeant Avatar asked Mar 01 '09 16:03

Nick Sergeant


People also ask

Can I clone part of a repository git?

Partial clone is a performance optimization that “allows Git to function without having a complete copy of the repository. The goal of this work is to allow Git better handle extremely large repositories.” Git 2.22. 0 or later is required.

How do I download a subdirectory from github?

Step1: Input github url to the field at the top-right. Step2: Press enter or click download for download zip directly or click search for view the list of sub-folders and files. Step3: Click "Download Zip File" or "Get File" button to get files.


1 Answers

What you are trying to do is called a sparse checkout, and that feature was added in git 1.7.0 (Feb. 2012). The steps to do a sparse clone are as follows:

mkdir <repo> cd <repo> git init git remote add -f origin <url> 

This creates an empty repository with your remote, and fetches all objects but doesn't check them out. Then do:

git config core.sparseCheckout true 

Now you need to define which files/folders you want to actually check out. This is done by listing them in .git/info/sparse-checkout, eg:

echo "some/dir/" >> .git/info/sparse-checkout echo "another/sub/tree" >> .git/info/sparse-checkout 

Last but not least, update your empty repo with the state from the remote:

git pull origin master 

You will now have files "checked out" for some/dir and another/sub/tree on your file system (with those paths still), and no other paths present.

You might want to have a look at the extended tutorial and you should probably read the official documentation for sparse checkout and read-tree.

As a function:

function git_sparse_clone() (   rurl="$1" localdir="$2" && shift 2    mkdir -p "$localdir"   cd "$localdir"    git init   git remote add -f origin "$rurl"    git config core.sparseCheckout true    # Loops over remaining args   for i; do     echo "$i" >> .git/info/sparse-checkout   done    git pull origin master ) 

Usage:

git_sparse_clone "http://github.com/tj/n" "./local/location" "/bin" 

Note that this will still download the whole repository from the server – only the checkout is reduced in size. At the moment it is not possible to clone only a single directory. But if you don't need the history of the repository, you can at least save on bandwidth by creating a shallow clone. See udondan's answer below for information on how to combine shallow clone and sparse checkout.


As of git 2.25.0 (Jan 2020) an experimental sparse-checkout command is added in git:

git sparse-checkout init # same as:  # git config core.sparseCheckout true  git sparse-checkout set "A/B" # same as: # echo "A/B" >> .git/info/sparse-checkout  git sparse-checkout list # same as: # cat .git/info/sparse-checkout 
like image 111
Chronial Avatar answered Sep 26 '22 07:09

Chronial