Use PHP Composer to Clone Git Repo

Use PHP composer to clone git repo

At the time of writing in 2013, this was one way to do it. Composer has added support for better ways: See @igorw 's answer

DO YOU HAVE A REPOSITORY?

Git, Mercurial and SVN is supported by Composer.

DO YOU HAVE WRITE ACCESS TO THE REPOSITORY?

Yes?

DOES THE REPOSITORY HAVE A composer.json FILE

If you have a repository you can write to: Add a composer.json file, or fix the existing one, and DON'T use the solution below.

Go to @igorw 's answer

ONLY USE THIS IF YOU DON'T HAVE A REPOSITORY
OR IF THE REPOSITORY DOES NOT HAVE A composer.json AND YOU CANNOT ADD IT

This will override everything that Composer may be able to read from the original repository's composer.json, including the dependencies of the package and the autoloading.

Using the package type will transfer the burden of correctly defining everything onto you. The easier way is to have a composer.json file in the repository, and just use it.

This solution really only is for the rare cases where you have an abandoned ZIP download that you cannot alter, or a repository you can only read, but it isn't maintained anymore.

"repositories": [
{
"type":"package",
"package": {
"name": "l3pp4rd/doctrine-extensions",
"version":"master",
"source": {
"url": "https://github.com/l3pp4rd/DoctrineExtensions.git",
"type": "git",
"reference":"master"
}
}
}
],
"require": {
"l3pp4rd/doctrine-extensions": "master"
}

Clone git repository via composer

The respositories section is only to define packages that are not present in the packagist.org database, but it is present on a 'source control'.

So, it is like you tell composer in your composer.json that there is a package which is source controlled, and here are the details where you get it from, by defining url .. etc.

But that is not enough, because that is only definition and not consuming (downloading) the package. In order to do so, you need to add it to your require section as well.

{
"repositories": [
{
"type": "vcs",
"url": "https://bitbucket.org/yuriikrevnyi/bitrix-teil-framework"
}
],
"require": {
"mockery/mockery": "dev-master@dev",
"phpunit/phpunit": "3.7.*",
"yuriikrevnyi/bitrix-teil-framework": "*"
}
}

How to perform shallow clone using Composer?

Shallow cloning using Composer isn't officially supported (without any patching) as the git parameters are hardcoded.

There is already a feature request to add this: Add support for git shallow clones. However implementing this feature can cause some issues (such as not reaching the locked commits if the depth is not so high@stof and other).

Furthermore there is a pull request which attempts to implement shallow clones by adding an extra --git-clone-depth parameter (tests shows some good results). However the change has been abandon due to faster git clones using cache.


For the quick hack, it's possible to edit git parameters in doDownload() in src/Composer/Downloader/GitDownloader.php, e.g. by changing --depth 1 --single-branch in this line:

$command = 'git clone --no-checkout ...'

Or find the way to apply depth 1 setting into git config.


The easiest workaround (without any hacks) for bigger repositories is just to increase the timeout by specifying the variable like:

COMPOSER_PROCESS_TIMEOUT=0 composer install

How to add private github repository as Composer dependency

Work with private repositories at GitHub and BitBucket:

JSON

{
"require": {
"vendor/my-private-repo": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "git@bitbucket.org:vendor/my-private-repo.git"
}
]
}

The only requirement is the installation of SSH keys for a git client.

Docs

How to use composer to install part of a git repository?

Given the answer to "Is there any way to clone a git repository's sub-directory only?" Is "No" , and sub directory checkout functionality would be required by composer to satisfy the desired functionality, then I would suggest the best composer could do was checkout the whole thing and then delete what you didnt want.

In short: Not Possible.

The longer answer:
is that git can do a sparse checkout so in theory composer could someday support that feature. You can use the autoload field to only load the section of code you want (ie, not load the whole lib).

Force composer to download git repo instead of zip

The quickest solution is to run install or update with the option --prefer-source

php composer.phar install --prefer-source

In this way git clone will be used for all dependencies, I don't know if there's a setting to limit to one dependency only.

How to use git in vendor folder of fork?

While VonCs answer is correct regarding git, I'm not certainly sure that git submodule support is well aligned with composer(1) vendor dir for packages from a VCS repository. At least I have not experimented much with it and when I use a composer configuration with a VCS git repository, I normally don't need that1.

While composer(1) has support for git for vendor packages, it is on repository level, that is, you can have your own repository for your package (as you have configured it shown in your question) and then composer takes care of updating (or giving a warnings about local changes).

composer(1) supports this with its own remote for the packages (non-bare) clone (in the source install, read on).

So yes, what you describe ("But this is a pain."), is as long as you don't use it to your benefit. While you develop your (cloned) package, you don't need to run composer update all the time.



.git
composer.json
vendor/foo/bar/.git

A Composer project with two Git repositories


This is why IMHO "git in git" must not feel wrong. Similar to git sub-modules, git supports this very well. By default it even keeps track in the parent project of the current revision (changes) of the sub-project but without having the information of the remote - as it is local (gitlink).

You won't see this thought as within the tree, the gitlink would be at vendor/foo/bar and commonly (& given that) vendor is git ignored, no version tracking in the main project for vendor/foo/bar/.git - but there in the sub-project.

This is not a problem as Composer manages that git sub-project for you (the initial clone and further checkouts) in terms of your main project.

And git realizes it is a different project.

You should be able to cd into the package directory within the vendor folder (vendor/foo/bar) and configure your remote(s) there. You can then work within that project and git(1) will work there and not within the parent repository.

To have this work with composer(1) it is important that you configure composer to prefer the source install variant for that repository. This is the preferred-install option and you can configure it for your repository specifically.

{
"config": {
"preferred-install": {
"foo/bar": "source"
}
}
}

From the wording in your question, I assume that you have not yet configured it.

And this is somewhat important as only with the source install, there will be a (non-bare) git clone in vendor/foo/bar and therefore the git checkout with the overall git configuration within the packages folder in the vendor directory (as you have Github configured as the repository source and composer optimizes to take the dist version by default IIRC).

After you changed your configuration to the source install and updated it, cd into vendor/foo/bar and then run git remote -v. It now should show you the "composer" remote(s) for that package.

As you use the develop branch, you can add changes locally but mind the gap that you would also need to push them to the remote repository (Github) before you use composer again to update (at least) that foo/bar package - as while you use git for the development of the foo/bar package now, in your main project you use composer to manage the dependency.

This is the price you have on the payroll using Github instead of a configuration that is more near to the place of work, but at least locally, you can handle the package with "git in git".

This is normally straight forward. One overall price remains thought, due to managing two instead of one repository but that you can't prevent with this kind of composer project [composer only versioned vendor folder]).

Note: If development takes longer than a few hours, it may also make sense to include the new Git sub-project in the backup routine of your parenting project, so that when you remove the folder vendor/foo/bar you have a backup of the (local) Git repository and working tree in it. However, this depends on the project configuration and is your own responsibility.


A bit of a workflow with some hints is also outlined in the composer documentation in Loading a package from a VCS repository.


1 There is a type of setup for a composer project where vendor itself is under git version control, with that git sub-modules can work (very well), but this is most likely not the kind of setup you have for your project, so I skip it for this answer.



Related Topics



Leave a reply



Submit