checking out a portion of a git repository

How can I check out just a portion of a Git repository? I have a repository that has several modules, and I only want one of the modules installed on a particular site.

In Subversion, I'd do svn export http://example.com/repository/path/to/module ./module-name.


Solution 1:

As @Chris mentioned, current versions of Git do support sparse checkout.

To convert a local repo to contain only specified directories:

cd <repo/location>
git config core.sparsecheckout true
echo desiredDir/ >> .git/info/sparse-checkout    # repeat to add multiple subdirs (the rest will be removed)

Now, to remove all, but the specified directories:

 git read-tree -mu HEAD             # remove all, but those in .git/info/sparse-checkout

Solution 2:

I think the closest equivalent to svn export would be git archive. You could pull the directory path/to/module from the master branch of a repository and put in the local directory module-name like this:

git archive --remote=url-of-Git-repository --prefix=module-name/ master:path/to/module |
tar xf -

If the remote server does not support archiving, then pull the archive from a local (bare) clone (using a bare clone avoids having another copy of the files in the local repository, if that is important).


However, your use of “check out” implies (to me) that you want to have a functional Git work tree with only some of the files present. One can accomplish this with the “sparse checkout” functionality introduced in Git 1.7.0.

Enable this functionality by

  1. setting the core.sparseCheckout configuration option to “true”*, and
  2. filling in the per-repository $GIT_DIR/info/sparse-checkout file with the patterns for the pathnames to keep**.

    One might use the the low level “skip-worktree bit” in the index*** to manage the sparseness of individual files, but it is probably easier to use the higher level mechanism instead.

There are some gaps in the overall user interface (i.e. there is no easy way say “clone the repository at this URL but only checkout X, Y, and Z”), but it should be enough to get “partial checkout” functionality.

* see “core.sparseCheckout” in the git config manpage
** see “Sparse checkout” in the git read-tree manpage
*** see “Skip-worktree bit” in the git update-index manpage

Solution 3:

https://stackoverflow.com/questions/600079/is-there-any-way-to-clone-a-git-repositorys-sub-directory-only

No, that's not possible in Git.

Implementing something like this in Git would be a substantial effort and it would mean that the integrity of the clientside repository could no longer be guaranteed. If you are interested, search for discussions on "sparse clone" and "sparse fetch" on the git mailinglist.