我刚才做了以下事情:
// make change
// git add .
// git commit -m "2.0.0"
// git tag -a v2.0.0 <sha-of-above-commit>
// git push --tags
但是,我忘了推送实际的提交,现在我的标签没有显示出来(可能是因为我实际上没有推送我标记的提交。)
然后我重新克隆了回购并运行了git tag
,并在那里看到了我的标签。
但是,我的提交未列在git log
下。所以我重新制作了我的更改,并运行了git push
。这成功了。但是,git push --tags
失败了,因为它说标签已存在于遥控器上。
对此有何解决方案?我尝试删除远程v2.0.0标记,但出现(hook declined)
错误。
答案 0 :(得分:2)
git push origin master
ElpieKay's comment有正确的答案:您的git push
推送了提交和标记,但其他(远程)Git存储库中没有分支包含提交。也就是说,就你自己的Git提交图而言,你有 - 我在这里猜测有问题的分支是master
- 这个:
...--o <-- origin/master
\
o <-- master, tag:v2.0.0
您随后向Git on origin发送了提交本身(根据需要发送标记v2.0.0
)以及 it 的请求以创建名为的标记v2.0.0
指向新提交 - 它做了 it 图表:
...--o <-- master
\
o <-- tag:v2.0.0
现在从其他Git(包括您自己)克隆存储库的任何人都会在git tag
输出中看到标记,但不会在分支master
上看到提交,因为它不是 on 分支master
。新提交的唯一链接是标记。
解决方案很简单:做一个git push
让你的Git让他们(来源的)Git设置他们的分支master
来指向新的提交。例如,如果提交的哈希ID是1234567
,那么这就可以解决问题:
git push origin 1234567:master
甚至来自你的新克隆。或者,因为标记v2.0.0
解析为正确的提交哈希: 1
git push origin v2.0.0^{commit}:master
这个简单修复的最简单版本是从原始开发存储库执行push
操作,其中master
分支指向与v2.0.0
标记相同的提交。在这种情况下,您不需要指定refspec参数的两半:
git push origin master
(当然,这确实假设起源master
从那时起没有增加新的提交。)
1 我说“解析为”,然后介绍这个时髦的v2.0.0:^{commit}
语法。那是什么意思?
由于v2.0.0
是带注释的标记(由git tag -a
生成),因此名称本身实际上指向存储库中的标记对象。它是指向提交的标记对象。当我绘制提交图时,我绘制了 commit 图,而不是commit-and-tag图。 :-)所以我离开了这一点。
但是,当我们转到git push
时,确保我们要求他们的Git将其分支master
设置为直接指向提交而不是标记,这可能是明智之举。分支名称不允许指向标记。也许请求会起作用 - 也许Git会知道“不允许分支名称指向标签”,并且会使用适当的魔法将标记对象转换为其目标提交ID,但可能不会。我们可以通过告诉我们的 Git将任何标记名称转换为其目标提交来完全避免这个问题。
这就是这个时髦的语法。如the gitrevisions
documentation中所述,name:^{type}
首先告诉Git解析名称,然后根据需要“剥离”该名称以找到给定类型的Git对象。
当您为Git提供分支名称时,该名称将保证解析为提交对象,因为分支名称必须指向提交对象。另一方面,标记名称可以指向all-commit,tag,tree或blob中的任何Git对象。通常它们仅指向标记对象或提交对象,但Git不会阻止您创建指向blob或树的对象。我已经在我自己的存储库中为各种实验目的做了这个。因此,对于标记,您可以使用^{commit}
强制它解析为提交。如果名称指向带注释的标记对象,则该标记将跟随其提交。如果名称已经指向提交,则它什么都不做。如果名称以某种方式指向树或blob,则会产生错误。
您还可以使用:^{tree}
和:^{blob}
来验证名称是否指向树或blob对象。当然,如果名称是分支名称,但它不是,但 name
部分也可以包含路径:例如,master:Documentation
命名一个树对象Git本身的Git存储库中的分支master
,如果您正在编写脚本并且需要非常确定您正在获取树的哈希ID,您可以写:
treehash=$(git rev-parse master:Documentation^{tree}) || die ...
在你的剧本中。