Git Tip: Exclude All But One Vendor Package
I am currently working on a project where I am pulling in several php packages via Composer. One of the packages doesn’t quite do everything I need it to. There have been a couple of pull requests that do what I need, but those pull requests haven’t been merged into the main package, and I’m not sure if they ever will be.
While I hate hacking a 3rd party package that I am using, I really need this additional functionality. So I decided to incorporate a modified version of one of the pull requests into the package in my project. Since I’m doing this, I can’t really pull the package in via Composer because then if I have to set up the project on another computer or if someone else clones the project, they won’t have my changes. So I need to put my version of the package into the git repository for the project, but I don’t want to include any of the other packages from any of the other vendors in my git repository.
So I took to the interwebs to try to find a solution. But nothing that I found was working the way I needed it to for this project. After some trial and error, I finally found a way to do what I needed to. I wanted to share in case anyone else needs to do this (but more for the situation where I need to do this for another project and I can’t remember the project I initially did this for 😀 ).
As I said, when you’re using Composer to pull in packages, you generally want to exclude the /vendor/ folder from your git repository. In order to include a specific package from a specific vendor, you need to utilize .gitignore files.
1) In the .gitignore file in your project root, add the following.
/vendor/* !VENDORNAME/
This tells git to ignore everything in the /vendor/ directory EXCEPT for the VENDORNAME directory.
2) Create a .gitignore file in the directory for the vendor that the package is under (/vendor/VENDORNAME/.gitignore) and add the following to it.
*/ !PACKAGE-NAME !PACKAGE-NAME/*
This tells git to ignore everything in the current directory EXCEPT for the PACKAGE-NAME directory and the files and folders in that directory.
If the package that you’re including in your git repository has more than one level of directories, you will need to add additional items to the .gitignore to include the files and directories at those deeper levels.
*/ !PACKAGE-NAME !PACKAGE-NAME/* !PACKAGE-NAME/*/* !PACKAGE-NAME/*/*/*
So if you have a package (called foobar under the hightechredneckwoman vendor) with the following structure, everything in the foobar package will be included in the git repository.
/vendor/hightechredneckwoman/
/vendor/hightechredneckwoman/foobar/
/vendor/hightechredneckwoman/foobar/config/
/vendor/hightechredneckwoman/foobar/src/
/vendor/hightechredneckwoman/foobar/tests/
/vendor/hightechredneckwoman/foobar/tests/config/
/vendor/hightechredneckwoman/foobar/tests/database/
/vendor/hightechredneckwoman/foobar/tests/database/migrations/
/vendor/hightechredneckwoman/foobar/tests/models/
If anyone knows of a way to include everything in the .gitignore in the project root, please share in the comments.Â