Wednesday, March 27, 2013

Git Tagging Makes Up for a Lot!

In the past, I've been rather indifferent both to git and to tagging. My main complaint about how tagging works in most other VCS systems is that it makes it too easy for folks to keep moving the tags around.

It is therefore with great joy that I read the following in the help text for "git tag":

On Re-tagging

  What should you do when you tag a wrong commit and you
  would want to re-tag?

  If you never pushed anything out, just re-tag it.
  Use "-f" to replace the old one. And you're done.

  But if you have pushed things out (or others could
  just read your repository directly), then others will
  have already seen the old tag. In that case you can
  do one of two things:

    1. The sane thing. Just admit you screwed up, and
       use a different name. Others have already seen
       one tag-name, and if you keep the same name,
       you may be in the situation that two people both
       have "version X", but they actually have different
      "X"'s. So just call it "X.1" and be done with it.

    2. The insane thing. You really want to call the new
       version "X" too, even though others have already seen
       the old one. So just use git tag -f again, as if you
       hadn't already published the old one.

  However, Git does not (and it should not) change tags behind
  users back. So if somebody already got the old tag, doing a
  git pull on your tree shouldn't just make them overwrite the
  old one.

  If somebody got a release tag from you, you cannot just change
  the tag for them by updating your own one. This is a big
  security issue, in that people MUST be able to trust their tag
  names. If you really want to do the insane thing, you need
  to just fess up to it, and tell people that you messed up.
  You can do that by making a very public announcement saying:

       Ok, I messed up, and I pushed out an earlier version
       tagged as X. I then fixed something, and retagged the
       *fixed* tree as X again.

       If you got the wrong tag, and want the new one, please
       delete the old one and fetch the new one by doing:

              git tag -d X
              git fetch origin tag X

       to get my updated tag.
       You can test which tag you have by doing

              git rev-parse X

       which should return 0123456789abcdef.. 
       if you have the new version.

       Sorry for the inconvenience.

  Does this seem a bit complicated? It should be. There is no way
  that it would be correct to just "fix" it automatically. People
  need to know that their tags might have been changed.

I am now a git convert. Yay! ...and how do you do moving tags? Well, you don't! Use a branch instead, and fast forward it to whatever location you want to go. Want to go backwards, well, don't. Branch out and revert, and later use "git merge -s ours" to re-unite the moving branch to its parent.