1

Specifically, while retaining the tag's annotation message and date.

Last night, I created a signed tag for a repo I'm working on. A few minutes later, I unthinkingly amended the commit I'd tagged. Now, I'm getting ready to push my changes and need to clean up that tag before I do.

Looking at a similar (ish) question, I've attempted various combinations of GIT_AUTHOR_DATE and GIT_COMMITER_DATE with no luck:

$ git show v0.1.1 | awk '{ if ($1 == "Date:") { print substr($0, index($0, $3)) } }'
Nov 26 18:14:17 2017 -0800
Nov 26 18:13:21 2017 -0800

$ git tag -d v0.1.1
Deleted tag 'v0.1.1' (was d4189a2)

$ GIT_AUTHOR_DATE="Nov 26 18:14:17 2017 -0800" \
> GIT_COMMITER_DATE="Nov 26 18:14:17 2017 -0800" \
> git tag v0.1.1 9aa951c -s -m 'Display in columns.'

$ git show v0.1.1 | awk '{ if ($1 == "Date:") { print substr($0, index($0, $3)) } }'
Nov 27 13:34:16 2017 -0800
Nov 26 21:18:34 2017 -0800

How can I "fix" this tag?

Ben Blank
  • 54,908
  • 28
  • 127
  • 156

2 Answers2

2

You're mostly there: you're making a new signed, annotated tag. You just have a typo:

GIT_COMMITER_DATE="Nov 26 18:14:17 2017 -0800" \

This should read:

GIT_COMMITTER_DATE="Nov 26 18:14:17 2017 -0800" \

(two T's in "committer"). But there's no obvious reason to force the tag time stamp back, since you're already making a new and different tag: you might as well just make a new signed tag with today's time-stamp.

Discussion

You must make a new signed tag (using, if you like, very similar contents and perhaps even the same tag-name, although before you re-use a tag name, you should read the documentation discussion on the topic). The issue here is that the signature is itself a cryptographic assertion about the tag's content, including the tag message and the commit hash of the target of the tag. This means that in the new signed tag, you must have a different signature.

Since it is a new and different tag, if there's a chance that anyone else has the old tag, it's wisest to just give the new tag a new name (see linked discussion). If there's no such chance, you can simply overwrite the old tag with -f. The special Git environment variables can be used to override the default timestamps.

torek
  • 448,244
  • 59
  • 642
  • 775
  • Good heavens, thwarted by a simple typo! Fortunately, this tag hasn't ever made it off my local dev box (I wanted to fix it, first), so I have no concerns there. As for my insistence on maintaining the original commit date, that's just to satisfy my near-obsession with bookkeeping! :-) – Ben Blank Nov 27 '17 at 23:02
1

In my tests, the syntax you used doesn't make the GIT_COMMITTER_DATE variable visible to the subsequent git command. I had better luck with

export GIT_COMMITTER_DATE=...

which of course you'd then want to un-set after running git. There may be other shorthand ways; this is just what worked for me.

Also make sure you're using a recognized date format. "YYYY-MM-DD hh:mm:ss" worked for me.

By the way, I don't think "author date" matters; AFAIK (and as far as the docs indicate) a tag would only worry about one date. In your output, the 2nd date is coming from the underlying commit (as you can see from the unprocessed show output).

So all of that said, one question... why? If the amended commit was done "unthinkingly", why not use the reflog to back it out and commit your other changes as a separate commit? Or, why is it a big deal that the tag date be retroactive anyway?

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52
  • I came to the same conclusion about author date, but was just throwing things at the wall to see what would stick at that point. I was, however, able to get it working (sans typo) with that command syntax and date format on bash 3.1.23 and git 2.5.0; I suppose I should have put those version numbers in my question! – Ben Blank Nov 27 '17 at 23:05
  • @BenBlank: Git's "approxidate" routine is pretty forgiving on inputs (with possibly hilariously wrong results without warning), but in general it should always take its own output as input. – torek Nov 27 '17 at 23:12