检查多个分支上存在的 git 个标签

Checkout git tags present on multiple branches

我阅读了很多 SO 帖子,但其中 none 让我了解了 git 标签的真正工作原理,尤其是关于它们的 link 分支。我认为这是由于对git原则的误解。也许有人可以帮助我。

假设我有以下两个分支 masterdevelop 以及 K 合并提交:

-A-B-C-D-E-F-G-K-L-M (master)
       \-H-I-J-/     (develop)

如果我标记 J 提交,这个标记将在两个分支上(因为合并)。 那么当我 checkout 这个标签时,我会有什么版本?包含 EFG 提交的 master 分支或来自 develop 分支的提交。不确定我是否清楚我想了解的内容。我知道标签不引用分支而只引用。但是签出标签也会恢复提交历史,不是吗?

您可以签出标签,但这会使您的存储库处于分离的 HEAD 状态。本质上不在任何分支上。

Git Tagging

我假设分支的位置是这样的(反正不是很重要):

                     v------- master
-A-B-C--D-E-F--G-K-L-M
      \-H-I-J-/
            ^------ develop

If I tag the J commit, this tag will be on the two branches (because of the merge).

标签是指向提交的只读指针。一个分支也指向一个提交,但它被许多 Git 命令移动到另一个提交(git commitgit mergegit rebasegit pullgit reset 是最常见的)。

鉴于两个分支的当前位置,确实可以从两个分支访问 J 提交。 git commitgit mergegit pull 不会改变这种 现状 。但是 git resetgit rebase 可以在不是 J 后代的提交上移动分支,在这种情况下 J 将无法从移动的分支访问。

So when I checkout this tag, what version would I have? The one containing the E,F,G commits of the master branch or the one from the develop branch.

git checkout 将您的工作副本更改为与签出的提交相同。

如果您将一个分支传递给 git checkout,它也会使该分支成为当前分支(又名 HEAD)。如果你传递给 git checkout 一个不是分支的引用(它可以是一个标签,一个提交哈希或其他 revision specification that resolves to a single commit) then you put the repository in a state that is named "detached HEAD"。这意味着没有当前分支。
不推荐在 detached HEAD 状态下工作(除非您知道自己在做什么),因为以这种方式创建的提交不会被任何分支指向并且会很快丢失当您签出另一个分支(或标记或提交)时。

假设你 运行:

git tag tagJ J

要在提交 J 时创建名为 tagJ 的标签,以下两个命令执行相同的操作:

git checkout J
git checkout tagJ

他们更改工作树和索引以匹配提交 J 中记录的项目状态。他们将回购设置为 分离 HEAD 状态。

命令:

git checkout develop

以与上述两个命令相同的方式更改工作树和索引。但是,它不会将 repo 设置为 detached HEAD 状态,而是将 develop 设置为 HEAD (当前分支)。

But checkouting a tag also recover a commit historic doesn't it?

历史由分支和标签决定。从任何分支或标记可访问的任何提交都是历史记录的一部分。如果您删除 master 分支 f.e,您的回购历史将仅包含可从 develop 分支访问的提交(即 ABCHIJ)。如果您删除 develop 分支(并保留 master 分支),您不会丢失任何东西,因为绘图中可见的所有提交都可以从提交 M 访问(由 master分支)。