我有一些自动系统来标记我的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.
我要添加的另一件事是,我希望在从中创建分支时删除此标记。
是否可以使用一些简单的分支创建命令来解决这个问题?
或许有人有类似的流程,可以提出更好的建议吗?
答案 0 :(得分:4)
分支或标记名称部分只是您所见过的那些丑陋的Git哈希ID之一的简短易读的名称。
X
这样的分支名称与X
等标记名称之间的区别非常小。事实上,关键的区别是:
X
的全名为refs/heads/X
; X
的全名为refs/tags/X
; 事实上,正是如何 Git知道哪些提交在分支上:分支名称X
,它实际上是refs/heads/X
,用于标识特定的提交是分支的一角。然后,该提交返回其父提交,这可能曾经是分支的提示。父提交引用其自己的父提交,依此类推;这是分支的历史。
当Git告诉您分支名称时,它会剥离前导refs/heads/
。当它告诉您标签名称时,会剥离前导refs/tags/
。 (有一些例外,但这是通常的规则。)
有两件事的短形式只是X
通常是不明智的......不是因为 Git 会混淆,而是因为你会的。 Git有一个非常精确 - 虽然相当复杂的规则,总是选择一个......但并不总是你意味着。这就是您收到警告信息的原因。
您的选择是忽略警告,或者更加努力地避免它。要更加努力,请使用Git所谓的 plumbing 命令。这些命令旨在从脚本中使用,因此具有非常可预测和可重复的行为,但它们往往需要大量输入(这是正常的,它是计算机进行打字)。
用于创建,删除或更新reference- 引用的管道命令是&#34;分支,标记或其他此类名称的奇特长词&#34; -is {{1并且它要求您每次都拼出git update-ref
或refs/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
的分支,指向修改强>
为了让您的生活更轻松,您可以将其添加到~/.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