8

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.

4

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
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

2
  • I don't need the work tree (svn export exports a non-working copy for production use). What do module-1 etc. correspond to? Folders within the repository? – ceejayoz May 19 '10 at 1:12
  • I rewrote the git archive example to better parallel your SVN example. But in answer to your question, yes module-1, module-2, and file-a were all examples of pathnames of files stored in the tree referenced by the commit referenced by the ref master in the repository. The new example puts the directory specification directly into the tree-ish argument so that it could use the --prefix option to extract a directory from the repository directly into a local directory of a different name. – Chris Johnsen May 19 '10 at 4:43
1

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.

2
  • Yeah. A rather baffling omission, if you ask me. I'm probably going to wind up using a checkout to a directory and symlinks to it from my web directory. I'd love to break it out into separate repositories, but Github charges per-repository for private ones. – ceejayoz May 18 '10 at 19:44
  • 6
    Git 1.7.0 introduced sparse checkouts. – Chris Johnsen May 18 '10 at 21:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.