将具有特定SHA1的子模块添加到现有的git repo [英] Adding a submodule with a specific SHA1 to an existing git repo

查看:71
本文介绍了将具有特定SHA1的子模块添加到现有的git repo的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

多年来,这个问题已经问了很多遍了,但从未见过实际的答案.

This has been asked quite a few times over the years, but never seen an actual answer.

我想将一些开源代码作为子模块添加到我现有的项目中,但是我只能使用特定的提交SHA1.

I would like to add some open source code to my existing project as a submodule, but I can only use a specific commit SHA1.

我已经建立了一个示例来演示该问题.

I have set up an example to demonstrate the problem.

所以,我的主要项目是:

So, my main project is:

https://github.com/BitvuLtd/myProj 

如您所见,该项目中有一个子模块指向:

As you can see, there is a sub module in this project that points to:

https://github.com/BitvuLtd/strangersPro/tree/bd06980e0d711348bc7831f6421b3c5b27948781

我想指出的是下一次提交该行:

I would like to point that to the next commit up the line:

https://github.com/BitvuLtd/strangersPro/tree/1463dd07645ce4e0450aabaa952b4c657d

我不想要最新的提交,因为它不兼容.

I don't want the most up-to-date commit as it is incompatible.

距离我最近的是能够使用以下方法在子模块的单独克隆副本中检出正确的提交:

The closest I've got is being able to checkout the correct commit is in a separate cloned copy of the submodule using:

git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39

但是如果我在主项目的子模块目录中执行此操作,它将得到:

But if I do that in the submodule directory of the main project, it get:

fatal: reference is not a tree: 1463dd07645ce4e0450aabaa952b4c657d16da39

推荐答案

TL; DR:您需要更新gitlink

为此,您需要将子模块的Git存储库更新为所需的提交(这是一个提交,而不是树),然后在超级项目中运行git addgit commit:

$ cd strangersPro
$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39

然后返回超级项目并git add strangersPro并提交:

then go back to the superproject and git add strangersPro and commit:

$ cd ..
$ git add strangersPro
$ git commit

详细信息

定义:子模块是一个Git存储库(不是一个非常有用的定义,但并非完全是错误).术语子模块"以几种不同的方式使用.通常,子模块"是指一个用作子模块的Git存储库",这是一个糟糕的定义,因为它提出这个问题,但是无论如何,让我们一起解决这个问题. :-)

Details

Definition: a submodule is a Git repository (not a very useful definition, but not exactly wrong). The term "submodule" gets used in several different ways. Typically "submodule" means "a Git repository being used as a submodule", which is a terrible definition since it kind of begs the question, but let's go with that anyway. :-)

定义: superproject 是一个Git存储库,其中至少包含一个子模块.

Definition: a superproject is a Git repository that has at least one submodule in it.

定义: gitlink 是对另一个Git存储库的引用.这样的引用由两部分组成:

Definition: a gitlink is a reference to another Git repository. Such a reference consists of two items:

  • 我们用来命名其他Git特定存储库的名称,
  • (我们假设)存在于其他Git存储库中的特定提交的哈希ID.
  • something by which we name the specific other Git repository, and
  • the hash ID of a specific commit that (we assume) exists in that other Git repository.

要将 new gitlink添加到Git存储库,以使该Git存储库成为包含子模块的超级项目,则必须在某个时候(仅每个子模块一次)运行git submodule add.这将创建或更新翻译表.我们需要此表,因为gitlink中存储的名称是路径名,例如strangersPro.

To add a new gitlink to a Git repository, so that this Git repository becomes a superproject containing a submodule, you must at some point (once only per submodule) run git submodule add. This creates or updates a translation table. We need this table because the name stored in the gitlink is a path name, such as strangersPro.

此表的(文件)名称为.gitmodules,每个子模块包含几行.

The (file) name of this table is .gitmodules, and it contains several lines per submodule.

在这种情况下,已经完成了:有一个.gitmodules文件,其中包含以下几行:

In this particular case, that's already been done: there is a .gitmodules file that has these lines in it:

[submodule "strangersPro"]
    path = strangersPro
    url = https://github.com/BitvuLtd/strangersPro

现在我们有了此文件,其中包含此条目,我们可以创建这些特殊的gitlink条目之一. gitlink分两部分.一个看起来像文件或目录/文件夹的名称,在本例中为strangersPro.另一个是提交哈希ID.

Now that we have this file with this entry in it, we can create one of these special gitlink entries. The gitlink comes in two parts. One looks like a file or directory/folder name—in this case, strangersPro. The other is a commit hash ID.

路径名strangersPro很容易看到.提交哈希ID不太容易看到.但是gitlink条目同时提供了两者.同时,.gitmodules文件为您的Git提供了一种克隆单独 Git存储库的方法,即子模块:.gitmodules文件表示,要与strangersPro一起使用,您的Git应该在strangersPro目录下克隆另一个存储库(子模块本身).

The path name, strangersPro, is easy to see. The commit hash ID is not as easy to see. But the gitlink entry provides both at the same time. Meanwhile the .gitmodules file provides the way for your Git to know to clone a separate Git repository, i.e., the submodule: the .gitmodules file says that to work with strangersPro, your Git should clone another repository—the submodule itself—under the strangersPro directory.

现在,您的超级项目中有第二个Git存储库(在strangersPro中),您的超级项目的Git在子模块中运行了另一个git checkout.第二个git checkout使用gitlink中的提交哈希来检出一个特定的提交.

Now that your superproject has a second Git repository inside it (in strangersPro), your superproject's Git runs another git checkout inside the submodule. This second git checkout uses the commit hash in the gitlink to check out the one specific commit.

现在您已有一个gitlink,您的任务将变为:更改哈希ID .

Now that you have an existing gitlink, your task becomes: change the hash ID.

执行此操作的方式与更改存储库中的任何文件的方式几乎相同:在运行git add之后进行一次新提交.也就是说,将gitlink检入到每个提交中的方式与将任何其他文件(如README.md)检入到每个提交中的方式相同.

You do this much the same way you change any file in a repository: by making a new commit after running git add. That is, the gitlink is checked in to every commit in the same way that any other file, like README.md, is checked in to every commit.

但是,哈希ID只是大的废话数字,您不能直接编辑"gitlink文件"(仅保存在超级项目的索引/临时区域中,而不是常规的工作树文件中).因此,要更新gitlink,您必须首先导航到子模块本身:

Hash IDs, though, are just big nonsense numbers, and you can't edit the "gitlink file" directly (it's saved only in the superproject's index / staging-area, not a regular work-tree file). Hence, to update the gitlink, you must first navigate into the submodule itself:

$ cd strangersPro

这个子模块本身就是一个Git存储库,就像其他任何Git存储库一样.这意味着您可以运行git checkoutgit statusgit branchgit addgit commit等.但是,您要做的只是签出一个新的特定提交.您将需要大的废话哈希ID.幸运的是,您在上面提供了此代码:它是1463dd07645ce4e0450aabaa952b4c657d16da39.

This submodule is itself a Git repository, just like any other Git repository. That means you can run git checkout and git status and git branch and git add and git commit and so on. But all you want to do here is check out a new specific commit. You will need the big nonsense hash ID. Fortunately you provided this above: it's 1463dd07645ce4e0450aabaa952b4c657d16da39.

$ git checkout 1463dd07645ce4e0450aabaa952b4c657d16da39

现在,您的子模块在此提交时具有分离的HEAD(而不是以前的旧分离的HEAD).

Now your submodule has a detached HEAD at this commit (instead of the old detached HEAD it had before).

现在您浏览子模块存储库的 out ,回到超级项目.现在,您可以git add子模块 path .您的超级项目git将从子模块中读取当前的提交哈希ID,并将其添加到您的超级项目的索引中:

Now you navigate out of the submodule repository, back to the superproject. You can now git add the submodule path. Your superproject git will read the current commit hash ID out of the submodule and add that to your superproject's index:

$ cd ..
$ git add strangersPro

现在您终于可以提交超级项目了,以现有名称记录新的哈希ID.

Now you are finally ready to commit in the superproject, recording the new hash ID under the existing name.

这篇关于将具有特定SHA1的子模块添加到现有的git repo的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆