Checkout subdirectories in Git?

One thing I don't like about sparse checkouts, is that if you want to checkout a subdirectory that is a few directories deep, your directory structure must contain all directories leading to it.

How I work around this is to clone the repo in a place that is not my workspace and then create a symbolic link in my workspace directory to the subdirectory in the repository. Git works like this quite nicely because things like git status will display the change files relative to your current working directory.


Sparse checkouts are now in Git 1.7.

Also see the question “Is it possible to do a sparse checkout without checking out the whole repository first?”.

Note that sparse checkouts still require you to download the whole repository, even though some of the files Git downloads won't end up in your working tree.


git clone --filter from git 2.19 now works on GitHub (tested 2020-09-18, git 2.25.1)

This option was added together with an update to the remote protocol, and it truly prevents objects from being downloaded from the server.

To clone only objects required for d1 of this repository: https://github.com/cirosantilli/test-git-partial-clone I can do:

git clone \
  --depth 1 \
  --filter=blob:none \
  --no-checkout \
  https://github.com/cirosantilli/test-git-partial-clone \
;
cd test-git-partial-clone
git checkout master -- d1

I have covered this in more detail at: Git: How do I clone a subdirectory only of a Git repository?


There is no real way to do that in git. And if you won’t be making changes that affect both trees at once as a single work unit, there is no good reason to use a single repository for both. I thought I would miss this Subversion feature, but I found that creating repositories has so little administrative mental overhead (simply due to the fact that repositories are stored right next to their working copy, rather than requiring me to explicitly pick some place outside of the working copy) that I got used to just making lots of small single-purpose repositories.

If you insist (or really need it), though, you could make a git repository with just mytheme and myplugins directories and symlink those from within the WordPress install.


MDCore wrote:

making a commit to, e.g., mytheme will increment the revision number for myplugin

Note that this is not a concern for git, if you do decide to put both directories in a single repository, because git does away entirely with the concept of monotonically increasing revision numbers of any form.

The sole criterion for what things to put together in a single repository in git is whether it constitutes a single unit, ie. in your case whether there are changes where it does not make sense to look at the edits in each directory in isolation. If you have changes where you need to edit files in both directories at once and the edits belong together, they should be one repository. If not, then don’t glom them together.

Git really really wants you to use separate repositories for separate entities.

submodules

Submodules do not address the desire to keep both directories in one repository, because they would actually enforce having a separate repository for each directory, which are then brought together in another repository using submodules. Worse, since the directories inside the WordPress install are not direct subdirectories of the same directory and are also part of a hierarchy with many other files, using the per-directory repositories as submodules in a unified repository would offer no benefit whatsoever, because the unified repository would not reflect any use case/need.