Jak zmienić nazwę tagu Git?

1219

Dzisiaj przeglądałem dzienniki projektu i zdałem sobie sprawę, że jakiś czas temu natknąłem się na nazwę tagu. Czy jest jakiś sposób na zmianę nazwy tagu? Google nie znalazł niczego przydatnego.

Zdaję sobie sprawę, że mogłem sprawdzić oznakowaną wersję i stworzyć nowy tag, nawet tego spróbowałem. Ale wydaje się, że tworzy to obiekt znacznika, który nie jest całkiem właściwy. Po pierwsze

git tag -l

wyświetla listę nie uporządkowaną względem wszystkich innych tagów. Nie mam pojęcia, czy to znaczące, ale prowadzi mnie do przekonania, że ​​nowy obiekt znacznika nie jest dokładnie tym, czego chcę. Mogę z tym żyć, ponieważ naprawdę dbam tylko o to, aby nazwa znacznika była zgodna z dokumentacją, ale wolę zrobić to „dobrze”, zakładając, że jest to właściwy sposób.

Brandon Fosdick
źródło
Czy użyłeś tego samego wywołania, tj. Jeśli stary znacznik był opatrzony adnotacjami / podpisany, to czy nowy znacznik jest również tego rodzaju, czy też jest lekki?
Jakub Narębski
1
Zarówno stary niepoprawny tag, jak i pożądany nowy tag powinny być opatrzone adnotacjami i niepodpisane. Stary tag został utworzony za pomocą „git tag -a bad_tag_name”, więc chciałbym zrobić coś w stylu „git tag -a good_tag_name”.
Brandon Fosdick
Powinienem zaznaczyć, że chcę również, aby ten proces magicznej zmiany nazwy tagu zachował adnotację z powodu zmiany nazwy tagu. Tak naprawdę chciałbym zmienić tylko nazwę i nic więcej.
Brandon Fosdick
7
git log --oneline --decorate --graphjest pomocny podczas czyszczenia tagów.
Joel Purra
Możesz zmienić nazwę znacznika w jednym wierszu: patrz moja odpowiedź poniżej
VonC

Odpowiedzi:

2037

Oto jak zmienić nazwę tagu oldna new:

git tag new old
git tag -d old
git push origin :refs/tags/old
git push --tags

Dwukropek w poleceniu push usuwa znacznik ze zdalnego repozytorium. Jeśli tego nie zrobisz, Git utworzy stary znacznik na twoim komputerze, gdy go pociągniesz.

Na koniec upewnij się, że inni użytkownicy usuwają usunięty tag. Powiedz im (współpracownikom), aby uruchomili następujące polecenie:

git pull --prune --tags

Zauważ, że jeśli zmieniasz znacznik z adnotacjami , musisz upewnić się, że nazwa nowego znacznika odnosi się do bazowego zatwierdzenia, a nie starego obiektu znacznika z adnotacjami, który zamierzasz usunąć. Dlatego używaj git tag -a new old^{}zamiast git tag new old(to dlatego, że tagi z adnotacjami są obiektami, podczas gdy tagi lekkie nie są, więcej informacji w tej odpowiedzi ).

Casey Watson
źródło
19
jeśli tag jest opatrzony adnotacją, nowy tag nie będzie zawierał wiadomości o starej, ale jest to przydatna informacja
NickSoft
25
@NickSoft, właśnie zrobiłem powyższe z tagami z adnotacjami. Wiadomości zostały skopiowane ze starej do nowej, dobrze. Może mam nowszą wersję git?
katyhuff 19.04.13
25
git push origin :refs/tags/oldgit push origin :oldmyślę, że można to uprościć .
Jesse Glick
25
Sugerowałbym zmianę słowa „git push --tags”, aby było bardziej wyraźne w tym znaczniku „git push origin refs / tags / new”. Nie chcesz przypadkowo popchnąć innych tagów.
chrish
11
Ostrzeżenie : Użycie git tag new oldspowoduje utworzenie znacznika wskazującego stary znacznik, a nie zatwierdzenie starego znacznika. (Zobacz Dlaczego nie mogę pobrać mojego tagu z Git GUI? )
Stevoisiak
297

Oryginalny pytanie, jak zmienić nazwę znacznik, który jest prosty: najpierw utworzyć nowe jako alias starych: git tag NEW OLDnastępnie usunąć stare: git tag -d OLD.

Cytat dotyczący „sposobu Gita” i (nie) zdrowia psychicznego jest nie na miejscu, ponieważ mówi o zachowaniu nazwy znacznika, ale o odwołaniu go do innego stanu repozytorium.

Greg McGary
źródło
3
Odpowiedź powyżej jest nieco lepsza, ponieważ obejmuje git push originfirmę.
Roly
najprościej, działaj świetnie, aby zmienić nazwę poprzedniego tagu wydania utworzonego za pomocą Gitflow
RousseauAlexandre,
5
Ostrzeżenie : Użycie git tag new oldspowoduje utworzenie znacznika wskazującego stary znacznik, a nie zatwierdzenie starego znacznika. (Zobacz Dlaczego nie mogę pobrać mojego tagu z Git GUI? )
Stevoisiak
118

Oprócz innych odpowiedzi:

Najpierw trzeba zbudować alias o starej nazwie znacznika, wskazując na oryginale popełnić:

git tag new old^{}

Następnie musisz usunąć stary lokalnie :

git tag -d old

Następnie usuń tag ze zdalnych lokalizacji:

# Check your remote sources:
git remote -v
# The argument (3rd) is your remote location,
# the one you can see with `git remote`. In this example: `origin`
git push origin :refs/tags/old

Wreszcie musisz dodać nowy tag do zdalnej lokalizacji. Dopóki tego nie zrobisz, nowe tagi nie zostaną dodane:

git push origin --tags

Iteruj to dla każdej zdalnej lokalizacji.

Pamiętaj o konsekwencjach, jakie zmiana Git Tag ma dla konsumentów pakietu!

kajzer
źródło
Ostrzeżenie : Użycie git tag new oldspowoduje utworzenie znacznika wskazującego stary znacznik, a nie zatwierdzenie starego znacznika. (Zobacz Dlaczego nie mogę pobrać mojego tagu z Git GUI? )
Stevoisiak
1
@StevenVascellaro Dzięki za link. Następnym razem prześlij edycję - udzielenie odpowiedzi to również wysiłek społeczności. Dzięki.
kaiser
Nie dokonałem edycji, ponieważ nie przetestowałem jeszcze kodu dla siebie. (Zwróć uwagę na datę przesłania powiązanego pytania)
Stevoisiak
Gdy to zrobimy git tag new old^{}, nie będziemy potrzebować git tag new_tag_name old_tag_name(pierwszy krok).
Number945
28

Jeśli jest opublikowany, nie można go usunąć (bez ryzyka smołowania i upierzania). „Sposób Git” polega na:

Rozsądna rzecz. Po prostu przyznaj, że spieprzyłeś i użyj innej nazwy. Inni widzieli już jedną nazwę znacznika, a jeśli zachowasz tę samą nazwę, możesz być w sytuacji, że obie osoby mają „wersję X”, ale tak naprawdę mają różne „X”. Więc po prostu nazwij to „X.1” i gotowe.

Alternatywnie,

Szalona rzecz. Naprawdę chcesz nazwać nową wersję „X”, nawet jeśli inni już widzieli starą. Więc po prostu ponownie użyj git-tag -f, tak jakbyś nie opublikował jeszcze starego.

To takie szalone, ponieważ:

Git nie zmienia (i nie powinien) zmieniać tagów za użytkownikami. Więc jeśli ktoś już ma starą etykietkę, wykonanie polecenia git-pull na twoim drzewie nie powinno po prostu zmusić go do zastąpienia starego.

Jeśli ktoś dostał od ciebie tag wydania, nie możesz po prostu zmienić dla niego tagu poprzez aktualizację własnego. Jest to duży problem bezpieczeństwa, ponieważ ludzie MUSZĄ mieć zaufanie do swoich tagów. Jeśli naprawdę chcesz zrobić szaloną rzecz, musisz po prostu przyznać się do tego i powiedzieć ludziom, że popełniłeś błąd.

Wszystko dzięki uprzejmości stron man .

Robert Munteanu
źródło
6
Lub możesz oznaczyć (z prawidłową nazwą) ten niepoprawnie nazwany tag.
Jakub Narębski
6
Dzięki, już milion razy przeglądałem tę stronę podręcznika. Na szczęście zły tag nie został nigdzie opublikowany. Nawet jeśli tak, to jest to projekt wewnętrzny i jestem jedynym programistą (na razie). Myślę, że jestem dość bezpieczny zarówno przed tarowaniem, jak i wtapianiem, ale tylko wtedy, gdy uda mi się uzyskać repozytorium pasujące do dokumentów.
Brandon Fosdick
Czasami używam tagów do własnych osobistych odniesień. Na przykład. może to być tag „ok_jb”. Korzystam z tego, ponieważ niektórzy ludzie, z którymi pracuję, nie mogą budować na mojej platformie, więc czasami pojawią się błędy kompilacji. Następnie mogę szybko uzyskać wersję, która buduje, sprawdzając ten tag. Kiedy nowe źródła się kompilują, po prostu przesuwam znacznik lub zmieniam jego nazwę na kompilacje ##, gdzie ## to liczba (w zależności od projektu). Mogę również podkreślić, kiedy wprowadzono specjalną funkcję, dodając tag.
7
Słaba odpowiedź. „Nie rób tego” nigdy nie jest prawidłową odpowiedzią na „Jak to zrobić?”. Użytkownik nie pytał, czy uważasz, że to jest dobry pomysł, czy ludziom się to spodoba. Jeśli ktoś zapyta „Jak mogę odciąć rękę”, powiedz mu, jak to się robi, lub zostaw go w spokoju, ale nie będzie potrzebował, aby ktoś powiedział mu, że obcięcie ręki może nie być tak dobrym pomysłem. I możesz to zrobić. Możesz dodać nowy tag i usunąć stary, jest to technicznie możliwe, nawet w zdalnym repozytorium.
Mecki
5
To wydaje się odpowiadać na pytanie „Jak sprawić, aby istniejący tag wskazywał inną wersję?” zamiast pytania OP: „Jak zmienić nazwę tagu?” Nie jest również jasne, w jaki sposób informowanie osób, które pomieszałeś, rozwiąże problem (mimo że ogólnie jest to dobry pomysł).
LarsH
25

Ta strona wiki ma ten interesujący jeden wiersz, który przypomina nam, że możemy przesłać kilka odnośników :

git push origin <refs/tags/old-tag>:<refs/tags/new-tag> :<refs/tags/old-tag> && git tag -d <old-tag>

i poproś o to innych klonerów git pull --prune --tags

Pomysł polega więc na:

  • <new-tag>dla każdego zatwierdzeń odwołuje <old-tag>: <refs/tags/old-tag>:<refs/tags/new-tag>,
  • usunięcie<old-tag> ::<refs/tags/old-tag>

Zobacz jako przykład „ Zmienić konwencję nazewnictwa tagów w repozytorium git? ”.

VonC
źródło
Czy to zachowuje adnotacje?
Brandon Fosdick
1
Uwaga: pozostawia to oryginalną nazwę znacznika w adnotacji znaczników z adnotacjami !! Nie jestem jednak pewien, czy to coś sugeruje, przynajmniej w obecnych wersjach.
gbr
@gbr Czy możesz edytować odpowiedź za pomocą przykładu pokazującego, że w adnotacji pozostała „oryginalna nazwa znacznika”?
VCC,
1
@VonC Nie jestem pewien, czy rozumiem, o co pytasz; może nie byłem jasny: obiekty adnotacji zawierają pole znacznika, które jest ustawione na nazwę znacznika, możesz to zobaczyć za pomocą git cat-file -p <tag>; dzięki twojej metodzie w moim systemie otrzymuję tag ref ( <new-tag>) o zmienionej nazwie , ale jego pole tagu jest nadal <old-tag>.
gbr
3
@gbr Czy to, czego chciał PO? Wspomniał „Powinienem zaznaczyć, że chcę również, aby ten proces magicznej zmiany nazwy znacznika zachował adnotację związaną ze zmianą nazwy znacznika. W rzeczywistości chciałbym zmienić tylko nazwę i nic więcej” ( stackoverflow.com/questions/1028649/ how-do-you-rename-a-git-tag /… )
VonC
25

Jako dodatek do innych odpowiedzi, dodałem alias, aby zrobić to wszystko w jednym kroku, z bardziej znanym dotykiem polecenia * nix move. Argument 1 to stara nazwa znacznika, argument 2 to nowa nazwa znacznika.

[alias]
    renameTag = "!sh -c 'set -e;git tag $2 $1; git tag -d $1;git push origin :refs/tags/$1;git push --tags' -"

Stosowanie:

git renametag old new
Jared Knipp
źródło
To nie dla mnie, ponieważ nie udało się !sh(pytania dotyczące systemu Windows GIT), jednak po aktualizacji format do następujących, to działało: renametag = "!f() { git tag $2 $1; git tag -d $1; git push origin :refs/tags/$1; git push --tags; }; f".
Sunny Patel
10

Postępuj zgodnie z 3-etapowym podejściem do jednego lub kilku tagów.

Krok 1: Określ identyfikator zatwierdzenia / obiektu zatwierdzenia, na który wskazuje bieżący znacznik

     command: git rev-parse <tag name>
     example: git rev-parse v0.1.0-Demo
     example output: db57b63b77a6bae3e725cbb9025d65fa1eabcde

Krok 2: Usuń tag z repozytorium

     command: git tag -d <tag name>
     example: git tag -d v0.1.0-Demo
     example output: Deleted tag 'v0.1.0-Demo' (was abcde)

Krok 3: Utwórz nowy znacznik wskazujący ten sam identyfikator zatwierdzenia, na który wskazywał stary znacznik

     command: git tag -a <tag name>  -m "appropriate message" <commit id>
     example: git tag -a v0.1.0-full  -m "renamed from v0.1.0-Demo" db57b63b77a6bae3e725cbb9025d65fa1eabcde
     example output: Nothing or basically <No error>

Gdy lokalny git jest gotowy ze zmianą nazwy znacznika, zmiany te można odesłać z powrotem do źródła, aby inni mogli je pobrać.

Vikas pachisia
źródło
Brakuje kroków, aby odepchnąć usunięty tag: git push origin :refs/tags/v0.1.0-Demoi odepchnąć tagi (wraz z innymi sprawami w toku)git push --tags
Star Wolf
6

Dla żądnych przygód można to zrobić za pomocą jednego polecenia:

mv .git/refs/tags/OLD .git/refs/tags/NEW
wolfc
źródło
7
To nie zadziała, jeśli twoje git gc
referencje
2
Wpłynie to również na lokalne repozytorium. Jeśli masz skonfigurowanego pilota, nie jestem pewien, jakie negatywne skutki może to spowodować. Nie polecam tego podejścia.
therealklanni
1
Zauważ też, że w przypadku tagów z adnotacjami będzie to prawdopodobnie jeszcze bardziej kłopotliwe, ponieważ kropelka „adnotacji” zawiera między innymi oryginalną nazwę tagu. Właściwie nie jestem pewien, czy jest to używane przez coś (mam nadzieję, że przynajmniej przez tag-weryfikacji), ale nie zaryzykuję.
gbr
1
@gbr Działa to dobrze. (Oczywiście należy wziąć pod uwagę uwagę @forivall.) Ta sztuczka była masowo używana od wieków w systemie kompilacji ALT Syzyf. Zobacz, jak są przechowywane źródła pakietu, np .: git.altlinux.org/gears/g/gear.git . Znaczniki czytelne, takie jak 2.0.7-alt1, to podpisane znaczniki przesłane przez opiekunów do systemu kompilacji. Kryptyczne tagi gb-sisyphus-task164472.200 są tam umieszczane przez system kompilacji w celu śledzenia identyfikatora zadania, które zbudowało i opublikowało pkg z tego źródła. Są to głupie kopie ( cp) z nietkniętą wiadomością opiekuna.
imz - Ivan Zachharyaschev
@ imz - IvanZakharyaschev Dobrze wiedzieć, nie ufałbym jednak zbytnio, że w przypadku niektórych produktów nie spowoduje to problemów w przyszłości; nie ma prawdziwej specyfikacji formatu repozytoriów git i oczekiwanej interakcji, więc gdy będzie to wykonalne, staram się robić rzeczy w czysty sposób w najmniej zaskakujący sposób
gbr
3

Niezależnie od problemów związanych z wypychaniem tagów i zmianą nazw tagów, które zostały już wypchnięte, w przypadku, gdy tag do zmiany nazwy jest opatrzony adnotacjami , możesz go najpierw skopiować dzięki poniższemu wierszowi poleceń:

git tag -a -m "`git cat-file -p old_tag | tail -n +6`" new_tag old_tag^{}

Następnie wystarczy usunąć stary tag:

git tag -d old_tag

Znalazłem ten wiersz poleceń dzięki następującym dwóm odpowiedziom:

Edycja:
Po napotkaniu problemów z automatyczną synchronizacją ustawień tagów fetch.pruneTags=true(jak opisano w https://stackoverflow.com/a/49215190/7009806 ), osobiście sugeruję najpierw skopiować nowy tag na serwerze, a następnie usunąć stary. W ten sposób nowy znacznik nie jest losowo usuwany podczas usuwania starego znacznika, a synchronizacja znaczników chciałaby usunąć nowy znacznik, który nie jest jeszcze na serwerze . Na przykład razem otrzymujemy:

git tag -a -m "`git cat-file -p old_tag | tail -n +6`" new_tag old_tag^{}
git push --tags
git tag -d old_tag
git push origin :refs/tags/old_tag
Olivier
źródło
3

Możesz także zmienić nazwę zdalnych znaczników bez ich sprawdzania, powielając stary znacznik / gałąź do nowej nazwy i usuwając stary, w jednym git pushpoleceniu.

Zdalne tag zmiany nazwy / Remote oddział → konwersja tag: (Wskazówka: :refs/tags/)

git push <remote_name> <old_branch_or_tag>:refs/tags/<new_tag> :<old_branch_or_tag>

Zdalny oddział rename / tag zdalnego → konwersja Branża: (Wskazówka: :refs/heads/)

git push <remote_name> <old_branch_or_tag>:refs/heads/<new_branch> :<old_branch_or_tag>

Wyjście zmieniające nazwę zdalnego tagu:

D:\git.repo>git push gitlab App%2012.1%20v12.1.0.23:refs/tags/App_12.1_v12.1.0.23 :App%2012.1%20v12.1.0.23

Total 0 (delta 0), reused 0 (delta 0)
To https://gitlab.server/project/repository.git
 - [deleted]               App%2012.1%20v12.1.0.23
 * [new tag]               App%2012.1%20v12.1.0.23 -> App_12.1_v12.1.0.23
zionyx
źródło