Po wykonaniu poniższych czynności pojawia się następujący błąd:
To [email protected]:username/repo-name.git
! [rejected] dev -> dev (already exists)
error: failed to push some refs to '[email protected]:username/repo-name.git'
hint: Updates were rejected because the tag already exists in the remote.
- Utworzono repozytorium
- Sklonowano repozytorium na komputerze lokalnym.
- Zmodyfikował plik README, zatwierdził zmiany i przekazał zatwierdzenie.
- Utworzony tag
dev
:git tag dev
- Przesłane tagi:
git push --tags
- Zmodyfikował plik README, zatwierdził zmiany i przekazał zatwierdzenie.
Usunięto tag
dev
, utworzyłem go ponownie i przekazałem tagi:git tag -d dev git tag dev git push --tags
Dlaczego to się dzieje?
Jestem na Macu. Moi znajomi, którzy używają Linuksa (Ubuntu), nie mają tego problemu. Wiem, że mogę git push --tags -f
wymusić aktualizację tagu, ale jest to niebezpieczne (np. Przepisanie popełnionego przez pomyłkę zatwierdzenia tylko w tagu, a nie w gałęzi).
git
repository
git-tag
Luca Boieru
źródło
źródło
git pull --tags
wtedygit push origin --tags
Odpowiedzi:
Edytuj, 24 listopada 2016 r .: ta odpowiedź jest najwyraźniej popularna, więc dodaję tutaj notatkę. Jeśli zastąpić tag na centralnym serwerze, kto ma stary Tag-dowolny klon tego repozytorium centralnego serwera, który ma już tag-mogła zachować swój stary znacznik . Więc chociaż mówi ci, jak to zrobić, upewnij się, że chcesz to zrobić. Będziesz musiał poprosić wszystkich, którzy mają już „zły” tag, aby usunął swój „zły tag” i zastąpił go nowym „właściwym tagiem”.
Testowanie w Git 2.10 / 2.11 pokazuje, że zachowanie starego tagu jest domyślnym zachowaniem dla działających klientów
git fetch
, a aktualizacja jest domyślnym zachowaniem dla działających klientówgit fetch --tags
.(Oryginalna odpowiedź jest następująca.)
Kiedy prosisz o wypchnięcie tagów,
git push --tags
wysyła (wraz z wszelkimi zatwierdzeniami i innymi potrzebnymi obiektami oraz innymi aktualizacjami referencyjnymi z ustawień wypychania) do pilota żądanie aktualizacji formularza . (Cóż, wysyła dowolną liczbę: po jednym dla każdego tagu.)new-sha1 refs/tags/name
Żądanie aktualizacji jest modyfikowane przez pilota w celu dodania
old-sha1
(lub ponownie jednego dla każdego znacznika), a następnie dostarczane do zaczepów przed odbiorem i / lub aktualizacją (niezależnie od tego, które z zaczepów istnieją na pilocie). Te haki mogą decydować, czy zezwolić, czy odrzucić tworzenie / usuwanie / aktualizację znacznika.old-sha1
Wartość jest all-Zera „null” SHA-1, jeśli znacznik jest tworzony. Tonew-sha1
jest zerowy SHA-1, jeśli tag jest usuwany. W przeciwnym razie obie wartości SHA-1 są rzeczywistymi, prawidłowymi wartościami.Nawet bez haków istnieje rodzaj „wbudowanego haka”, który jest również uruchamiany: pilot odmówi przeniesienia taga, chyba że użyjesz flagi „wymuś” (chociaż „wbudowany zaczep” jest zawsze OK z obydwoma „dodaj” i „usuń”). Komunikat o odrzuceniu, który widzisz, pochodzi z tego wbudowanego hooka. (Nawiasem mówiąc, ten sam wbudowany punkt zaczepienia odrzuca również aktualizacje gałęzi, które nie są szybkie do przodu.) 1
Ale - oto jeden z kluczy do zrozumienia, co się dzieje -
git push
krok nie ma pojęcia, czy pilot ma teraz ten znacznik, a jeśli tak, jaką ma wartość SHA-1. Mówi tylko „oto moja pełna lista tagów, wraz z ich wartościami SHA-1”. Pilot porównuje wartości i jeśli są dodatki i / lub zmiany, uruchamia na nich przechwyty. (W przypadku tagów, które są takie same, w ogóle nic nie robi. W przypadku tagów, których nie masz, to one również nie robią!)Jeśli usuniesz tag lokalnie, to
push
naciśnięcie po prostu nie przenosi tagu. Pilot zakłada, że nie należy wprowadzać żadnych zmian.Jeśli usuniesz tag lokalnie, a następnie utwórz go wskazując nowe miejsce, wtedy
push
twoje naciśnięcie przenosi tag, a pilot postrzega to jako zmianę tagu i odrzuca zmianę, chyba że jest to wymuszenie.Masz więc dwie możliwości:
To ostatnie jest możliwe za pomocą
git push
2, mimo że lokalne usunięcie taga ipush
nie ma żadnego efektu. Zakładając, że nazwa pilota toorigin
, a tag, który chcesz usunąć, todev
:To prosi pilota o usunięcie tagu. Obecność lub brak tagu
dev
w lokalnym repozytorium nie ma znaczenia; ten rodzajpush
, jako refspec, jest wypychaniem czystego usuwania.:remoteref
Pilot może, ale nie musi, pozwolić na usunięcie tagu (w zależności od dodanych dodatkowych haków). Jeśli pozwoli to na usunięcie, tag zniknie, a po
git push --tags
chwili, gdy masz lokalnydev
znacznik wskazujący na jakiś obiekt repozytorium tagów zatwierdzonych lub z adnotacjami, wyślij nowydev
tag. Na pilociedev
będzie teraz nowo utworzony tag, więc pilot prawdopodobnie pozwoli na wypchnięcie (znowu zależy to od dodanych dodatkowych haków).Pchnięcie siły jest prostsze. Jeśli chcesz mieć pewność, nie do niczego aktualizacji innych niż tagu, po prostu powiedz
git push
naciskać tylko jeden refspec:(uwaga: nie musisz tego robić,
--tags
jeśli jawnie wypychasz tylko jeden tag ref-spec).1 Oczywiście powodem tego wbudowanego punktu zaczepienia jest pomoc w egzekwowaniu zachowania, którego oczekują inni użytkownicy tego samego zdalnego repozytorium: gałęzie nie są przewijane, a tagi nie poruszają się. Jeśli naciskasz na siłę, powinieneś poinformować innych użytkowników, że to robisz, aby mogli to poprawić. Zwróć uwagę, że „tagi w ogóle się nie poruszają” zostało na nowo wymuszone przez Git 1.8.2; poprzednie wersje umożliwiały znacznikowi „przesuwanie do przodu” na wykresie zmian, podobnie jak w przypadku nazw gałęzi. Zobacz informacje o wydaniu git 1.8.2 .
2 To trywialne, jeśli możesz zalogować się na pilocie. Po prostu przejdź do repozytorium Git i uruchom
git tag -d dev
. Zwróć uwagę, że w każdym przypadku - usuwając znacznik na pilocie lub używając gogit push
do usunięcia - istnieje okres, w którym każdy, kto uzyska dostęp do pilota, stwierdzi, żedev
brakuje tagu. (Będą one nadal mają swój stary tag, jeśli już masz, a może nawet przesunąć swój stary tag z powrotem w górę, zanim będzie można wcisnąć nowy).źródło
1.7.9.5
i nie mam tego problemu ...git push --tags
automatycznej zmiany tagu w starszych wersjach gita, bez--force
. Przetestowałem to jednak pod 1.8.4 i potrzebujesz--force
, lub dwuetapowej techniki aktualizacji.W Mac SourceTree tylko odznacz pole wyboru Push all tags :
źródło
Jest to dość proste, jeśli używasz SourceTree .
Zasadniczo wystarczy usunąć i ponownie dodać kolidujący tag:
źródło
Jeśli chcesz ZAKTUALIZOWAĆ tag, powiedzmy to
1.0.0
git checkout 1.0.0
git ci -am 'modify some content'
git tag -f 1.0.0
git push origin --delete 1.0.0
git push origin 1.0.0
GOTOWE
źródło
Wygląda na to, że spóźniłem się z tą kwestią i / lub została już udzielona, ale co można zrobić to: (w moim przypadku miałem tylko jeden tag lokalnie, więc ... Usunąłem stary tag i ponownie oznaczyłem go tagiem :
Następnie:
To zaktualizuje wszystko tagi na pilocie.
Może być niebezpieczne! Używaj na własne ryzyko.
źródło
Powód, dla którego jesteś odrzucany jest utrata synchronizacji tagu z wersją zdalną. To samo dotyczy gałęzi.
zsynchronizuj z tagiem z pilota przez,
git pull --rebase <repo_url> +refs/tags/<TAG>
a po synchronizacji musisz zarządzać konfliktami . Jeśli masz zainstalowany diftool (np. Meld),git mergetool meld
użyj go do synchronizacji pilota i zachowania zmian.Powodem, dla którego ciągniesz z flagą --rebase, jest to, że chcesz umieścić swoją pracę na zdalnym, aby uniknąć innych konfliktów.
Nie rozumiem też, dlaczego miałbyś usunąć
dev
tag i ponownie go utworzyć? Tagi służą do określania wersji oprogramowania lub punktów kontrolnych. Przykłady znaczników gitv0.1dev
,v0.0.1alpha
,v2.3-cr
(Cr - uwalnianie kandydat), itd ..Innym sposobem rozwiązania tego problemu jest problem a
git reflog
i przejście do momentu, w którym wcisnąłeśdev
tag na pilocie. Skopiuj identyfikator zatwierdzenia, a dziękigit reset --mixed <commmit_id_from_reflog>
temu będziesz mieć pewność, że tag był zsynchronizowany z pilotem w momencie jego naciśnięcia i nie pojawią się żadne konflikty.źródło
W systemie Windows SourceTree odznacz
Push all tags to remotes
.źródło
Kilka dobrych odpowiedzi. Szczególnie ten autorstwa @torek . Pomyślałem, że dodam to obejście z małym wyjaśnieniem dla tych, którzy się spieszą.
Podsumowując, dzieje się tak, że gdy przenosisz znacznik lokalnie, zmienia on znacznik z wartości zatwierdzenia innej niż Null na inną wartość. Jednakże, ponieważ git (jako domyślne zachowanie) nie pozwala na zmianę zdalnych tagów innych niż Null, nie możesz wypchnąć zmiany.
Rozwiązaniem jest usunięcie tagu (i zaznaczenie opcji usuń wszystkie piloty). Następnie utwórz ten sam tag i wciśnij.
źródło