我阅读了很多SO帖子,但没有一个让我明白git标签是如何真正起作用的,特别是关于它们与分支的链接。我认为这是由于对git原则的误解。也许有人可以帮助我。
我们说我有以下两个分支master
和develop
K
合并提交:
-A-B-C-D-E-F-G-K-L-M (master)
\-H-I-J-/ (develop)
如果我标记J
提交,则此标记将位于两个分支上(因为合并)。
所以当我checkout
这个标签时,我会有什么版本?包含E
分支的F
,G
,master
提交或develop
分支的提交的提交。不确定我清楚我想要了解什么。我知道标签不引用分支但只提交。但是检查一个标签也可以恢复提交历史记录吗?
答案 0 :(得分:2)
您可以签出标记,但这会使您的存储库处于分离的HEAD状态。本质上不在任何分支上。
请参阅Git Tagging。
答案 1 :(得分:2)
我认为分支的位置是这样的(无论如何都无关紧要):
v------- master
-A-B-C--D-E-F--G-K-L-M
\-H-I-J-/
^------ develop
如果我标记
J
提交,则此标记将位于两个分支上(因为合并)。
标记是提交的只读指针。分支也指向提交但是它被许多Git命令移动到另一个提交(git commit
,git merge
,git rebase
,git pull
,git reset
是最常见的。)
考虑到两个分支的当前位置,确实可以从两个分支到达J
提交。 git commit
,git merge
和git pull
不会更改此现状。但是git reset
或git rebase
可以在不是J
后代的提交上移动分支,并且在这种情况下J
将无法从移动的分支中访问。
所以当我签出这个标签时,我会有什么版本?包含
master
分支的E,F,G提交或develop
分支的提交的提交。
git checkout
将您的工作副本更改为与签出的提交相同。
如果将分支传递给git checkout
,它也会使该分支成为当前分支(又名HEAD
)。如果您传递给git checkout
不是分支的引用(它可以是标记,提交哈希或解析为单个提交的其他revision specification),那么您将存储库置于一个状态名为"detached HEAD
"。这意味着没有当前的分支
建议不要在分离的HEAD
状态下工作(除非您知道自己在做什么),因为任何分支都不会指向以这种方式创建的提交,并且一旦您结帐,就会丢失另一个分支(或标记或提交)。
假设你跑:
git tag tagJ J
在commit tagJ
上创建名为J
的标记,以下两个命令执行相同的操作:
git checkout J
git checkout tagJ
他们更改工作树和索引以匹配commit J
中记录的项目的状态。他们将回购设置为分离的HEAD
状态。
命令:
git checkout develop
以与上述两个命令相同的方式更改工作树和索引。但是,它不会将repo设置为分离的HEAD
状态,而是将develop
设置为HEAD
(当前分支)。
但是检查一个标签也可以恢复提交历史记录不是吗?
历史记录由分支和标签决定。任何可从任何分支或标记访问的提交都是历史记录的一部分。如果您删除master
分支fe,则您的仓库的历史记录将仅包含可从develop
分支到达的提交(即A
,B
,{{1 },C
,H
和I
)。如果删除J
分支(并保留develop
分支),则不会丢失任何内容,因为图中可见的所有提交都可以从提交master
访问(由{{指向) 1}}分支)。