私たちは展開プロセスの一部としてgitのタグを使います。ときどき、これらのタグをリモートリポジトリから削除してクリーンアップします。
これはかなり簡単です。 1人のユーザーが1組のコマンドでローカルタグとリモートタグを削除します。両方のステップを組み合わせた小さなシェルスクリプトがあります。
2番目(3番目、4番目、...)のユーザーには、リモートに反映されなくなったローカルタグが追加されました。
リモートブランチが削除されているブランチをローカルで追跡するためにクリーンアップするgit remote Prune Origin
のようなコマンドを探しています。
あるいは、リモートタグを一覧表示する単純なコマンドを使用して、git tag -l
を介して返されたローカルタグと比較することもできます。
良い質問。完全な答えがありません。
そうは言っても、あなたはgit ls-remote
を通してリモートタグのリストを得ることができます。 Origin
によって参照されるリポジトリ内のタグを一覧表示するには、次のように実行します。
git ls-remote --tags Origin
次のようなハッシュとわかりやすいタグ名のリストが返されます。
94bf6de8315d9a7b22385e86e1f5add9183bcb3c refs/tags/v0.1.3
cc047da6604bdd9a0e5ecbba3375ba6f09eed09d refs/tags/v0.1.4
...
2f2e45bedf67dedb8d1dc0d02612345ee5c893f2 refs/tags/v0.5.4
このリストによって生成されたタグとあなたがローカルに持っているタグとを比較するためのbashスクリプトを確かに組み合わせることができます。 git show-ref --tags
を見てください。これはgit ls-remote
と同じ形式でタグ名を生成します。
余談ですが、git show-ref
にはあなたが望むものとは反対のことをするオプションがあります。次のコマンドは、あなたが持っていないローカルブランチにあるリモートブランチ上のすべてのタグを一覧表示します。
git ls-remote --tags Origin | git show-ref --tags --exclude-existing
これは大きな問題です。私は同じことを疑問に思っていました。
私はスクリプトを書きたくなかったので、別の解決策を探しました。重要なのは、タグをローカルに削除してから、git fetchを使用してリモートサーバーから「元に戻す」ことができることです。タグがリモートに存在しない場合は、削除されたままになります。
したがって、2行を順番に入力する必要があります。
git tag -l | xargs git tag -d
git fetch --tags
これら:
ローカルリポジトリからすべてのタグを削除します。 FWIW、xargsは "tag -l"によって出力された各タグを "tag -d"のコマンドラインに配置します。これがなければ、gitは何も削除しません(stdinを読んでいないので(愚かなgit))。
リモートリポジトリからすべてのアクティブなタグを取得します。
これはWindows上でも問題ありません。
Git v1.7.8からv1.8.5.6まで、これを使うことができます。
git fetch <remote> --Prune --tags
Commit e66ef7ae6f31f2 のため、これは新しいバージョンのgit(v1.9.0以降)では機能しません。それは何人かの人々のために働いたので私は本当にそれを削除したくない。
"Chad Juliano"によって示唆されているように、v1.7.8以降のすべてのGitバージョンでは、次のコマンドを使うことができます。
git fetch --Prune <remote> +refs/tags/*:refs/tags/*
ワイルドカード拡張を回避するために、タグ部分を引用符で囲む必要がある場合があります(Windowsの場合など)。
git fetch --Prune <remote> "+refs/tags/*:refs/tags/*"
リモートに存在するタグだけが必要な場合は、ローカルタグをすべて削除してください。
$ git tag -d $(git tag)
そして、すべてのリモートタグを取得します。
$ git fetch --tags
V1.7.8以降のGitのすべてのバージョンは、refspecでgit fetch
を理解しますが、v1.9.0以降、--tags
オプションは--Prune
オプションをオーバーライドします。汎用的な解決策として、これを試してください。
$ git --version
git version 2.1.3
$ git fetch --Prune Origin "+refs/tags/*:refs/tags/*"
From ssh://xxx
x [deleted] (none) -> rel_test
Git v1.9.0での "--tags"と "--Prune"の動作の違いについての詳細は、 https://github.com/git/git/commit/を参照してください。 e66ef7ae6f31f246dead62f574cc2acb75fd001c
最新バージョンのGit(私はgit v2.20を使っています)のように見えるので、単純に言うことができます。
git fetch --Prune --Prune-tags
ずっときれい!
https://git-scm.com/docs/git-fetch#_pruning
取得時に常にタグをプルーニングするようにgitを設定することもできます。
git config fetch.pruneTags true
特定のリモートから取得するときにタグを整理するだけの場合は、remote.<remote>.pruneTags
オプションを使用できます。たとえば、Originから取得するときに常にタグをプルーニングし、他のリモートからは取得しないようにするには、
git config remote.Origin.pruneTags true
Gitはローカルタグのクリーンアップをネイティブにサポートします。
git fetch --tags --Prune
このコマンドは最新のタグを取り込み、削除されたすべてのタグを削除します。
ローカルタグとリモートタグの違いを表示します。
diff <(git tag | sort) <( git ls-remote --tags Origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)
git tag
はローカルタグのリストを与えますgit ls-remote --tags
はリモートタグへのフルパスのリストを与えますcut -f2 | grep -v '\^' | sed 's#refs/tags/##'
は、リモートタグパスのリストからタグ名だけを解析します。"<"で始まる行はあなたのローカルタグで、もうリモートリポジトリにはありません。それらが少ない場合は、手動で1つずつ削除できます。多い場合は、自動化するためにさらに多くのグリップと配管を行います。
GitHubのpivotal_git_scripts Gem forkにgit sync-local-tagsコマンドを追加したばかりです。
https://github.com/kigster/git_scripts
Gemをインストールしてから、リポジトリに "git sync-local-tags"を実行してリモートに存在しないローカルタグを削除してください。
あるいは、以下のスクリプトをインストールして "git-sync-local-tags"と呼ぶこともできます。
#!/usr/bin/env Ruby
# Delete tags from the local Git repository, which are not found on
# a remote Origin
#
# Usage: git sync-local-tags [-n]
# if -n is passed, just print the tag to be deleted, but do not
# actually delete it.
#
# Author: Konstantin Gredeskoul (http://tektastic.com)
#
#######################################################################
class TagSynchronizer
def self.local_tags
`git show-ref --tags | awk '{print $2}'`.split(/\n/)
end
def self.remote_tags
`git ls-remote --tags Origin | awk '{print $2}'`.split(/\n/)
end
def self.orphaned_tags
self.local_tags - self.remote_tags
end
def self.remove_unused_tags(print_only = false)
self.orphaned_tags.each do |ref|
tag = ref.gsub /refs\/tags\//, ''
puts "deleting local tag #{tag}"
`git tag -d #{tag}` unless print_only
end
end
end
unless File.exists?(".git")
puts "This doesn't look like a git repository."
exit 1
end
print_only = ARGV.include?("-n")
TagSynchronizer.remove_unused_tags(print_only)
TortoiseGitは今タグを比較することができます。
左のログはリモートにあり、右のログはローカルにあります。
同期ダイアログのタグ比較機能を使用する:
@Richard Wと同じ回答ですが、Windows用(PowerShell)
git tag | foreach-object -process { git tag -d $_ }
git fetch -t
これはどうですか - すべてのローカルタグを削除してから再取得しますか?リポジトリを検討することはサブモジュールを含むかもしれません:
git submodule foreach --recursive 'git tag | xargs git tag -d'
(alternatively, "for i in `find .git -type d -name '*tags*'`; do rm -f $i/*; done")
git fetch -t
git submodule foreach --recursive git fetch -t