Usuń lokalne tagi Gita, które nie są już w zdalnym repozytorium

Używamy tagów w git jako część naszego procesu wdrażania. Od czasu do czasu chcemy wyczyścić te tagi, usuwając je z naszego zdalnego repozytorium.

To dość proste. Jeden użytkownik usuwa tag lokalny i tag zdalny w jednym zestawie poleceń. Mamy mały skrypt powłoki, który łączy oba kroki.

The 2nd( 3rd, 4th,...) użytkownik ma teraz lokalne tagi, które nie są już odzwierciedlane na pilocie.

Szukam komendy podobnej do git remote prune origin, która czyści lokalne gałęzie śledzące, dla których gałąź zdalna została usunięta.

Alternatywnie, można użyć prostego polecenia listy zdalnych tagów do porównania z lokalnymi tagami zwracanymi przez git tag -l.

 364
Author: Steven Vascellaro, 2009-12-03

11 answers

Dobre pytanie. :) Nie mam kompletnej odpowiedzi...

To powiedziawszy, możesz uzyskać listę zdalnych tagów za pośrednictwem git ls-remote. Aby wyświetlić listę tagów w repozytorium, do którego odwołuje się origin, należy uruchomić:

git ls-remote --tags origin

, który zwraca listę skrótów i przyjaznych nazw tagów, takich jak:

94bf6de8315d9a7b22385e86e1f5add9183bcb3c        refs/tags/v0.1.3
cc047da6604bdd9a0e5ecbba3375ba6f09eed09d        refs/tags/v0.1.4
...
2f2e45bedf67dedb8d1dc0d02612345ee5c893f2        refs/tags/v0.5.4

Z pewnością możesz stworzyć skrypt bash, aby porównać tagi generowane przez tę listę z tagami, które masz lokalnie. Spójrz na git show-ref --tags, który generuje nazwy znaczników w tej samej formie, co git ls-remote).


Na marginesie, git show-ref ma opcję, która robi przeciwieństwo tego, co chcesz. Poniższe polecenie wyświetli listę wszystkich tagów w zdalnej gałęzi, których nie posiadasz lokalnie :

git ls-remote --tags origin | git show-ref --tags --exclude-existing
 53
Author: Mike West,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-12-04 15:43:17

To świetne pytanie, zastanawiałam się nad tym samym.

Nie chciałem pisać scenariusza, więc szukałem innego rozwiązania. Kluczem jest odkrycie, że możesz usunąć tag lokalnie, a następnie użyć git fetch, aby "odzyskać go" ze zdalnego serwera. Jeśli znacznik nie istnieje na pilocie zdalnego sterowania, pozostanie on usunięty.

Dlatego musisz wpisać dwie linie w kolejności:

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

Te:

  1. Usuń wszystkie tagi z lokalnego repo. FWIW, xargs umieszcza każdy tag wyjście przez " tag-l "do wiersza poleceń dla"tag-d". Bez tego, git niczego nie usunie, ponieważ nie odczytuje stdin (silly git).

  2. Pobranie wszystkich aktywnych tagów ze zdalnego repo.

To działa nawet na Windows.

 833
Author: Richard W,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-07 08:43:17

Z Git v1.7.8 do v1.8. 5. 6, możesz użyć tego:

git fetch <remote> --prune --tags

Update

To nie działa na nowszych wersjach Gita (począwszy od v1. 9.0) z powodu commit e66ef7ae6f31f2. Tak naprawdę nie chcę go usuwać, ponieważ działało to dla niektórych ludzi.

Jak sugeruje "Chad Juliano" , ze wszystkimi wersjami Git od v1. 7. 8, możesz użyć następującego polecenia:

git fetch --prune <remote> +refs/tags/*:refs/tags/*

Może być konieczne załączenie części znaczników cudzysłowami (na przykład w systemie Windows), aby uniknąć wieloznaczności rozszerzenie:

git fetch --prune <remote> "+refs/tags/*:refs/tags/*"
 203
Author: loganfsmyth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-06 02:03:00

Jeśli chcesz tylko te tagi, które istnieją na zdalnym, usuń wszystkie lokalne tagi:

$ git tag -d $(git tag)

A następnie pobierz wszystkie zdalne tagi:

$ git fetch --tags
 113
Author: newmangt,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-31 21:35:29

Wszystkie wersje Gita od wersji 1.7.8 rozumieją git fetch z refspec, podczas gdy od wersji 1.9.0 opcja --tags nadpisuje opcję --prune. Aby uzyskać ogólne rozwiązanie, spróbuj tego:

$ git --version
git version 2.1.3

$ git fetch --prune origin "+refs/tags/*:refs/tags/*"
From ssh://xxx
 x [deleted]         (none)     -> rel_test

Aby dowiedzieć się więcej o zmianie zachowania "--tags" z "--prune" w Git v1.9.0, zobacz: https://github.com/git/git/commit/e66ef7ae6f31f246dead62f574cc2acb75fd001c

 64
Author: Chad Juliano,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-06 05:31:37

Jest to dobra metoda:

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

Źródło: demisx.GitHub.io

 5
Author: imjoseangel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-19 12:31:30

Pokaż różnicę między lokalnymi i zdalnymi tagami:

diff <(git tag | sort) <( git ls-remote --tags origin | cut -f2 | grep -v '\^' | sed 's#refs/tags/##' | sort)
  • git tag podaje listę lokalnych tagów
  • git ls-remote --tags wyświetla listę pełnych ścieżek do zdalnych tagów
  • cut -f2 | grep -v '\^' | sed 's#refs/tags/##' parsuje tylko nazwę znacznika z listy zdalnych ścieżek tagów
  • W końcu sortujemy każdą z dwóch list i różnicujemy je

Linie zaczynające się od "

 4
Author: dotstaraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-15 22:10:32

Właśnie dodałem polecenie Git sync-local-tags do widelca Gem pivotal_git_scripts na Githubie:

Https://github.com/kigster/git_scripts

Zainstaluj gem, a następnie uruchom "git sync-local-tags"w repozytorium, aby usunąć lokalne tagi, które nie istnieją na zdalnym.

Alternatywnie możesz zainstalować ten skrypt poniżej i nazwać go "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)
 3
Author: Konstantin Gredeskoul,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-12-14 23:12:30

Git natywnie obsługuje czyszczenie lokalnych tagów:

git fetch --tags --prune

To polecenie pobiera najnowsze tagi i usuwa wszystkie usunięte tagi.

 3
Author: Nirav Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-20 10:31:52

Co powiesz na to - zrzucić wszystkie lokalne tagi i ponownie pobrać? Biorąc pod uwagę, że Twój repo może zawierać podmoduły:

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
 1
Author: tetzu0,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-09 19:34:34

TortoiseGit może teraz porównywać tagi.

Lewy log jest na zdalnym, prawy na lokalnym.

Tutaj wpisz opis obrazka

Używanie funkcji porównywania tagów w oknie dialogowym synchronizacji:

Tutaj wpisz opis obrazka

Zobacz też Numer TortoiseGit 2973

 1
Author: Yue Lin Ho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-14 09:12:39