Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Script to prune any tags which exist locally but not on the remote
#!/usr/bin/env ruby
require 'readline'
def prompt(prompt="> ")
input = nil
prompt += " " unless prompt =~ /\s$/
loop do
input = Readline.readline(prompt)
break if input.length > 0
return input
remote = ARGV[0]
dry_run = ARGV.include?("--dry-run")
if !remote || remote == "--dry-run"
puts "no remote specified, assuming 'origin'"
remote = "origin"
local_tags = `git tag`.split("\n")
remote_tags = []
remote_tag_details = `git ls-remote --tags #{remote}`.split("\n")
remote_tag_details.each do |details|
sha, tag = details.split("\t")
next if tag[-3, 3] == "^{}"
remote_tags << tag.gsub(%r(^refs/tags/), '')
delete_tags = []
local_tags.each do |local_tag|
next if remote_tags.include?(local_tag)
puts "local tag '#{local_tag}' not found in '#{remote}'"
delete_tags << local_tag
if delete_tags.empty?
abort "No tags found locally which aren't on '#{remote}'"
if dry_run
puts "#{delete_tags.size} tags would have been deleted, run without --dry-run to do the deed"
response = prompt("Are you sure you want to delete these tags? (yn)")
if response.downcase.strip =~ /^y/
delete_tags.each do |local_tag|
`git tag -d #{local_tag}`
puts "#{delete_tags.size} tags have been deleted"
puts "Aborted"

Awesome. Just what I was looking for. Thanks!

aferouz commented Nov 24, 2014

What is the license for this code?

If not copyrighted would you mind adding:
Not copyrighted -- provided to the public domain

lfilho commented Jun 9, 2015

Just do:

git tag -l | xargs git tag -d
git fetch

Won't that delete every local tag?

@julias-shaw yes it will
Isn't this the idea of pruning is to remove local tags that no longer exist on the remote?
This will make it so you're up to date with the remote 1:1.
If you want to keep your local clean though this is not for you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment