如何在fork的vendor文件夹中使用git?

3
我通常在Laravel中使用composer包,但从未更改过其中任何一个。这是我第一次尝试,我不想出错。
我需要使用并更改一个名为foo/bar的包。接下来的所有内容都是猜测:
  1. 我fork了这个仓库
  2. 我创建了一个develop分支
  3. 我将vcs添加到了我的composer.json文件中
  "require": {
    //...
    "foo/bar": "dev-develop",
  },
  "repositories": [
    {
      "type": "vcs",
      "url": "https://github.com/thisisme/bar"
    }
  ],
  1. composer update(更新依赖包)
  2. 现在,thisisme/bar 的 fork 版本已经在 foovendor 文件夹中了。

到目前为止一切顺利。现在我可以使用自己的 fork 版本了。

但是,由于我不知道修改 repo 的正确做法是什么,所以我将其克隆到了完全不同的位置。然后我将更改推送到那里,并在我的项目中运行 composer update 命令以获取更改。但这很麻烦。

我需要在 vendor/foo 中创建一个子 Git,然后使用命令 git remote add origin https://github.com/thisisme/bar.git 吗?因为“Git 中的 Git”感觉不太对,而且最终似乎并没有真正起作用,因为 Git 命令似乎会与“父 Git”交互。


你可以在沙盒中有两个远程仓库。使用 git remote add myfork <url> 命令,例如,如果原始仓库已经是 origin,则添加你的 fork 仓库,然后当你推送或拉取时,只需指定你想要交互的远程仓库,即 originmyfork(以我的示例为例)。这不是一个子 git,而是两个平行的远程仓库,你可以根据需要分别与它们进行通信。 - joanis
但是我将整个 Laravel 项目推送到包中。我希望将包与 Laravel 项目分开。 - PeterPan
3个回答

3

虽然VonCs answer关于git的回答是正确的,但我不确定git子模块支持是否与composer(1) vendor目录对于来自VCS仓库的包的支持相符。至少我没有进行过太多实验,当我使用一个带有VCS git仓库的composer配置时,我通常不需要那个1

虽然composer(1)支持git作为供应商包,但它是在仓库级别上,也就是说,你可以有自己的包仓库(就像你在问题中所配置的那样),然后composer负责更新(或警告本地更改)。

composer(1)通过其自己的远程支持这一点,用于包(非裸克隆)的克隆(在source安装中,继续阅读)。

所以,是的,你描述的("但这很痛苦。")只要你不利用它来获益。当你开发你的(克隆的)包时,你不需要一直运行composer update


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

一个具有两个Git仓库的Composer项目。
这就是为什么我认为"git in git"不应该感到奇怪。与git子模块类似,git非常支持它。默认情况下,它甚至在父项目中跟踪当前修订版(更改)的子项目,但没有远程信息-因为它是本地的(gitlink)。
你看不到这个想法,因为在树中,gitlink将位于vendor/foo/bar,通常(并且假设)vendor被忽略了,因此主项目中没有对vendor/foo/bar/.git进行版本跟踪-但在子项目中有。
这不是问题,因为Composer会代替你管理那个git子项目(初始克隆和进一步的检出),以满足你的主项目需求。
而且git也意识到这是一个不同的项目。
你应该能够进入vendor文件夹内的软件包目录(vendor/foo/bar)并在那里配置你的远程。然后你可以在该项目内工作,git(1)将在那里工作,而不是在父存储库中。
为了让composer(1)能够正常工作,重要的是你要配置composer以优先选择该存储库的源代码安装变体。这是preferred-install选项,你可以专门为你的存储库进行配置。
{
    "config": {
        "preferred-install": {
            "foo/bar": "source"
        }
    }
}

从您提问的措辞来看,我认为您尚未进行配置。
这是有点重要的,因为只有使用“源”安装时,在vendor/foo/bar中将有一个(非裸)git克隆,因此在包文件夹中的整体git配置位于vendor目录中(由于您已将Github配置为存储库源,并且composer默认优化为采用dist版本,如果我没记错的话)。
在您将配置更改为“源”安装并更新后,cd进入vendor/foo/bar,然后运行git remote -v。现在应该显示该软件包的“composer”远程。
由于您使用的是develop分支,因此可以在本地添加更改,但请注意,在再次使用composer更新之前,您还需要将它们推送到远程存储库(Github),因为虽然您现在使用git开发foo/bar软件包,在主项目中您使用composer来管理依赖项。
这是使用Github而不是更接近工作地点的配置在薪资单上的价格,但至少在本地,您可以使用“git in git”处理包。
通常情况下很简单。由于管理两个而不是一个存储库,因此会产生一项总费用,但是对于这种composer项目[仅composer版本化供应商文件夹]无法防止。
注意:如果开发时间超过几个小时,将新的Git子项目包含在父项目的备份例程中也可能是有意义的,这样当您删除文件夹vendor/foo/bar时,其中有一个(本地)Git存储库和工作树的备份。但是,这取决于项目配置,并且是您自己的责任。

从版本控制系统仓库加载软件包中,Composer文档中也概述了一些提示的工作流程。


1 有一种针对composer项目的设置,其中vendor本身处于git版本控制下,这样git子模块可以很好地工作,但这很可能不是你的项目采用的设置,所以在本答案中我将跳过它。


1
同意:在自定义存储库上使用VCS存储库是正确的方法。正如您所提到的,它需要在拉取/推送/组合时采用严格的方法。另一件事是VCS存储库可能是私有的。因此,对于像AWS EBS这样的CI / CD,您需要额外的SSH密钥存储和部署操作,以便composer可以拉取它。此外,在没有composer.lock的情况下进行推送时要小心,在foo / bar中使用新文件,这些文件在您的Laravel应用程序中使用,并且您的CI管道只执行“composer install”。没有锁定,composer install会检出旧的foo / bar,并且自动加载程序生成将抛出异常,因为您的应用程序尝试使用它。 - Mtxz
我会选择John Zwarthoed的答案,因为对我来说似乎更直接,但我会接受你的答案,因为我认为这将是更通用的更好方法。 - PeterPan
@PeterPan:是的,谢谢你。这里的方法应该与Docker挂载兼容(请注意文件权限,也许从只读挂载开始,这样您就不会意外地在容器环境中修改项目文件和依赖项)。并且在使用git处理vendor内部时,评论中遗漏了提示composer status -vv - hakre

2
如果您正在使用Sail或docker-compose,并且将vendor目录中的foo/bar项目链接仅是“能工作”的临时解决方案,那么您可以将其添加为卷链接。这通常是我所做的。
例如:我正在~/projects/my-project上开发my-project,在~/projects/bar中克隆了foo/bar存储库。
然后在docker-compose.yml中,我可以添加该卷:
volumes:
      - .:/var/www/html
      - ../bar:/var/www/html/vendor/foo/bar

再次强调,以下内容基于使用 Docker 的假设,但是我认为现在几乎所有人都在使用它。


我使用Docker,非常喜欢这种方法。你会进入foo/bar包进行提交更改吗? - PeterPan
1
不,通常我会在我的IDE中的不同项目选项卡中打开foo/bar - John Zwarthoed

1
我需要在我的项目中的vendor/foo目录下添加一个子git,并使用git remote add origin https://github.com/thisisme/bar.git吗? 这可以通过submodule实现,它允许您的父Git存储库仅存储对另一个存储库的引用。您可以使用git submodule add来实现这一点。因此,git clone --recurse-submodule将克隆您的项目,并将子模块Git存储库一起克隆,并检出到您先前提交的确切引用。

这意味着即使我的vendor文件夹(其中包含分支)被.gitignore忽略,它也不会与“父”git产生交互? - PeterPan
1
@PeterPan 是的,.gitignore 不会影响其他仓库(嵌套或父级)。 - VonC
我尝试过这个,但是它会将子模块添加到根目录。这对我来说不起作用,因为我需要将其放在我的供应商文件夹中,以便与composer一起使用。 - PeterPan
@PeterPan 在 git submodule add 中,它会将子模块添加到您指定的路径中。它不必是根文件夹。 - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接