在这种情况下我应该如何使用git

时间:2016-11-11 21:51:16

标签: git

我正在为我的公司创建一个基础php项目,到目前为止它还有用户身份验证,角色,权限,组等。

我的目标是,对于我们开始的每个项目,我们都会复制此基础项目,并添加客户端所需的功能。回到我们的基础项目可能会有一些有趣的功能。

这是我的基本工作流程。我的问题是:如何使用git作为工具来实现这个工作流程?你可以在高级别解释我,或者你有一些链接可以解释如何在这种情况下使用git,或类似的?

我对git的体验减少了创建分支,进行更改然后合并回主人,所以我很难弄清楚如何使用git来实现我的目标。

更新:我觉得我错过了工作流程的重要部分:

目前,我遵循这个项目的工作流程: enter image description here

有一个主分支,我可以随时部署到生产中。每次我开始一个新的sprint(scrum)时,我都会创建一个新的dev分支,对于我想要添加到这个dev分支的每个新功能,我创建了另一个分支(feature branch)。当我完成每个功能后,我将其分支合并回dev分支(dev分支是我们的暂存环境)。在sprint结束时,我将dev分支合并到master分支中。

这个工作流程对我来说很好,我想保留它用于我使用这个基础应用程序的项目。

假设我在这个基础应用程序中发现了一个错误,因此使用它的每个项目都会有相同的错误。我还希望能够将修复程序应用于所有项目。

感谢您的帮助

3 个答案:

答案 0 :(得分:3)

由于此处的其他答案建议使用子模块,我将尝试使用不同的策略并使用分支代替。如果你刚开始使用git,并且不想使用子模块,这种方法会更容易。此方法还假定您的项目只有一个分支。可以使用多个分支,但很难跟踪变化。

初始化一个新项目,并将基础项目添加为远程项目:

git remote add base <url>

这里,base是您分配给遥控器的名称。 现在,创建一个代表基本分支的新跟踪分支:

git branch --track base-project base/master 

这样,当远程仓库中的其他人更新基础分支时,您将能够更新基本分支。

接下来,您需要签出master并更新它,以便它包含基础项目分支中的所有提交。

git checkout master
git rebase base-project

有了这个,您就可以开始在基础项目的基础上构建。如果您还希望基础项目具有一些更改,则可以使用cherry-pick命令单独选择特定提交并将其添加到基础项目分支。确保您的工作树干净且HEAD指向基础项目:

git cherry-pick <commit-hash> 

如果要应用master引入的所有更改:

git cherry-pick ^HEAD master

然后将分支推送到远程存储库:

git push base base-project

答案 1 :(得分:2)

  
    

我的问题是:我如何使用git作为工具来实现这个工作流程?

  

您应该使用子模块。 &#39;子模块&#39;只是一个git项目在另一个得到的项目中,你可以把它看作git的依赖管理器(但不是真的)

您只需要在根文件夹中,然后添加子模块文件夹,该文件夹将是所有其他项目之间共享的公共项目。

git submodule add <url>

现在,当你克隆项目时,你只需要初始化并更新子模块

添加&amp;提交.gitsubmodule文件并在每个项目中使用:

git submodule init
git submodule update

这将从每个子模块的上游获取最新的更改

如果在任何给定时间您决定删除子模块,请完整回答如何操作 What is the current way to remove a git submodule?

enter image description here

答案 2 :(得分:2)

  

我的目标是,对于我们开始的每个项目,我们都会复制此基础项目,并添加客户端所需的功能。回到我们的基础项目可能会有一些有趣的功能。

最佳解决方案取决于基础项目与添加的功能之间的耦合。

如果您的项目设计时考虑了松耦合,并且添加的功能是可以安全添加或删除的独立模块,而不会影响项目的其余部分,那么您可以将每个功能放在Git子模块中,或者您甚至可以将它们创建为单独的组件(独立项目),并使用Composer将它们加载到主项目中。

对于这两种方法,每个功能都将保留在自己的Git存储库中。

每个客户都将获得基础项目,自定义composer.json(及其相应的composer.lock)文件和一些自定义配置文件。

特定于每个客户的文件可以存储在主项目的不同分支上,也可以存储在专用目录的子目录中(没有客户分支)。需要通过部署脚本(或能够为客户准备包的脚本)从那里复制它们(删除其他客户的配置)。

这种方法的优点和缺点:

  • (+)每个功能的代码有一个副本;通过在使用该功能的所有客户的目录上运行composer update,可以轻松地将对一个功能执行的更改,修复和改进传输给所有客户;
  • ( - )它不允许某个功能为两个不同的客户独立发展;为此,必须复制功能项目。

另一方面,如果耦合更紧密并且无法将特征提取为独立的子项目(尽管它们都取决于主项目),那么我将每个特征放在它自己的子目录中(所有这些)位于features/目录中。

主分支(masterdevelop或您使用的任何名称约定)包含功能齐全的项目(主项目和所有功能)。对于每个客户,从主分支开始创建一个新分支。此客户的所有更改都发生在此分支上。首先从features/中删除未提供给客户的功能。

只要您在一个方向上操作主项目中的所有更改,此策略就可以正常工作:将它们应用于主分支,然后将主分支合并到客户分支中。

功能上的更改通常首先应用于一个客户分支,并且在验证之后,可以将它们移植到主分支,然后从那里移植到其他客户的分支。

通过合并无法将功能中的更改从客户分支移植到主分支,因为通常会以不同的方式为每个客户自定义功能。您可能需要仅向主分支应用几个提交(包含修复或功能改进),您可以使用cherry-pick来执行此操作。通常可以使用合并将主要分支中的更改从主分支移植到客户分支,因为主分支应仅包含通用代码,而不包含自定义。