LoginSignup
88
47

More than 3 years have passed since last update.

【git tag】プッシュしたtag名を削除・変更してはいけない理由〜manコマンドで読めるgitメンテナの怒り〜

Last updated at Posted at 2020-11-30

一度プッシュしたtagは、名前変更・削除してはならない

プッシュしたtag名を削除・変更してはいけない理由は、git tagのmanコマンドの中で説明されている。

manコマンドの内容は、コマンドの使い方を淡々と説明している印象があり、今まであまり読んでこなかった。
しかしgit tagのmanコマンドではとても人間味のある文章が書かれていた。

感情部分だけ要約すると、
「tag名を変更するのは馬鹿げている!!絶対にするなよ!!
それでもやりたいって?じゃあこうやれ!馬鹿げたやり方だけどな!!
それは面倒だって?やるならこれしかないんだよ!(怒)」

という筆者の熱い思いが文章で綴られている。

それでは見ていこう。

manコマンドをみてみる

下記コマンドで該当の記述を読むことが出来る

man git-tag

web上で見たい場合はこちらでも。

原文

該当の記述はこちら

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.

意訳

怒りの部分が分かるように意訳していく。

pushしていないtagは変更して良い

-fオプションを使って名前を付け替えるだけで良い。

pushしたけどtag名を変更したくなった場合

push済みの場合、他の作業者がpushしたtagをみている可能性がある。
その場合出来る方法は2つある。

1.健全なやり方(sane thing)

まずはやらかしたことを認めろ。そして違うタグ名を使え。
(わざわざ「健全な」とつけたり、やらかしたことを最初に認めさせたりと怒りが沸き始めている
もし同じ名前で新しい内容でtagを作った場合、同じversion Xという名前なのに、人によって違う内容を指している状態ができてしまう。
あなたはversion X.1など別の名前を使いなさい。

2.狂気的なやり方(insane thing)

(もうワードが強い。怒りに溢れている)
あなたがどーしても同じtag名で新しい内容を指したいのであれば、
それも既に他の作業者がpushしたtagを既にみているのにどーしてもやりたいのであれば、
-fオプションでforce pushすれば良い。まるでまだtagをpushしていなかったかのようにね。
(やっても良いと言う割に、節々に嫌味っぽい怒りを感じる)

tagを変更したとしても、他の作業者のtagがあなたの更新で上書かれるわけではない

しかし、Gitはユーザーの見えないところでtagを変更することはしないし、するべきではない。
すなわち、古いtagが既にある状態でgit pullをしても、新しいtagが上書かれることはない。
同じレポジトリの作業者がtag名を「必ず」信頼出来る状態でなければならない。
(manコマンドらしく、知るべき前提情報を淡々と説明してある)

それでも狂気的なやり方をやりたい場合

まず大騒ぎして、他の作業者に自分がやらかしたことを報告し、下記の内容をレポジトリの全ての作業者に大々的に告知しなければならない。
(罪を償え!と言われている気がしてならない)

告知すべき内容

私はやらかしました。
tag Xを新たなバージョンとしてpushしました。
もし間違った(古い)タグを取得してしまい更新する必要がある方は、古いtagを削除し、新しいtagをfetchしてください。
コマンドは下記です。

git tag -d X
git fetch origin tag X

下記コマンドで最新のtagを取得しているか確認することができます。

git rev-parse X

正しければ0123456789abcdefが表示されます。
ご不便をおかけし申し訳ありません。

やり方が複雑だって?やるべきだ!

自動的に「修正」する方法なんて他にない。
(「修正」が強調されているのは、やっていることが修正ではなく「狂気な所業」なので、修正というものばからしい、のニュアンスが入っている)
他の作業者は自分が触っているtagが変更されている可能性があるなら知らされるべきだ。

manコマンドから感じられた怒りと要点まとめ

とりあえず、remoteのtagを変更したらgitメンテナがめっちゃ怒ることは感じられたと思う。
git tagでのベストプラクティスは、

  • tagは1度pushしたら変更はしない
  • どうしても変えたくなったら別のtag名を新たに付与する

こと。
理由

  • gitの思想的に、tag名によってtagが一意に決定され存在が保証されるべき
  • tag変更後他の作業者がpullをしても、tag名の上書きは行われない
  • 上書きを行いたかったら、全ての作業者が取得済みのtagを消してfetchし直す必要がある

ことである。

もし「tagを変えたい」とチーム内で相談されたら、
「やれないことはないけどめんどくさいよ。
あと、gitメンテナがめっちゃ怒るよ」

と伝えるようにしよう。

このmanコマンドを書いた人は何者?

この人間味を溢れる記述を書いたのは、なんと日本人エンジニア
お名前は濱野純さん。
該当のコミットはこちらからgithub上で見れる。

濱野純さんはLinuxの生みの親リーナス・トーバルズから信頼されたGitメンテナであり、Googleのエンジニアである。

濱野 純 (はまの じゅん、英語: Junio C Hamano) は、カリフォルニア在住[1]の日本のソフトウェア工学者(英語版)である。現在はGoogleに勤務している[2]。最初のリリースから2ヶ月後の2005年7月26日からGitのメンテナであることで知られている[3][4]。リーナス・トーバルズは2012年に、Gitが彼にとっての最大の成功の1つとなったのは、濱野がGitの開発において優秀な開発者であることによると認識しており、メンテナとして彼を信頼していると述べた[5]。

引用:wikipediaより https://ja.wikipedia.org/wiki/%E6%BF%B1%E9%87%8E%E7%B4%94

まとめ

gitメンテナの怒りを買わないように、tagは変えずに新しく作ろう!

関連書籍

GitHub実践入門
新卒エンジニア向け課題図書。
結局gitで難しいのはコマンドの扱い方ではなく、git上での他の作業者との円滑なやり取りだったりする。
gitを使ったチームでの開発フローに関して、何かしら読んでから現場に入ってもらえるとスムーズに感じる。

88
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
88
47