Git子模块:添加,使用,删除,更新

2021-02-17 19:42:33

我现在花了一个多月的时间与Git合作。我可以坦白地说,尽管我喜欢Git的很多事情,但我个人发现很多事情对屁股也很痛苦。

子模块在很多情况下都已经成为我这边的荆棘。虽然子模块的概念很简单,但是弄清楚如何实际使用它们可能是一件很麻烦的事情。我之所以说“搞清楚”,是因为并不是所有有关使用子模块的内容都得到了很好的记录。我将介绍两个更难解决的问题:从存储库中删除和更新子模块。

子模块的概念很棒。从本质上讲,它允许您在特定路径下将外部存储库附加到另一个存储库中。为了说明子模块的价值,对我解释如何使用它们可能会有所帮助。

我的专业是处理WordPress主题。基本上,我会为主题开发功能增强。我在完全包含在自己的文件夹中的模块中开发了这些增强功能的代码。这使得代码可以轻松地添加到其他主题中,并且还简化了代码的更新/改进,因为针对特定功能的代码在使用该特定模块的所有主题之间是一致的。

我们产生的每个主题都保存在自己的Git存储库中。此外,我为每个功能模块都创建了一个单独的存储库。我没有直接将功能模块代码直接放入主题存储库中,而是将所需的功能模块存储库添加为子模块。

例如,我们有一个名为FlexxBold的主题。 FlexxBold当前总共包括七个子模块:广告牌,联系页面插件,特色图像,feedburner小部件,文件实用程序,flexx布局编辑器和教程。由于我使用的是子模块,因此可以直接从相关子模块存储库中提取代码,而无需我手动更新每个主题存储库。

如前所述,并非Git中的所有内容都易于使用。为了使用Git子模块,您需要了解四个主要功能。因此,您将需要知道如何添加,使用,删除和更新子模块。我将在下面介绍所有这些用途。

幸运的是,将子模块添加到git存储库实际上非常简单。例如,如果我位于一个名为SampleTheme的新主题的存储库工作目录中,并且需要将Billboard存储库添加到路径lib / billboard,则可以使用以下命令进行操作:

[user @ office SampleTheme] $ git子模块add git @ mygithost:billboard lib / billboard〜/ git_dev / SampleTheme / lib / billboard / .git / remote中初始化的空Git存储库:计算对象:1006,完成。远程:压缩对象:100 %(978/978),完成远程:总计1006(增量631),重用0(增量0)接收对象:100%(1006/1006),408.22 KiB,完成解析增量:100%(631/631) , 完毕。

git submodule add –这只是告诉Git我们正在添加一个子模块。此语法将始终保持不变。

git @ mygithost:billboard –这是要作为子模块添加的外部存储库。确切的语法会因要连接的Git存储库的设置而异。您需要确保具有克隆给定存储库的能力。

lib / billboard –这是将子模块存储库添加到主存储库的路径。

[user @ office SampleTheme] $ git status#在分支master上#要提交的更改:#(使用" git reset HEAD< file> ..."取消登台)##新文件:.gitmodules #新文件:lib / billboard#

请注意,如何创建提供的路径并将其添加到要提交的更改中。此外,还创建了一个名为.gitmodules的新文件。这个新文件包含我们提供的有关新子模块的详细信息。出于好奇,让我们检查一下该新文件的内容:

现在剩下要做的就是提交更改,然后在必要时将提交推送到远程系统。

在存储库中拥有子模块非常好,但如果我查看存储库,我所拥有的只是一个空文件夹,而不是子模块存储库的实际内容。为了用外部存储库中的文件填充子模块的路径,必须首先初始化子模块,然后再更新它们。

注意:这在较新版本的Git中已更改。现在,子模块的存储库将被克隆,其中master已检出。如果该存储库还包含子模块,则必须通过在项目的子模块目录中执行以下步骤来填充子模块的子模块(令人困惑吗?)。

例如,如果您在名为phone-app的项目中工作,则添加一个名为graphics-lib的子模块,而graphics-lib有一个名为renderer的子模块,当您将graphics-lib添加到phone-app时,phone-app / graphics- lib目录将被填充为克隆存储库,但是phone-app / graphics-lib / renderer目录将为空。要填充phone-app / graphics-lib / renderer,首先将目录更改为phone-app / graphics-lib,然后按照以下说明进行操作。

首先,我们需要初始化子模块。我们可以使用以下命令来做到这一点:

[user @ office SampleTheme] $ git子模块更新〜/ git_dev / SampleTheme / lib / billboard / .git / remote中初始化的空Git存储库:计数对象:26,已完成。远程:压缩对象:100%(22/22),已完成远程:总计26​​(增量5),已重用0(增量0)接收对象:100%(26/26),17.37 KiB,已完成解析增量:100%(5/5),已完成子模块路径&#39 ; lib / billboard&#39 ;:已检出' 1c407cb2315z0847facb57d79d680f88ca004332'

如果需要删除子模块会怎样?也许我弄错了。也可能是项目的设计已更改,子模块也需要随之更改。没问题,我只需要运行git submodule rm [submodule path],一切都会很好,对吧?

[user @ office SampleTheme] $ git子模块rm lib / billboarderror:pathspec' rm'与git已知的任何文件都不匹配。您忘了' git add'吗? b8ff8f68eb56938b9b4bf993619218fa848c5848 lib / billboard(1.2.25)

不幸的是,这是错误的。 Git没有内置的方式来删除子模块。希望将来可以解决此问题,因为我们现在必须手动删除子模块。

坚持该示例,我们将从SampleTheme中删除lib / billboard模块。所有说明都将从SampleTheme存储库的工作目录中运行。为了进行此操作,我们需要执行以下操作:

删除.gitmodules文件中子模块的条目。由于lib / billboard是SampleTheme存储库中的唯一子模块,因此我们可以通过运行git rm .gitmodules完全删除该文件。如果lib / billboard不是唯一的子模块,则必须手动修改.gitmodules文件。在vi或您喜欢的文本编辑器中将其打开,然后删除与要删除的子模块相关的三行。在这种情况下,这些行将被删除:

删除.git / config中子模块的条目。此步骤不是绝对必要的,但它可以使您的配置文件保持整洁,并有助于防止将来出现问题。仅当您在存储库中运行git submodule init时,.git / config中子模块的条目才会出现。如果还没有,则可以跳过此步骤。在此示例中,以下行将被删除:

删除为子模块创建的路径。这很容易。只需运行git rm --cached [插件路径]。在此示例中,我将运行git rm --cached lib / billboard。正如我在其他地方看到的那样,请勿在命令末尾加上斜线,因为该命令将失败。例如,如果我运行git rm --cached lib / billboard /,则会收到错误消息:致命:pathspec' lib / billboard /'没有任何文件。

子模块有一个方面,某些方面在首次使用Git子模块时可能无法实现。添加子模块时,子模块的最新提交将存储在主存储库的索引中。这意味着,随着子模块存储库中代码的更新,依赖于子模块的存储库中仍将提取相同的代码。

当您考虑如何针对子模块代码的特定版本对代码进行测试(或至少应进行验证)时,这很有意义,但是在进行更改之前,主存储库的代码可能不适用于新的子模块更新经过测试。

不幸的是,就像删除子模块一样,Git并未明确说明如何将子模块更新为以后的提交。幸运的是,这并不难。

通过运行git submodule init并随后进行git submodule update来初始化存储库的子模块。 [user @ office SampleTheme] $ git子模块initSubmodule' lib / billboard' (git @ mygithost:billboard)已注册路径' lib / billboard' [user @ office SampleTheme] $ git子模块更新〜/ git_dev / SampleTheme / lib / billboard / .git / remote中初始化的空Git存储库:计数对象:26,已完成。远程:压缩对象:100%(22/22),已完成远程:总计26​​(增量5),已重用0(增量0)接收对象:100%(26/26),17.37 KiB,已完成解析增量:100%(5/5),已完成子模块路径&#39 ; lib / billboard&#39 ;:已检出' 1c407cb2315z0847facb57d79d680f88ca004332'

git子模块更新添加的子模块存储库是“无头的”。这意味着它们不在当前分支上。要解决此问题,我们只需要切换到分支即可。在此示例中,这将是master分支。我们使用以下命令进行切换:git checkout master。 [user @ office SampleTheme / lib / billboard] $ git status#当前不在任何分支上。没有提交内容(工作目录干净)[user @ office SampleTheme / lib / billboard] $ git checkout master先前的HEAD位置是b8ff8f6 ... re -ordering切换到分支机构' master'您的分支机构位于' origin / master'之后8次提交,并且可以快速转发。 [user @ office SampleTheme / lib / billboard] $ git status#在分支master上#您的分支位于' origin / master'之后。最多提交8次,并且可以快速转发。#什么都不提交(工作目录干净)

接下来,我们只需要更新存储库以确保我们拥有最新的更新。我们可以通过pull来做到这一点:git pull。 [user @ office SampleTheme / lib / billboard] $ git pullremote:计数对象:31,完成。远程:压缩对象:100%(24/24),完成。远程:总计24(增量15),重用0(增量0) )解压缩对象:完成100%(24/24)。来自mygithost:billboard b8ff8f6..5cab93f master->来源/主服务器* [新标签] 1.2.28-> 1.2.28来自mygithost:billboard * [新标签] 1.2.26-> 1.2.26 * [新标签] 1.2.27-> 1.2.27更新c547e0d..5cab93f快速转发billboard.php | 109 ++++++++++++++++-classes / view_gettingstarted.php | 107个++++++++++++++++类/view_gettingstarted_content.php | 38 +++++ css / admin.css | 26 ++++ history.txt | 22 +++-js / admin.js | 17 +++ lib / updater / get.php | 94 +++++++ ----- lib / updater / history.txt | 9 ++ lib / updater / updater.php | 241 ++++++++++++++++++++ -------------更改了9个文件,519个插入(+),144个删除(-)创建模式100644 classes / view_gettingstarted.php创建模式100644 classes / view_gettingstarted_content.php创建模式100644 css / admin.css创建模式100644 js / admin.js创建模式100644 lib / updater / history.txt

现在切换回存储库的根工作目录。在我们的示例中,我们在两个目录中,因此我们运行cd .. / ...

现在一切就绪,可以提交并推回(如果有要推送到的远程存储库)。如果您运行git status,您会注意到子模块的路径被列为已修改。这是您应该期望看到的。只需添加要提交的路径并进行提交。当您执行提交时,索引将更新子模块的提交字符串。 [user @ office SampleTheme] $ git status#在分支master上#更改但未更新:#(使用" git add ..."更新将提交的内容)#(使用" git签出-..."放弃工作目录中的更改)##修改:lib / billboard(新提交)#未添加更改以提交(使用" git add"和/或&# 34; git commit -a")[user @ office SampleTheme] $ git add lib / billboard [user @ office SampleTheme] $ git status#在分支母版上#提交的更改:#(使用" git reset HEAD ..."降级)##修改:lib / billboard#

在Git的短时间内,我学到了很多东西。 希望将来能看到有关使用Git的更多详细信息。 我发现了一系列陷阱,我应该组织起来并发布。 我还创建了一些非常漂亮的脚本,以帮助我在处理要共享的存储库时自动执行许多操作。 如果您想了解有关Git的任何特定信息,请添加评论或与我联系。