I always use composer packages in Laravel but I never changed one. This is my first time and I don't want to do it incorrect.
I need to use and change a packages foo/bar
. Everything that follows now is just guessed:
develop
branchcomposer.json
"require": {
//...
"foo/bar": "dev-develop",
},
"repositories": [
{
"type": "vcs",
"url": "https://github.com/thisisme/bar"
}
],
composer update
thisisme/bar
fork in my vendor
folder in foo
.So far so good. Now I can use my own fork.
But currently, as I don't know what is good practice to modify the repo, I cloned the repo to a completely different location. Then I push my changes there and run composer update
in my project to get the changes. But this is a pain.
Do I need to have a sub git in my project in vendor/foo
with
git remote add origin https://github.com/thisisme/bar.git
. Because "git in git" feels wrong and finally is not really working as git commands seem to interact with the "parent git".
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.