然而,标签通常是“众所周知的”。事实上,标记的意义--特别是PGP签名的带注解标记,PGP签名让您验证没有人篡改标记数据--是为了 * 保证 * 您可以确信这个标记是 * 正确的 * 标记,并且它指向的提交对象是原始提交而不是特洛伊木马。如果你改变了一个现有的标签,你就破坏了这个意图。此外,一些知道前一个标记值的人会拒绝接受新值:你将无法让他们更新现有的标签。只要你在别人拿到标签之前就这么做,他们永远不会知道,你会没事的。 1或者更确切地说,您无法更改Git对象的内容,除非您可以break the hash。参见How does the newly found sha1 collision affect git?
3条答案
按热度按时间hfyxw5xn1#
TL;DR
使用新的所需数据重新创建标记。但是如果其他人以前有过他们,他们可能不会接受你的新的。或者他们可以!但这取决于他们。
说明
我知道你可以修改Git提交的作者和提交者的名字/日期
事实上,你不能,事实上,你不能(以及你能做什么)在答案的其余部分起着重要的作用。
所有的Git对象都有一个哈希ID作为它们的“真实名称”。通过计算对象内容的加密校验和来形成散列。这意味着你永远不能改变任何Git对象。1你 * 能 * 做的是构造一个 * 新 * 对象,然后说服所有拥有旧对象的人停止使用它,并使用新对象。
这就是
git commit --amend
所做的(以及各种交互式变基选项(如edit
和reword
)也可以做的)。首先我们将原始的Git对象提取为普通数据,在这里我们可以操作它;然后我们进行操作并要求Git构造一个新对象;最后,我们停止使用旧对象,并开始使用新对象。对于 tip commit(参见gitglossary中 head 的定义)的提交,只要我们还没有推送那个提交,这一切都进行得非常简单和顺利。没有额外的提交引用回这个提示提交,所以我们做了一个“同样好”的新提交,将分支名称(head)重定向到新提交,并忘记我们刚刚替换的原始提交。它看起来像是我们改变了一个提交,但我们得到了一个新的哈希ID。
如何应用于标签
Git有两种标签,一个是 *lightweight标签 *,另一个是 *annotated标签 *。它们之间的区别在于,带注解的标记由指向 * 标记对象 * 的轻量级标记组成。它是具有标记器信息的标记对象。(轻量级标记本身没有这样的信息,它只是直接指向commit对象。
因此,要“改变”一个标记对象,我们必须做与“改变”一个提交对象相同的事情:将其复制到一个 new 标记对象。
没有内置的命令来完成这项工作,但是很容易用
git cat-file -p
和git mktag
构建一个,git cat-file -p
允许您将原始标记提取为普通数据,git mktag
允许您将普通数据转换为新的标记对象。例如,Git存储库中的v2.2.1
标签以以下开头:object
行是标记指向的提交:所以我们可以将这个标签复制到一个新的带有不同
tagger
的标签:其中
sed
执行任何必要的操作(见下文),$name
是标记的名称。然后,我们将使轻量级标记v2.2.1
指向$new_hash_id
中的这个新标记对象。但有两个问题(其中只有一个很可能适用于你的情况)。标签支持PGP签名
上面的标签接着说:
里面有PGP签名此签名涵盖除签名本身之外的所有数据。如果您复制并修改此标记,则应完全丢弃原始签名(它将无效,并且将无法通过任何应用的测试);您是否可以并且应该用新的签名替换它,如果可以,由您决定谁的签名。
标签不能改变目标对象
现有的轻量级标记
v2.2.1
当前指向现有的标记对象:这是我们到目前为止看到的数据。
然而,标签通常是“众所周知的”。事实上,标记的意义--特别是PGP签名的带注解标记,PGP签名让您验证没有人篡改标记数据--是为了 * 保证 * 您可以确信这个标记是 * 正确的 * 标记,并且它指向的提交对象是原始提交而不是特洛伊木马。如果你改变了一个现有的标签,你就破坏了这个意图。此外,一些知道前一个标记值的人会拒绝接受新值:你将无法让他们更新现有的标签。只要你在别人拿到标签之前就这么做,他们永远不会知道,你会没事的。
1或者更确切地说,您无法更改Git对象的内容,除非您可以break the hash。参见How does the newly found sha1 collision affect git?
ohtdti5x2#
不像提交,你可以很容易地从远程删除标签,用你想要的作者名重新创建它们。
k4aesqcs3#
一个额外的细节:在创建带注解/签名的标签时,
git tag
将使用GIT_COMMITTER_NAME
和GIT_COMMITTER_EMAIL
(notGIT_AUTHOR_NAME
/GIT_AUTHOR_EMAIL
)作为“Tagger
”字段。创建一个不同名称/email的标签,而不改变全局Git配置:
注1:要创建签名标记(
-s
),需要指定身份的私钥(这是签名的要点)。注2:也可以重新创建具有特定时间戳的旧标签。例如:
GIT_COMMITTER_DATE="Wed Dec 16 22:33:44 UTC 2020" ...