How do I use git to checkout just the files and their parent folders that have a given file extension?
We would be using this inside 开发者_高级运维an Ant build script running under TeamCity.
This is what I did and it works pretty well. I had a need to edit only the markdown (extension .md) files within a project.
#clone as usual
git clone https://github.com/username/repo.git myrepo
#change into the myrepo directory that was just created
cd myrepo
#turn off tracking for everything
#this allows us to start pruning our working directory without the index
#being effected, leaving us only with the files that we want to work on
git ls-files | tr '\n' '\0' | xargs -0 git update-index --assume-unchanged
#turn on tracking for only the files that you want, editing the grep pattern
# as needed
#here I'm only going to track markdown files with a *.md extension
#notice the '--no-assume-unchanged' flag
git ls-files | grep \\.md | tr '\n' '\0' | xargs -0 git update-index --no-assume-unchanged
#delete everything in the directory that you don't want by reversing
#the grep pattern and adding a 'rm -rf' command
git ls-files | grep -v \\.md | tr '\n' '\0' | xargs -0 rm -rf
#delete empty directories (optional)
#run the following command. you'll receive a lot of 'no such file or
#directory' messages. run the command again until you
#no longer receive such messages.you'll need to do this several times depending on the depth of your directory structure. perfect place for a while loop if your scripting this
find . -type d -empty -exec rm -rf {} \;
#list the file paths that are left to verify everything went as expected
find -type f | grep -v .git
#run a git status to make sure the index doesn't show anything being deleted
git status
you should see:
# On branch master
nothing to commit, working directory clean
done!
Now you can work with these files just as you would as if you had everything checked out, including doing a pull and push to a remote and it will only update the files that you checked out without deleting the rest.
(By "checkout" I assume that you mean "clone" in git terminology - i.e. you currently don't have a copy of the repository, and need to get some files from a remote repository.)
The short answer is that you can't.
You can, with some restrictions, do shallow clones in git (only getting the last few versions), but you can't easily do narrow clones (grabbing only some parts of the repository, such as one subdirectory, or only files that match particular criteria).
In a way, this is actually a feature of git as a distributed version control system: when you've cloned a repository you know that you've got the complete history, all the branches, and everything you need to work on the code completely standalone.
There are, of course, various ways around this, for example:
- you could use
git archive --remote=<repo>
to fetch a tar archive of the remote repository, and pipe that totar -x --wildcards --no-anchored '*.whatever'
- just clone the complete repository somewhere else locally, and have your build script update it and copy over just the files you want
- etc. etc.
精彩评论