git标记是否适用于所有分支?

git标记是否适用于所有分支?,git,branch,git-branch,git-tag,Git,Branch,Git Branch,Git Tag,我对git标签很感兴趣,但我以前的背景是Subversion,“标签”实际上只是拷贝,而不是“真正的”标签 如果我在git回购中添加一个标记,它是应用于所有分支还是仅应用于当前分支 例如,如果我当前有这些分支(git branch-v): 如您所见,当前签出的分支是master。现在假设我git标记-一个标记名,那么标记名是否仅适用于deadbeef(主分支)或baddfeed(开发分支) e、 例如,在签出标记之前,假设我随后切换到dev分支(即,不是创建标记的分支): git checkou

我对git标签很感兴趣,但我以前的背景是Subversion,“标签”实际上只是拷贝,而不是“真正的”标签

如果我在git回购中添加一个标记,它是应用于所有分支还是仅应用于当前分支

例如,如果我当前有这些分支(
git branch-v
):

如您所见,当前签出的分支是master。现在假设我
git标记-一个标记名
,那么
标记名
是否仅适用于
deadbeef
(主分支)或
baddfeed
(开发分支)

e、 例如,在签出标记之前,假设我随后切换到dev分支(即,不是创建标记的分支):

git checkout dev
git checkout TAGNAME
然后我是否会签出
baddfeed
,或者标记签出(第二行)是否会将我切换回主分支(创建标记的地方),并签出
deadbeef
? (或者第三个选项,我对创建和恢复标签的理解是否有缺陷或过于简单,以致于答案无法像这两个选项中的一个那样简单?)


另外,如果我使用轻量级标记(
git tag TAGNAME
)而不是带注释的标记,我的问题的答案会有任何变化吗?

假设您在branch
myBranch
。然后创建一个名为
myTag

-----A-----B-----C-----D-----H-------I-----> master
                       \
                        \
                         \---E----F-----G-----> myBranch
                                        |
                                        myTag
标记将仅位于
myBranch
分支的提交对象上。我也使用过CVS,它也标记了修订,不是所有的分支(但在CVS中,分支是特殊的标记)。我不这么认为

如果您签出myTag,您将处于示例的提交
G
。不能在不同的分支上创建具有相同名称的标记。如果这样做,您将移动标记

与此相关的注释标记没有区别

注意:签出标记时,您将以“分离头部”模式结束。除非从签出的标记开始创建另一个分支,否则您所做的更改将丢失。

要简化此过程,请执行以下操作:

如果我在git回购中添加一个标记,它是应用于所有分支还是仅应用于当前分支

在Git中,标记只是提交id的别名。添加标记时,Git只是将标记名(标记字符串)映射到给定的提交id。由于提交id与特定分支(或合并时的分支)相关,因此标记将仅与该分支(及其合并到的任何分支)相关

更多信息可在此处找到:


阅读了这些问题和您的评论后,我认为让您感到困惑的基本点是,在git(相对于其他系统)中,“在分支上”意味着什么

在git中,一个
git checkout
操作将签出一些特定的提交(但请参见脚注1)。它还设置了特殊名称
HEAD
,以便它引用该特定提交。但是:
HEAD
可以通过两种不同的方式指定特定的提交。它可以是:

  • 通过ID(这不是通常的情况),或
  • 通过间接引用分支名称(这是更常见的情况)
如果您执行了git checkout branchname,git将设置第二种常见情况。如果随后
cat.git/refs/HEAD
您将发现它包含文本字符串
ref:
,后跟
refs/heads/branchname
[2]。这就是“在分支上”的含义:您已经签出了分支名称所指的提交,但是,
HEAD
是一个“符号引用”。如果您进行了新的更改并提交了它们,git将进行新的提交,然后“剥下”分支标签便笺并将其粘贴到您刚刚添加的新提交上。“移动分支”到新添加的提示,您“仍然在分支上”

另一方面,如果您使用git签出标记名,git将设置第一个异常情况。如果您通过SHA-1 ID(那些
ea56709…
style字符串)进行签出,也会执行相同的操作。在本例中,
HEAD
的文件中只有文本SHA-1 ID。在这种状态下,如果您进行了一次新的提交,它会像往常一样被添加,但不会因为移动分支标签而更改便笺。你不是“在树枝上”<代码>头部不是“符号参考”

就实际标记本身而言,它们只是提交的名称。但是等等,这不是一个分支名称吗?对分支名称和标记名称之间的区别在于,分支名称需要移动,git将在“on a branch”的情况下自动移动它。标记名不是“预期移动”[3],永远不会自动移动


脚注:

[1] 只是为了让事情变得混乱(或者因为git的用户界面是“邪恶的”,正如一些人所说:-)),有些情况下,
git checkout
不会改变
HEAD
,特别是当您要求它签出特定的路径名时

[2] 在非常旧的git版本中,git使用了符号链接,而不是
ref:…
git。链接的目标是分支ID文件,例如,
refs/heads/master
或其他任何文件,因此打开和读取该文件会获得提交ID,并且您必须使用
lstat
来检测“分支上”。这在Windows上不起作用,并且排除了“打包”引用(
.git/packed refs
),因此更改为使用
ref:


[3] 短语“被期望”和“不被期望”应该会促使你问:被谁期望?Git本身对Git用户移动标签没问题,使用Git的人(通常是他们编写的脚本)对此感到困惑。因此,除非您首先与共享存储库的其他人进行了检查,否则不要移动标记。

我强烈建议阅读:&。所有东西都在里面。一个标记标识一个提交。看,格雷格的答案就是你所需要的。标记是没有上下文的单个提交,它们位于存储库范围的命名空间中。你不会说一个给定的标记“在”一个分支上,就像你不会说Linux3.11“在”任何分支上一样
-----A-----B-----C-----D-----H-------I-----> master
                       \
                        \
                         \---E----F-----G-----> myBranch
                                        |
                                        myTag