简体   繁体   English

Git 子模块:如何知道子模块的提交/标签

[英]Git Submodules: how to know the commit/tag of the submodule

due to company policies, we have very little tools in the toolbelt.由于公司政策,我们的工具带中的工具很少。 I'm stuck with using Git for a number of things where another tool would do the work better, faster.我坚持使用 Git 来处理许多其他工具可以更好、更快地完成工作的事情。

I need a specific dll in my project and the fastest way to get it was found to add a second repository as a submodule.我在我的项目中需要一个特定的 dll 并且找到它的最快方法是添加第二个存储库作为子模块。 I'm in the testing department, so I don't need the latest dll, nor the stable branch of the dll.我在测试部门,所以我不需要最新的 dll,也不需要 dll 的稳定分支。 I need a specific version of said dll, and I need fine control over it.我需要一个特定版本的 dll,我需要对其进行精细控制。

Luckily, I can use tags to navigate to the specific version.幸运的是,我可以使用标签导航到特定版本。 By git checkout <tag> I send the submodule in detached head and I can freeze the information with a commit of the superproject.通过git checkout <tag>我将子模块发送到分离的头部,我可以通过提交超级项目来冻结信息。 Running git status doesn't explicitly tell me where I am with the submodule.运行git status并没有明确告诉我子模块在哪里。

How can I explicitly get the information regarding tag the submodule is aligned within the detached head from the superproject?如何明确获取有关子模块在超级项目的分离头内对齐的标签的信息? Ideally, I would like to have this information stored in plain text, for instance in the .gitsubmodules file.理想情况下,我希望将这些信息以纯文本形式存储,例如在.gitsubmodules文件中。 I want to be positive that the submodule is aligned with a given tag (or commit if the tag is not available) and I want to have this testable automatically.我想肯定子模块与给定标签对齐(如果标签不可用,则提交),并且我希望自动测试这个子模块。

Let's note a few basic facts:让我们注意一些基本事实:

  1. A submodule is a Git repository (so it has its own branch names, tag names, and commit objects).子模块Git 存储库(因此它有自己的分支名称、标签名称和提交对象)。
  2. A superproject is a Git repository in which the superproject Git goes into a submodule Git and does a git checkout hash (or git switch --detach hash ), by hash ID, to get a detached HEAD in the submodule Git repository. A superproject is a Git repository in which the superproject Git goes into a submodule Git and does a git checkout hash (or git switch --detach hash ), by hash ID, to get a detached HEAD in the submodule Git repository. The hash ID used for this operation is the one recorded in a commit in the superproject.用于该操作的 hash ID 是在超级项目中的一次提交中记录的 ID。 (That's the hash ID you froze by committing.) (那是您通过提交冻结的 hash ID。)

In other words, Git really doesn't use a tag to achieve this, even though you did use one to get the state that you then froze into a commit.换句话说,Git 确实没有使用标签来实现这一点,即使您确实使用了标签来获取 state,然后您将其冻结为提交。 So...所以...

How can I explicitly get the information regarding tag the submodule is aligned within the detached head from the superproject?如何明确获取有关子模块在超级项目的分离头内对齐的标签的信息?

... there are two different ways to deal with this: ...有两种不同的方法来处理这个问题:

  • One way is to record, in the superproject—in something that Git itself won't use, because Git is going to use the hash ID in the commit—the tag name.一种方法是在超级项目中记录 Git 本身不会使用的东西,因为 Git 将在提交中使用 hash 标记 ID。

  • The other way is to use the hash ID anyway, and then enter the submodule and see if there are some tag(s) that correspond to that hash ID.另一种方法是无论如何使用hash ID,然后进入子模块,看看是否有一些标签对应于那个hash ID。

These are the two overall strategies.这是两个总体策略。 They have different consequences if someone chooses to do something that's technically-possible but recommended-against.如果有人选择做一些技术上可行但建议反对的事情,它们会产生不同的后果。 In particular, suppose someone who controls the submodule repository alters the tags in some way.特别是,假设控制子模块存储库的人以某种方式更改了标签 A tag like v2.1 used to name commit a123456 bu now names commit b789abc .v2.1这样的标签曾经命名为 commit a123456 bu 现在命名为 commit b789abc Perhaps a123456 now has a tag 2.1alpha instead.也许a123456现在有一个标签2.1alpha代替。 Then:然后:

  • Asking the submodule what tag(s) do you have for a123456 comes up with a new and different answer ( 2.1alpha ), but you—or rather, your superproject Git, when you do git submodule update —will still check out and thus use a123456 (the hash ID you froze earlier by committing).询问子模块你对a123456有什么标签会得到一个新的和不同的答案 ( 2.1alpha ),但是当你执行git submodule update时,你——或者更确切地说,你的超级项目 Git——仍然会检查并使用a123456 (您之前通过提交冻结的 hash ID)。

  • Asking the submodule what hash ID do you have for v2.1 comes up with a new and different answer, b789abc .询问子模块什么 hash ID do you have for v2.1得到一个新的和不同的答案b789abc

If nobody does this frowned-upon thing, the question won't ever arise in the first place.如果没有人做这种不受欢迎的事情,那么这个问题一开始就不会出现。 But you'll have to decide for yourself how it should be handled, if you think it might happen.但是,如果您认为它可能会发生,您必须自己决定如何处理它。

Now, as for recording items in .gitmodules , there is a way to do this.现在,对于在.gitmodules中记录项目,一种方法可以做到这一点。 The problem is that what Git will record is not a tag name but rather a branch name:问题是 Git 将记录的不是标签名称而是分支名称:

git submodule set-branch -b <name> submodule

will add:将添加:

branch = <name>

to the entry in the .gitmodules file..gitmodules文件中的条目。 The name you use here need not actually exist, For instance: I just did:您在此处使用的name实际上不需要存在,例如:我刚刚做了:

git submodule set-branch -b v1.0 scripts

in a temporary test repo to which I added a submodule.在我添加了一个子模块的临时测试存储库中。 There is no v1.0 , neither as branch nor tag, anywhere in the actual submodule.实际子模块中的任何地方都没有v1.0 ,既不是分支也不是标签。 Git completely ignores this name unless you run particular varieties of git submodule update . Git 完全忽略此名称,除非您运行特定品种的git submodule update I won't go into all of them, but for instance, consider this:我不会 go 进入所有这些,但例如,考虑一下:

$ git submodule update --remote
fatal: Needed a single revision
Unable to find current origin/v1.0 revision in submodule path 'scripts'

Note that Git assumed v1.0 was a branch name here, and added origin/ in front of it;注意 Git 这里假设v1.0是一个分支名称,并在其前面添加了origin/ there is no way to tell it not to make this assumption.没有办法告诉它不要做这个假设。

The .gitmodules file is simply a Git configuration file, though, and can therefore be manipulated directly by git config . .gitmodules文件只是一个 Git 配置文件,因此可以通过git config直接操作。 You can read or write the branch entry, or invent your own entries.您可以读取或写入branch条目,或发明自己的条目。 There is a bit of danger to inventing your own: some future version of Git might invent the same thing, but use it in some different way.自己发明有点危险:Git 的某些未来版本可能会发明同样的东西,但以不同的方式使用它。 Still, let's see what this does:不过,让我们看看这是做什么的:

$ git config -f .gitmodules submodule.scripts.tag v1.0
$ git diff
diff --git a/.gitmodules b/.gitmodules
index 32170c2..f8cb154 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,5 @@
 [submodule "scripts"]
        path = scripts
        url = ssh://git@github.com/chris3torek/scripts
+       branch = v1.0
+       tag = v1.0

The branch = is left over from my earlier git submodule command—let's remove it now, just to clean up: branch =是我之前的git submodule命令遗留下来的——让我们现在删除它,只是为了清理:

$ git submodule set-branch --default scripts
$ git diff
diff --git a/.gitmodules b/.gitmodules
index 32170c2..71dcdd2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,4 @@
 [submodule "scripts"]
        path = scripts
        url = ssh://git@github.com/chris3torek/scripts
+       tag = v1.0

You can now retrieve this tag with git config -f.gitmodules --get :您现在可以使用git config -f.gitmodules --get检索此标签:

$ git config -f .gitmodules --get submodule.scripts.tag
v1.0

The git config command is quite suitable for scripting; git config命令非常适合编写脚本; consult the documentation for more.有关更多信息,请参阅文档 See also git submodule foreach in the git submodule documentation for a way to automatically run commands for each submodule.另请参阅 git 子git submodule git submodule foreach ,了解为每个子模块自动运行命令的方法。

(You don't have to store this tag information directly in .gitmodules , of course; any file will work, and that can insulate you from potential future Git changes.) (当然,您不必将此标签信息直接存储在.gitmodules中;任何文件都可以使用,这可以使您免受未来潜在的 Git 更改的影响。)

To turn a hash ID into a tag name, consider using git tag --points-at (assuming your Git version is at least 1.7.10):要将 hash ID 转换为标签名称,请考虑使用git tag --points-at (假设您的 Git 版本至少为 1.7.10):

git tag --points-at <hash>

will print the name(s) of the tag(s) that select that particular commit.将打印 select 该特定提交的标签的名称。 Note that you must run this Git command in the submodule , after using the superproject to find the hash ID.请注意,在使用超级项目找到 hash ID 后,您必须在子模块中运行Git 命令。 1 1

Last, to automate checking of submodules, consider the git submodule status and/or git submodule summary commands, which are also described in the git submodule documentation.最后,要自动检查子模块,请考虑git submodule status和/或git submodule summary命令,这些命令也在git submodule文档中进行了描述。


1 One way to use the superproject to find the submodule's hash ID is to let Git run git checkout / git switch in the submodule, by running git submodule update in the superproject. 1 One way to use the superproject to find the submodule's hash ID is to let Git run git checkout / git switch in the submodule, by running git submodule update in the superproject. But if you just want to read the correct hash ID, use git rev-parse .但是,如果您只想读取正确的 hash ID,请使用git rev-parse The submodule hash ID is stored in each commit as a gitlink entry, which is then copied to Git's index when checking out the superproject commit.子模块 hash ID 作为gitlink条目存储在每个提交中,然后在签出超级项目提交时将其复制到 Git 的索引中。 So you can, for instance, use:例如,您可以使用:

git rev-parse <commit>:path/to/submodule

in the superproject to see the hash ID in the given commit, or:在超级项目中查看给定提交中的 hash ID,或者:

git rev-parse :path/to/submodule

to see the hash ID currently stored in the superproject Git's index.查看当前存储在超级项目 Git 索引中的 hash ID。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM