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

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

问题描述

长话短说,我正在编写一个脚本,将一个非常大的项目从(gasp)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.

对于属于 tip提交的提交(请参见 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的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 标记,它指向的提交对象是原始提交,而不是某些Trojan Horse.如果您更改现有标签,那么您正在颠覆这种意图.而且,一些知道先前标签值的人只会拒绝采用新值:您将 无法让他们更新现有标签.只要您在之前进行此操作,其他任何人都可以使用该标签,但是他们永远不会知道,您会很好的.

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 或者,除非您可以打破哈希值.另请参见新发现的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标签的Tagger名称和电子邮件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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