samshers
samshers

Reputation: 3660

Are git annotated tags modifyable? If so, how?

Modifying lightweight tags in git is working as intended. git tag -f <tagname> <commit-id>

But using the same with annotated tags seems to be causing trouble -

$ git cat-file -t tag2rag
tag

and

$ git cat-file -p tag2rag
object a7b4b4823f0222b79376e4c16bdbba0f3d1f5d33
type commit
tag tag2rag
tagger samshers <[email protected]> 1568930032 +00:00

tag to rag

then,

$ git tag -f tag2rag 3096b
Updated tag 'tag2rag' (was 8931274)

then, the unexpected

$ git cat-file -t tag2rag
commit

and

$ git cat-file -p tag2rag
tree b0053bf300da86e5aeabafb29d7dedcdbf713d51
parent 49c74fafd7c69e938052a4cba96ad62999438413
author samshers <[email protected]> 1568910804 +0000
committer samshers <[email protected]> 1568910804 +0000

wowfiles in

Disclaimer: Well, I acknowledge that changing tags after publishing is not a good practice and could cause more collaboration issues. And instead a new tag should be created and published.
Well the purpose here is to understand git and how to do things in git.

Any suggestions on how to edit annotated tags.

Upvotes: 0

Views: 195

Answers (1)

torek
torek

Reputation: 487725

The short answer is no.

The longer answer is that they are exactly as modifiable as commits: not at all, but if you try hard enough, you can get a new and different commit—or annotated tag, in this case—and you can trick people into thinking you changed some existing object.

An annotated tag is composed of a lightweight tag—a reference that begins with refs/tags/—that points to an internal Git object of type tag:

$ git cat-file -t v2.4.0
tag

The underlying object has a hash ID:

$ git rev-parse v2.4.0
67308bd628c6235dbc1bad60c9ad1f2d27d576cc

This hash ID is the Git-style checksum of the object (header + contents):

$ git cat-file -p v2.4.0 | sed 's/@/ /'
object 3d4a3ffe64162b45ae7c991fc60623ecb4678cfd
type commit
tag v2.4.0
tagger Junio C Hamano <gitster pobox.com> 1430418320 -0700

Git 2.4
-----BEGIN PGP SIGNATURE-----
[snip]

You can make a new tag object with different contents (using git tag or git mktag, for instance) but if the contents differ, so will the hash ID. You can then make the lightweight tag name point to the new tag object, using git update-ref for instance.

This does not modify the existing object in any way. A naïve user, however, would now examine the tag uncritically, not notice that the refs/tags/v2.4.0 name produces a new and different tag object ID, read the new and different tag object, and think the tag has changed. (If the identifier inside the tag object still has the v2.4.0 name, everything is in sync and perhaps the tag really has changed, from some points of view!)

Attempts to send this new updated tag to other Git repositories may succeed or fail, depending on their policy on replacing an existing tag-namespace ref and whether they had a copy of the previous tag <name,object> pair.

Upvotes: 2

Related Questions