gitブランチのタグを別のコミットに移動するにはどうすればよいですか?


858

私はマスターブランチに次のv0.1ようなタグを作成しました:

git tag -a v0.1

しかし、私はリリース0.1のマスターにマージする必要があるいくつかの変更がまだあることに気付いたので、それを行いました。しかし、今私のv0.1タグは(ポストイットのアナロジーを呼び出すために)間違ったコミットでスタックしています。マスターの最新のコミットでスタックしたいのですが、代わりに、マスターの2番目に新しいコミットでスタックします。

マスターの最新のコミットに移動するにはどうすればよいですか?

回答:


1200

-fオプションを使用してgit tag

-f
--force

    Replace an existing tag with the given name (instead of failing)

-fと一緒に使用して-a、注釈の付いていないタグの代わりに注釈付きのタグを強制的に作成することをお勧めします。

  1. プッシュする前にリモコンのタグを削除してください

    git push origin :refs/tags/<tagname>
    
  2. 最新のコミットを参照するようにタグを置き換えます

    git tag -fa <tagname>
    
  3. タグをリモートの原点にプッシュする

    git push origin master --tags
    

90
プッシュする前に、次のようにして、リモートのタグを削除することをお勧めします。git push origin :refs/tag/<tagname>次に、を実行git tag -fa <tagname>git push origin master --tagsます。そうしないと、リモートのrefsリストに^と{}文字が追加されて、奇妙なものになる可能性があります。これを指摘してくれたcodebasehq.comのDanに感謝します。
eedeep

47
@eedeep:マイナー修正-代わりにに:refs/tag/<tagname>する必要があります:refs/tags/<tagname>
Ben Hocking

8
これは、コードをマシンからプッシュしていない場合にのみ機能します。もしそうなら、最善の答えは「世界にはたくさんの数字がある」ということです。おそらくそれは面倒なことに値しないでしょう。
Chris Huang-Leaver 2013

33
タグを既にプッシュしている場合でも、リモートタグを強制プッシュで更新できますgit push -f origin <tagname>
rc_luke

11
こことドキュメントで言及されていないのは、新しいメッセージが提供されない場合、これは実際にタグメッセージを移動することです。
Twonky

259

より正確には、タグを強制的に追加してから、オプション--tagsおよび-fを使用してプッシュする必要があります。

git tag -f -a <tagname>
git push -f --tags

171

リモートが呼び出されoriginmasterブランチで作業している場合をまとめると:

git tag -d <tagname>
git push origin :refs/tags/<tagname>
git tag <tagname> <commitId>
git push origin <tagname>
  • 1行目は、ローカル環境のタグを削除します。
  • 2行目は、リモート環境のタグを削除します。
  • 3行目でタグを別のコミットに追加します
  • 4行目は、変更をリモートにプッシュします。

また、4行目を交換git push origin --tagsして、ローカルの変更からすべての変更をタグでプッシュすることもできます。

@ stuart-golodetz、@ greg-hewgill、@ eedeep、@ ben-hockingの回答、回答の下のコメント、私の回答の下のNateSコメントに基づいています。


87

で削除git tag -d <tagname>してから、正しいコミットで再作成してください。


3
@eedeep:私はグレッグの反応が実際にはここで公平である方が良いと思います。
スチュアートゴロデッツ

複雑にしないでおく。それを削除し、もう一度前にやったことをしてください。
ooolala 2016年

1
簡単にするために、これは受け入れられる答えになるはずです。また、-f forceを過度に使用しないでください。
chinnychinchin

48

Gitを使用するときは、いくつかのことを回避しようとします。

  1. 内部の知識、例えばrefs / tagsの使用。文書化されたGitコマンドのみを使用し、.gitディレクトリの内部コンテンツの知識を必要とするものは使用しないようにします。(つまり、私はGitをGitユーザーとして扱い、Git開発者として扱いません。)

  2. 不要な場合の力の使用。

  3. やりすぎ。(ブランチや多数のタグをプッシュして、必要な場所に1つのタグを取得します。)

そこで、Gitの内部についての知識がなくても、ローカルとリモートの両方でタグを変更するための非暴力的な解決策を紹介します。

最終的にソフトウェア修正に問題があり、更新/再リリースする必要がある場合に使用します。

git tag -d fix123                # delete the old local tag
git push github :fix123          # delete the old remote tag (use for each affected remote)
git tag fix123 790a621265        # create a new local tag
git push github fix123           # push new tag to remote    (use for each affected remote)

githubはサンプルのリモート名、fix123はサンプルのタグ名、790a621265サンプルのコミットです。


26

ここでは、自分のニーズに合ったこのコマンドの別の形式だけを残します。移動したい
タグがありましたv0.0.1.2

$ git tag -f v0.0.1.2 63eff6a

Updated tag 'v0.0.1.2' (was 8078562)

その後:

$ git push --tags --force

良い、2つの無地でシンプルなコマンドありがとう
セルジオ

10

もう1つの方法:

リモートリポジトリのタグを移動します(必要に応じてHEADを他のリポジトリに置き換えます)。

$ git push --force origin HEAD:refs/tags/v0.0.1.2

変更を取り戻します。

$ git fetch --tags

これは他の回答よりも「トランザクション」です。
ジャスティンM.キーズ

9

1つのタグを別のコミットに移動するエイリアス。

サンプルで、ハッシュe2ea1639を使用してコミットを移動するには、次のようにします。 git tagm v0.1 e2ea1639

プッシュされたタグには、 git tagmp v0.1 e2ea1639

どちらのエイリアスも元の日付とメッセージを保持します。使用する場合git tag -dと、元のメッセージが失われます。

それらを.gitconfigファイルに保存します

# Return date of tag. (To use in another alias)
tag-date = "!git show $1 | awk '{ if ($1 == \"Date:\") { print substr($0, index($0,$3)) }}' | tail -2 | head -1 #"

# Show tag message
tag-message = "!git show $1 | awk -v capture=0 '{ if(capture) message=message\"\\n\"$0}; BEGIN {message=\"\"}; { if ($1 == \"Date:\" && length(message)==0 ) {capture=1}; if ($1 == \"commit\" ) {capture=0}  }; END { print message }' | sed '$ d' | cat -s #"

### Move tag. Use: git tagm <tagname> <newcommit> 
tagm = "!GIT_TAG_MESSAGE=$(git tag-message $1) && GIT_COMMITTER_DATE=$(git tag-date $1) && git tag-message $1 && git tag -d $1 && git tag -a $1 $2 -m \"$GIT_TAG_MESSAGE\" #"

### Move pushed tag. Use: git tagmp <tagname> <newcommit> 
tagmp = "!git tagm $1 $2 && git push --delete origin $1 && git push origin $1 #"

1

注釈付きタグを移動したい場合は、ターゲットのコミットのみを変更し、注釈メッセージとその他のメタデータは保持します。

moveTag() {
  local tagName=$1
  # Support passing branch/tag names (not just full commit hashes)
  local newTarget=$(git rev-parse $2^{commit})

  git cat-file -p refs/tags/$tagName | 
    sed "1 s/^object .*$/object $newTarget/g" | 
    git hash-object -w --stdin -t tag | 
    xargs -I {} git update-ref refs/tags/$tagName {}
}

使用法:moveTag <tag-to-move> <target>

上記の関数は、teerapap / git-move-annotated-tag.shを参照して開発されました


1
これはもう必要ないようです:git tag -f -a my_tagすでに前のメッセージのメッセージを保持しています(gitバージョン2.11.0)。
Matthijs Kooijman
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.