Jak usunąć zdalny tag?

3415

Jak usunąć tag Git, który został już wypchnięty?

markdorison
źródło

Odpowiedzi:

5745

Wystarczy wcisnąć „puste” odwołanie do nazwy zdalnego znacznika:

git push origin :tagname

Lub, bardziej konkretnie , użyj --deleteopcji (lub -djeśli Twoja wersja git jest starsza niż 1.8.0):

git push --delete origin tagname

Zauważ, że git ma przestrzeń nazw znaczników i przestrzeń nazw gałęzi, więc możesz użyć tej samej nazwy dla gałęzi i znacznika. Jeśli chcesz się upewnić, że nie możesz przypadkowo usunąć gałęzi zamiast tagu, możesz podać pełne odwołanie, które nigdy nie usunie gałęzi:

git push origin :refs/tags/tagname

Jeśli musisz również usunąć tag lokalny, użyj:

git tag --delete tagname

tło

Przekazywanie gałęzi, znacznika lub innego odwołania do zdalnego repozytorium wymaga określenia „które repozytorium, jakie źródło, jakie miejsce docelowe?”

git push remote-repo source-ref:destination-ref

Przykładem świata rzeczywistego, w którym wypychasz gałąź master do gałęzi master źródła, jest:

git push origin refs/heads/master:refs/heads/master

Które z powodu domyślnych ścieżek można skrócić do:

git push origin master:master

Tagi działają w ten sam sposób:

git push origin refs/tags/release-1.0:refs/tags/release-1.0

Które można również skrócić do:

git push origin release-1.0:release-1.0

Pomijając źródło ref (część przed dwukropkiem), wypychasz „nic” do miejsca docelowego, usuwając ref na odległym końcu.

Adam Franco
źródło
187
+1 za udzielenie odpowiedzi na pytanie i wyjaśnienie ogólnego przypadku oraz uszczegółowienie znaczenia nieskróconej składni
Peter Host
77
I na wypadek, gdyby ktoś zastanawiał się, jak usunąć wiele tagów jednocześnie, po prostu umieść je na liście za pomocą białych znaków, np git push --delete origin tag1 tag2 . To samo dotyczy usuwania tagów lokalnychgit tag -d tag1 tag2
dVaffection
8
Jeśli nazwa znacznika koliduje z nazwą oddziału, możesz skończyć z usunięciem oddziału. Ha ha. Zobacz drugą odpowiedź - jest bardziej ekologiczna
zuba
1
@ EmmaHe A tagjest dołączony tylko do jednego zatwierdzenia. Z tego powodu nazwa oddziału jest nieistotna.
cb2
1
Interesujące jest również to, że git tag -d `git tag`usuniesz wszystkie lokalne tagi. To samo dotyczy git push --delete origin `git tag`założenia, że ​​ściągnąłeś zdalne tagi lokalnie. Było to przydatne w środowisku testowym.
DarkFranX
382

Prostszym sposobem jest

git push --delete origin YOUR_TAG_NAME

Składnia dwukropka przed IMO jest w tej sytuacji trochę dziwna

quexer
źródło
4
Myślę, że to jest właściwy sposób ... inna składnia wygląda dla mnie bardziej na hacki.
Luigi R. Viggiano,
11
Tak, to jest proste i działa. Chociaż wyjaśnię odpowiedź, określając część zmienną: git push --delete origin "TAGNAME"gdzie TAGNAME to nazwa oryginalnego tagu.
Teemu Leisti
12
To działa. Jeden dodatek: jeśli masz gałąź i tag o tej samej nazwie, możesz umieścić słowo tagprzed nazwą tagu, aby mieć pewność, że otrzymasz tag, a nie gałąź.
andypaxo
9
@andypaxo Co komenda Wystarczy refspecs, poprawny sposób byłoby poprzedzenie tagi ze refs/tags/coś takiego: refs/tags/v2.3.1.
p3lim
Jakoś utworzyłem „zły” znacznik na zdalnym serwerze, który miał znaki specjalne, więc nie mogę się z nim zsynchronizować, więc po prostu usunąłem to z twoją sugestią: usługa git push - usunięcie źródła ”- <domyślny> - 151 ", nie można go usunąć nie za pomocą intellij, nie ze skrytki, nie z sourceTree. Dzięki !
Dmitri Algazin,
215

Jeśli masz zdalny tag v0.1.0do usunięcia, a Twój pilot to origin, to po prostu:

git push origin :refs/tags/v0.1.0

Jeśli musisz także usunąć tag lokalnie:

git tag -d v0.1.0

Zobacz odpowiedź Adama Franco , aby uzyskać wyjaśnienie niezwykłej :składni Git do usuwania.

Alex Dean
źródło
2
działa to również z jgit. Skrót: tag shorthand nie działa z jgit
rynop
Mam fatal: remote part of refspec is not a valid name in :/refs/tags/0.0.1...?
Chaim Eliyah,
3
@ChaimEliyah masz wiodący slash, może to twój problem
Joffrey
5
Lepsza odpowiedź, ponieważ działa to również, jeśli masz gałąź i tag, który nazywa się tak samo.
Erik A. Brandstadmoen
Po prostu :tagnamepowinien działać na zdalne usunięcie.
Acumenus
106

Usuń wszystkie tagi lokalne i uzyskaj listę zdalnych tagów :

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

Usuń wszystkie zdalne tagi

git tag -l | xargs -n 1 git push --delete origin

Wyczyść tagi lokalne

git tag -l | xargs git tag -d
Siddhartha Mukherjee
źródło
2
Jak usunąć wszystkie tagi z lokalnych i zdalnych repozytoriów. Właśnie tego szukałem, dzięki!
Jorge Orpinel,
git fetch, usuń zdalnie, a następnie posprzątaj mieszkańców, działał pięknie!
DiegoRBaquero
powolny, ale najprostszy
Lucent Fox
33

Aby usunąć znacznik ze zdalnego repozytorium:

git push --delete origin TAGNAME

Możesz także chcieć usunąć tag lokalnie:

git tag -d TAGNAME
Andrea
źródło
więc jedna linia do zrobienia obu:git push --delete origin TAGNAME && git tag -d TAGNAME
sakurashinken
25

Z poziomu terminala wykonaj następujące czynności:

git fetch
git tags
git tag -d {tag-name}
git push origin :refs/tags/{tag-name}

Teraz przejdź do Github.com i odśwież, znikają.

Mahmoud Zalt
źródło
3
tag git nie tagi
DSF
23
git tag -d your_tag_name
git push origin :refs/tags/your_tag_name
  1. Pierwsza linia usuwa your_tag_namez lokalnego repozytorium.
  2. Druga linia usuwa your_tag_namez zdalnego repo.
  3. Naciśnij przycisk Odrzuć wersję roboczą w sekcji Wydania GitHub .

wprowadź opis zdjęcia tutaj

kokabi
źródło
2
Chociaż to polecenie może odpowiedzieć na pytanie, zapewnienie dodatkowego kontekstu dotyczącego tego, dlaczego i / lub jak ten kod odpowiada na pytanie, poprawia jego długoterminową wartość. Jak odpowiedzieć
Popo
20

Usuń lokalny tag „12345”

git tag -d 12345

Usuń zdalny tag „12345” (np. Również wersja GitHub)

git push origin :refs/tags/12345

alternatywne podejście

git push --delete origin tagName
git tag -d tagName

wprowadź opis zdjęcia tutaj

Lyes CHIOUKH
źródło
15

Zauważ, że jeśli masz zdalną gałąź o nazwie jako tag zdalny, poniższe polecenia są niejednoznaczne:

git push origin :tagname
git push --delete origin tagname

Musisz więc użyć tego polecenia, aby usunąć znacznik:

git push origin :refs/tags/<tag>

i ten, aby usunąć gałąź:

git push origin :refs/heads/<branch>

Jeśli nie, pojawi się taki błąd:

error: dst refspec <tagname> matches more than one.
error: failed to push some refs to '<repo>'
Alex Vazquez Fente
źródło
Krótkie i zwięzłe. Ten post wraz z MeganZhou okazał się odpowiedzią na to, dlaczego mieliśmy problemy, nazwa gałęzi i zmienna były identyczne. Usunąłem lokalny tag i pchnąłem do: refs / tags i wszystko poszło dobrze.
rwheadon
12

Do 100 razy szybsza metoda dla tysięcy zdalnych tagów

Po przeczytaniu tych odpowiedzi i konieczności usunięcia ponad 11 000 tagów, nauczyłem się, że te metody polegają lub xargstrwają zbyt długo, chyba że masz godziny na spalenie.

Walcząc, znalazłem dwa znacznie szybsze sposoby. W obu przypadkach zacznij od git taglub, git ls-remote --tagsaby utworzyć listę znaczników, które chcesz usunąć na pilocie. W poniższych przykładach możesz pominąć lub zamienić na sorting_proccessing_etcdowolne greping, sorting, tailing lub heading ( np. grep -P "my_regex" | sort | head -n -200 Itp. ):


Ta pierwsza metoda jest zdecydowanie najszybsza, może od 20 do 100 razy szybsza niż użycie xargsi działa z co najmniej kilkoma tysiącami tagów jednocześnie.

git push origin $(< git tag | sorting_processing_etc \
| sed -e 's/^/:/' | paste -sd " ") #note exclude "<" for zsh

Jak to działa? Normalna lista tagów oddzielonych wierszami jest konwertowana na jeden wiersz tagów oddzielonych spacjami, każdy poprzedzony znakiem „ :tak”. . .

tag1   becomes
tag2   ======>  :tag1 :tag2 :tag3
tag3

Używanie git pushz tym formatem tagów nie wpycha niczego do każdego zdalnego odwołania, usuwając go (normalny format do przekazywania w ten sposób tolocal_ref_path:remote_ref_path ).

Metoda druga jest oddzielną odpowiedzią w innym miejscu na tej samej stronie


Po zastosowaniu obu tych metod prawdopodobnie prawdopodobnie również chcesz usunąć tagi lokalne. Jest to o wiele szybsze, więc możemy wrócić do używania xargsi git tag -d, co jest wystarczające.

git tag | sorting_processing_etc | xargs -L 1 git tag -d

LUB podobny do zdalnego usuwania:

git tag -d $(< git tag | sorting_processing_etc | paste -sd " ")
TonyH
źródło
Powinieneś podzielić to na kilka różnych odpowiedzi. Odpowiedź z wieloma znacznikami w jednym wierszu jest bez wątpienia właściwą odpowiedzią na zbiorcze usunięcie znaczników. Właściwie trudno jest znaleźć te informacje prawie gdzie indziej. Nawet wiedząc, czego szukam, z trudem znajduję to na stronie pomocy git :) Więc dziękuję i zaznacz to jako właściwą odpowiedź, i przenieś interfejs API GitHub w inne miejsce. I wreszcie, usuwanie tagów lokalnie, masowo, działa z tagami rozdzielanymi spacjami (pozbyć się dwukropków)
CubanX
Dzięki za pochwały i sugestie. Podzielę to. Nie rozumiem Twojego komentarza na temat usuwania tagów lokalnych. Nie sądzę, że mój ostatni fragment polecenia używa żadnych dwukropków, ale jestem na telefonie komórkowym, więc może czegoś brakuje.
TonyH
Przepraszam, chodziło mi o to, że to, co robisz, aby usunąć tagi zdalne, działa z usuwaniem tagów lokalnych, zapewniając całą listę na raz. :) Po prostu zamiast git push origin: tag1: tag2 itp. Zrobiłbyś git tag - usuń tag1 tag2 tag3 w ten sposób możesz uzyskać całkowite oczyszczenie. Jeszcze raz dziękuję za tonę!
CubanX
11

Jeśli używasz SourceTree - świetnego GUI Git - możesz to łatwo zrobić bez wiersza poleceń, wykonując następujące czynności:

  1. Otwórz swoje repozytorium w SourceTree
  2. Wybierz i rozwiń kartę „Tagi” po lewej stronie
  3. Kliknij prawym przyciskiem myszy znacznik, który chcesz usunąć
  4. Wybierz „Usuń YOUR_TAG_NAME”
  5. W oknie weryfikacji wybierz „Usuń tag z pilotów”

YOUR_TAG_NAME zostanie teraz usunięty z lokalnego repozytorium i wszystkich pilotów - czy to GitHub, BitBucket, czy gdziekolwiek indziej wymieniony jako zdalny dla tego repozytorium.

Ponadto, jeśli usunąłeś znacznik lokalnie, ale nie ze zdalnego źródła, i chcesz go usunąć wszędzie, po prostu utwórz nowy znacznik, który ma tę samą nazwę i jest dołączony do tego samego zatwierdzenia co źródła. Następnie powtórz powyższe kroki, aby usunąć wszędzie.

Chris Sprague
źródło
Działa jak marzenie. Dzięki!
Native_Mobile_Arch_Dev
9

Jeśli utworzyłeś znacznik wywoływany release01w repozytorium Git, usuniesz go z repozytorium, wykonując następujące czynności:

git tag -d release01 
git push origin :refs/tags/release01 

Aby usunąć jeden z repozytorium Mercurial:

hg tag --remove featurefoo

Proszę odnieść się do https://confluence.atlassian.com/pages/viewpage.action?pageId=282175551

MeganZhou
źródło
7

Jeśli używasz programu PowerShell i chcesz usunąć kilka z nich:

# Local tags:
git tag -l | foreach { git tag -d $_ }

# Remote tags:
git tag -l | foreach { git push --delete origin $_ }

Oczywiście możesz je również przefiltrować przed usunięciem:

git tag -l | Where-Object { $_ -like "build-*" } | foreach { git tag -d $_ }
rsenna
źródło
To był gładki i dobry przykład wyrażenia regularnego. Dzięki, proszę pana
Yunus
7

Zgodnie z sugestią @CubanX, podzieliłem tę odpowiedź z mojego oryginału:

Oto metoda, która jest kilka razy szybsza niż ta xargsi może skalować się znacznie bardziej z poprawkami. Korzysta z Github API , osobistego tokena dostępu i wykorzystuje narzędzie parallel.

git tag | sorting_processing_etc | parallel --jobs 2 curl -i -X DELETE \ 
https://api.github.com/repos/My_Account/my_repo/git/refs/tags/{} -H 
\"authorization: token GIT_OAUTH_OR_PERSONAL_KEY_HERE\"  \
-H \"cache-control: no-cache\"`

parallelma wiele trybów pracy, ale generalnie równolegle do każdej wydanej komendy, jednocześnie pozwalając ustawić limity liczby procesów. Możesz zmienić ten --jobs 2parametr, aby umożliwić szybsze działanie, ale miałem problemy z limitami prędkości Github , które obecnie wynoszą 5000 / godz., Ale wydaje się, że również mam nieudokumentowany limit krótkoterminowy.


Po tym prawdopodobnie prawdopodobnie będziesz chciał również usunąć tagi lokalne. Jest to o wiele szybsze, więc możemy wrócić do używania xargsi git tag -d, co jest wystarczające.

git tag | sorting_processing_etc | xargs -L 1 git tag -d
TonyH
źródło
Wydaje się to o wiele bardziej skomplikowane niż zaakceptowana odpowiedź. Jaka jest korzyść?
theUtherSide
2
Jeśli musisz usunąć kilka tysięcy tagów, prędkość jest 10-100 razy większa
TonyH
Dziękuję za wyjaśnienie. OP poprosił o usunięcie pojedynczego tagu. Nie mogłem sobie wyobrazić, dlaczego ktoś użyłby tego podejścia do pojedynczego tagu. Być może ta odpowiedź jest lepsza w przypadku innego pytania dotyczącego usunięcia wielu tagów
TheUtherSide
Nie sądzę, że istnieje. Mógłbym go stworzyć, aby samemu odpowiedzieć. Czy uważasz, że to jest właściwe?
TonyH
1
Ja robię! Myślę, że w rzeczywistości jest to dość powszechna praktyka.
theUtherSide
6

Inne odpowiedzi wskazują, jak to osiągnąć, ale należy pamiętać o konsekwencjach, ponieważ jest to zdalne repozytorium.

Strona podręcznika git tag w On Retagging , dobrze wyjaśnia, jak uprzejmie poinformować innych użytkowników zdalnego repo o zmianie. Dają nawet przydatny szablon ogłoszenia do komunikowania, w jaki sposób inni powinni uzyskać twoje zmiany.

Richard Venable
źródło
6

Chciałem usunąć wszystkie tagi oprócz tych, które pasują do wzorca, abym mógł usunąć wszystkie tagi produkcyjne oprócz ostatnich kilku miesięcy, oto co przyniosłem z wielkim sukcesem:

Usuń wszystkie zdalne tagi i wyklucz wyrażenie z Usuń

git tag -l | grep -P '^(?!Production-2017-0[89])' | xargs -n 1 git push --delete origin

Usuń wszystkie lokalne tagi i wyklucz wyrażenie z Usuń

git tag -l | grep -P '^(?!Production-2017-0[89])' | xargs git tag -d
Lucent Fox
źródło
5

Prosty skrypt do usunięcia podanego tagu z lokalizacji lokalnej i źródłowej. Sprawdzanie, czy tag naprawdę istnieje.

if [ $(git tag -l "$1") ]; then
    git tag --delete  $1
    git push --delete origin $1

    echo done.
else
    echo tag named "$1" was not found
fi

Jak używać:

  • Utwórz plik skryptu powłoki (np. Git-tag-purge.sh) i wklej zawartość.
  • chmod plik skryptu, aby był wykonywalny.
  • Udostępnij skrypt na całym świecie
  • cd do twojego projektu git
  • Skrypt wywoławczy (np
    $> git-tag-purge.sh nazwa_znacznika
    )
Dimitar Vlasev
źródło
4

Wydaje się, że dużo pracy nad czymś, co xargsjuż robi. Patrząc wstecz na ten wątek, domyślam się, że powolność, z xargsktórą się spotkałeś, jest spowodowana pierwotną odpowiedzią, xargs -n 1kiedy tak naprawdę nie było takiej potrzeby.

Jest to równoważne z twoją metodą, z tym wyjątkiem, że xargsautomatycznie zajmuje się maksymalną długością wiersza poleceń:

git tag | sorting_processing_etc | xargs git push --delete origin

xargspotrafi również uruchamiać procesy równolegle. Metoda 2 z xargs:

git tag | sorting_processing_etc | xargs -P 5 -n 100 git push --delete origin

Powyższe wykorzystuje maksymalnie 5 procesów do obsługi maksymalnie 100 argumentów w każdym procesie. Możesz eksperymentować z argumentami, aby znaleźć to, co najlepiej pasuje do twoich potrzeb.

HomerM
źródło
Ciekawy. Codziennie dowiadujesz się czegoś nowego o poleceniu Uniksa. Będę musiał przetestować mój przypadek użycia z tą alternatywą.
TonyH
4

Jeśli masz znacznik utworzony od znaku # , np. #ST002Możesz stwierdzić, że nie możesz go usunąć przy użyciu normalnych wzorców. to znaczy

git tag -d #STOO2

Nie usunie znacznika, ale zawinie go w literały łańcuchowe w ten sposób

git tag -d "#ST002" or git tag -d '#ST002'

To spowoduje jego usunięcie. Mam nadzieję, że pomoże to komuś, kto popełnił błąd przy użyciu # do pisania nazw znaczników.

MernXL
źródło
2

Oto lokalna skrzynka testowa do testowania lokalnego bez bałagania za pomocą pilota:

~/p $ mkdir gittest    
~/p/git $ cd gittest/
~/p/gittest $ git init
Initialized empty Git repository in /Users/local_user/p/gittest/.git/
 ~/p/gittest $ touch testfile.txt
 ~/p/gittest $ git add testfile.txt
 ~/p/gittest $ git commit -m "initial commit"
[master (root-commit) 912ce0e] initial commit
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 testfile.txt
 ~/p/gittest $ git tag
 ~/p/gittest $ git tag -a testtag
 ~/p/gittest $ git tag
testtag
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
b0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag
 ~/p/gittest $ cd ..
 ~/p $ mkdir gitbare
 ~/p $ cd gitbare
 ~/p/gitbare $ git init --bare
Initialized empty Git repository in /Users/local_user/p/gitbare/
 ~/p/gitbare $ cd ..
 ~/p $ cd gittest/
 ~/p/gittest $ git remote add origin /Users/local_user/p/gitbare
 ~/p/gittest $ git push -u origin master
Counting objects: 3, done.
Writing objects: 100% (3/3), 215 bytes | 215.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To /Users/local_user/p/gitbare
 * [new branch]      master -> master
Branch 'master' set up to track remote branch 'master' from 'origin'.
 ~/p/gittest $ git push origin testtag
Counting objects: 1, done.
Writing objects: 100% (1/1), 163 bytes | 163.00 KiB/s, done.
Total 1 (delta 0), reused 0 (delta 0)
To /Users/local_user/p/gitbare
 * [new tag]         testtag -> testtag
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master
b0a6c15cabb990e6d6c46f762891b63608d962f3 refs/tags/testtag
 ~/p/gittest $ git push -d origin testtag
To /Users/local_user/p/gitbare
 - [deleted]         testtag
 ~/p/gittest    git tag -d testtag
Deleted tag 'testtag' (was b0a6c15)
 ~/p/gittest $ git show-ref
912ce0e40635c90241fdab756dce7ea34938de57 refs/heads/master
912ce0e40635c90241fdab756dce7ea34938de57 refs/remotes/origin/master
 ~/p/gittest
Adnan Y
źródło
1

Cześć, chciałem tylko udostępnić utworzony alias, który robi to samo:

Dodaj następujące elementy do ~ / .gitconfig

[alias]
    delete-tag = "!f() { \
            echo 'deleting tag' $1 'from remote/origin ausing command: git push --delete origin tagName;'; \
            git push --delete origin $1; \
            echo 'deleting tag' $1 'from local using command: git tag -d tagName;'; \
            git tag -d $1; \
        }; f"

Użycie wygląda następująco:

-->git delete-tag v1.0-DeleteMe
deleting tag v1.0-DeleteMe from remote/origin ausing command: git push --delete origin tagName;
To https://github.com/jsticha/pafs
 - [deleted]             v1.0-DeleteMe
deleting tag v1.0-DeleteMe from local using command: git tag -d tagName;
Deleted tag 'v1.0-DeleteMe' (was 300d3ef22)
ranma2913
źródło