如何更改 Git Tag 的 Tagger 名称和电子邮件 [英] How to change the Tagger name and email of a Git Tag

查看:13
本文介绍了如何更改 Git Tag 的 Tagger 名称和电子邮件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

长话短说,我正在编写一个脚本来将一个非常大的项目从(喘气)Microsoft SourceSafe 迁移到 Git,并且我正在尝试保留 SourceSafe 项目标签(本质上是 Git 中的标签)的作者.我知道你可以修改 Git 提交的作者和提交者姓名/日期,但你可以对 Git 标签做同样的事情吗?

Long story short I'm writing a script to migrate a very large project from (gasp) Microsoft SourceSafe to Git and I'm trying to retain the authors of the SourceSafe project's labels(which are essentially tags in Git). I know you can modify the author and committer name/date of a Git Commit but can you do the same to a Git Tag?

推荐答案

TL;DR

使用新的所需数据重新创建标签.但是,如果其他人以前拥有它们,他们可能不会接受您的新产品.或者他们可能!不过,这取决于他们.

我知道您可以修改 Git 提交的作者和提交者姓名/日期

I know you can modify the author and committer name/date of a Git Commit

实际上,您不能,而您不能(以及您可以做什么)这一事实在其余答案中起着重要作用.

Actually, you can't, and the fact that you can't (and what you can do instead) plays an important part in the rest of the answer.

所有 Git 对象都有一个哈希 ID 作为它们的真实名称".哈希是通过计算对象内容的加密校验和形成的.这意味着您根本无法更改任何 Git 对象.1可以做的是构造一个 new 对象,然后说服所有拥有旧对象停止使用它,而使用新对象.

All Git objects have a hash ID as their "true name". The hash is formed by computing a cryptographic checksum of the object's contents. This means you can never change any Git object at all.1 What you can do is construct a new object, then convince everyone who had the old object to stop using it, and use instead the new object.

这就是 git commit --amend 所做的(以及各种交互式 rebase 选项,如 editreword 也可以做).首先我们将原始的 Git 对象提取为普通数据,我们可以在其中对其进行操作;然后我们进行操作并要求 Git 构造一个新对象;最后我们停止使用旧对象并开始使用新对象.

This is what git commit --amend does (and what various interactive rebase options like edit and reword can do as well). First we extract the original Git object into ordinary data, where we can manipulate it; then we do the manipulation and ask Git to construct a new object; and finally we stop using the old object and start using the new one instead.

对于作为 提示提交 的提交(请参阅 head 在 gitglossary 中的定义),这一切都很容易顺利,只要我们还没有推送那个提交.没有引用此提示提交的其他提交,因此我们进行同样好"的新提交,将分支名称(head)重定向到新提交,然后忘记关于我们刚刚更换的原件.看起来我们更改了一个提交,但我们得到了一个新的哈希 ID.

For a commit that is the tip commit (see the definition of head in the gitglossary), this all goes pretty easily and smoothly, as long as we haven't pushed that commit yet. There are no additional commits referring back to this tip commit, so we make a new commit that is "just as good", re-direct the branch name (the head) to the new commit, and forget about the original we just replaced. It looks like we changed a commit, but we got a new hash ID instead.

Git 有两种标签,一种是 轻量级标签和一个带注释的标签.它们之间的区别在于,带注释的标签由指向 标签对象.它是具有标记器信息的标记对象.(轻量级标签本身没有这样的信息,它只是直接指向提交对象.)

Git has two kinds of tags, a lightweight tag and an annotated tag. The difference between these is that an annotated tag consists of a lightweight tag pointing to a tag object. It's the tag object that has the tagger information. (A lightweight tag has no such information of its own, it just points directly to the commit object.)

因此,要更改"标签对象,我们必须做与更改"提交对象相同的操作:将其复制到 new 标签对象.

Hence, to "change" a tag object, we must do the same thing we do to "change" a commit object: copy it to a new tag object.

没有内置命令来执行此操作,但很容易从 git cat-file -p 构建一个 - 这可以让您将原始标签提取到普通数据中 - 和 git mktag,它可以让你把普通数据变成一个新的标签对象.例如,Git 存储库中的 v2.2.1 标签以:

There is no built in command to do this, but it is easy to build one out of git cat-file -p—this lets you extract the original tag into ordinary data—and git mktag, which lets you turn ordinary data into a new tag object. For instance, the v2.2.1 tag in the Git repository for Git begins with:

$ git cat-file -p v2.2.1
object 9b7cbb315923e61bb0c4297c701089f30e116750
type commit
tag v2.2.1
tagger Junio C Hamano <...

object 行是标签指向的提交:

The object line is the commit to which the tag points:

$ git cat-file -t 9b7cbb315923e61bb0c4297c701089f30e116750
commit

所以我们可以将此标签复制到具有不同 tagger 的新标签:

so we can copy this tag to a new one with a different tagger:

$ new_hash_id=$(git cat-file -p v2.2.1 | sed -e .... | git mktag)
$ git update-ref refs/tags/$name $new_hash_id

sed 做任何必要的事情(见下文),$name 是标签的名称.然后我们让轻量级标签 v2.2.1 指向 $new_hash_id 中的这个新标签对象.但是有两个问题(其中只有一个可能适用于您的情况).

where the sed does whatever is necessary (see below) and $name is the name of the tag. Then we would make the lightweight tag v2.2.1 point to this new tag object in $new_hash_id. But there are two problems (only one of which is likely to apply to your case).

上面的标签接着说:

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

然后在其中有一个 PGP 签名.此签名涵盖除签名本身之外的所有数据.如果您复制和修改此标签,您应该完全放弃原始签名(它将无效并且将无法通过任何应用测试);您是否可以并且应该用新签名替换它,如果可以,由您决定.

and then has a PGP signature in it. This signature covers all the data except for the signature itself. If you copy-and-modify this tag, you should discard the original signature entirely (it will be invalid and will fail any testing applied); whether you can and should replace it with a new signature, and if so, whose, is up to you.

已有的轻量级标签v2.2.1目前指向已有的标签对象:

The existing lightweight tag v2.2.1 currently points to the existing tag object:

$ git rev-parse v2.2.1
7c56b20857837de401f79db236651a1bd886fbbb

这是到目前为止我们一直在查看的数据.

This is the data we have been viewing up to this point.

new 标记对象将具有其他一些不同的哈希 ID.当我们修改一个未发布的提交时,这没什么大不了的,因为没有其他人知道某个分支名称映射到某个特定的哈希 ID.

The new tag object will have some other, different hash ID. When we amended an unpublished commit, that was no big deal, because no one else had any idea that some branch name mapped to some particular hash ID.

但是,标签通常是众所周知的".事实上,标签的意义——尤其是 PGP 签名的带注释的标签,PGP 签名让您可以验证没有人对标签数据进行过篡改——是为了保证您可以确定这个标签是 right 标记,并且它指向的提交对象是原始提交而不是某些特洛伊木马.如果您更改 现有标签,您就是在颠覆这个意图.此外,一些知道前一个标签值的人会简单地拒绝接受一个新值:您将无法能够让他们更新现有标签.但是,只要您在 其他人拥有该标签之前这样做,他们就永远不会知道,而您会没事的.

Tags, however, are pretty commonly "well known". In fact, the point of tags—particularly PGP-signed annotated tags, where the PGP signature lets you verify that no one has monkeyed with the tag data—is to guarantee that you can be sure that this tag is the right tag, and that the commit object to which it points is the original commit and not some Trojan Horse. If you change an existing tag, you're subverting this intent. Moreover, some people who know the previous tag's value will simply refuse to take a new value: you won't be able to get them to update an existing tag. As long as you're doing this before anyone else has the tag, though, they will never know, and you will be fine.

1或者更确切地说,您不能更改 Git 对象的内容,除非您可以破坏哈希.另见新发现的sha1冲突对git有何影响?

1Or rather, you cannot change a Git object's contents unless you can break the hash. See also How does the newly found sha1 collision affect git?

这篇关于如何更改 Git Tag 的 Tagger 名称和电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆