Git:标记分支并从标记创建一个新分支

时间:2017-07-21 20:38:48

标签: git git-branch git-tag

我有一些自动系统来标记我的old分支机构。 我这样做是为了避免大量分支。

但有时会发生一些标记的先前分支,我需要进行一些额外的更改。

有没有正确的方法来处理这个标签?

AFAIK,我可以从这些标签中创建一个新分支:

git checkout -b <new_branch_name> <tag>

看起来很不错,但是......

1)我正在调用与分支原始名称相同的标签。

2)我想创建一个与其名称相同的分支。

这是不可能的,因为它会引发错误:

warning: refname '<branch_name>' is ambiguous.
fatal: A branch named '<branch_name>' already exists.

我要添加的另一件事是,我希望在从中创建分支时删除此标记。

是否可以使用一些简单的分支创建命令来解决这个问题?

或许有人有类似的流程,可以提出更好的建议吗?

2 个答案:

答案 0 :(得分:4)

分支或标记名称部分只是您所见过的那些丑陋的Git哈希ID之一的简短易读的名称。

X这样的分支名称与X等标记名称之间的区别非常小。事实上,关键的区别是:

  • 分支X全名refs/heads/X;
  • 标记X全名refs/tags/X;
  • 作为一项规则,标记名称永远不应该更改它命名的哈希ID,但通常的分支名称会以明确定义的方式随时间发生变化:它始终指向最新提交添加到分支机构。

事实上,正是如何 Git知道哪些提交在分支上:分支名称X,它实际上是refs/heads/X,用于标识特定的提交是分支的一角。然后,该提交返回其父提交,这可能曾经是分支的提示。父提交引用其自己的父提交,依此类推;这是分支的历史。

当Git告诉您分支名称时,它会剥离前导refs/heads/。当它告诉您标签名称时,会剥离前导refs/tags/。 (有一些例外,但这是通常的规则。)

有两件事的短形式只是X通常是不明智的......不是因为 Git 会混淆,而是因为会的。 Git有一个非常精确 - 虽然相当复杂的规则,总是选择一个......但并不总是你意味着。这就是您收到警告信息的原因。

您的选择是忽略警告,或者更加努力地避免它。要更加努力,请使用Git所谓的 plumbing 命令。这些命令旨在从脚本中使用,因此具有非常可预测和可重复的行为,但它们往往需要大量输入(这是正常的,它是计算机进行打字)。

用于创建,删除或更新reference- 引用的管道命令是&#34;分支,标记或其他此类名称的奇特长词&#34; -is {{1并且它要求您每次都拼出git update-refrefs/heads/X。因此,您可以编写一个脚本来检查refs/tags/X和/或refs/heads/whatever的存在,并创建或删除&#34;其他的&#34;。

要确定一个是否存在,如果存在,请使用管道命令refs/tags/whatever并拼出引用的全名。如果名称不存在,该命令将失败(并返回非零状态,并且通常打印消息,但您可以禁止此操作),如果名称确实存在,将打印出哈希ID。

注意:删除分支名称时,还会删除其reflog。分支(或任何引用,实际上)的reflog包含引用的所有之前的值,在过去的30到90天左右(数字有点复杂,如果你可以调整喜欢)。由于标签通常不会移动,因此它们的reflog(如果有的话)往往非常沉闷:&#34;此标签始终具有值git rev-parse&#34;然而,分支机构移动,正如我们上面提到的那样,并且他们的reflogs充满了&#34;这个分支指向昨天&#34;等等。

答案 1 :(得分:2)

您可以执行以下一系列命令来完成此操作:

$ git checkout -b _tmp_<tag name> <tag name>
$ git tag -d <tag name>
$ git checkout -b <tag name>
$ git branch -d _tmp_<tag name>

这将做什么(以相同的顺序)

  • 创建一个名称为_tmp_tag_branch的分支,指向
  • 删除对
  • 的引用
  • 创建另一个分支,引用_tmp_tag_branch,从而创建原始标记
  • 删除_tmp_tag_branch

修改

为了让您的生活更轻松,您可以将其添加到~/.gitconfig

[alias]
    tag2branch = ! sh -c 'git checkout -b _tmp_$1 $1 && git tag -d $1 && git checkout -b $1 && git branch -d _tmp_$1' -

之后,您只需执行$ git tag2branch <tag name>

即可

注意:这仅适用于您的系统以及拥有~/.gitconfig

的用户