Tak, to naprawdę źle, yada yada, ale z jakiegoś powodu muszę to lubić.
James Morris,
44
Wiem, że to głupie, ale czasami zdarza się gówno - na przykład testowanie logowania i używanie w kodzie haseł tekstowych, które są prawdziwymi danymi uwierzytelniającymi. I
ups
6
prawdziwe dane logowania. Tak, przypomina mi się whoopos
Jestem bardzo zmęczony tą akademicką grą o tym, jak niebezpieczne jest to i jak nigdy nie należy tego robić Yada Yada. Są chwile, w których zdecydowanie lepiej jest usuwać rzeczy z historii gitów i radzić sobie z konfliktami / łamaniem innych deweloperów. To naprawdę takie proste. Ludzie, którzy to ignorują, prawdopodobnie nigdy nie pracowali poza klasą.
zmiażdżyć
Odpowiedzi:
368
Jesteś git reset --hardoddziałem lokalnym, aby usunąć zmiany z działającego drzewa i indeksu, a git push --forceTwój zmieniony oddział lokalny do pilota. ( inne rozwiązanie tutaj , obejmujące usunięcie zdalnej gałęzi i ponowne jej przekazanie)
Ta SO odpowiedź ilustruje niebezpieczeństwo takiego polecenia, szczególnie jeśli ludzie polegają na odległej historii swoich lokalnych repozytoriów.
Musisz być przygotowany, aby wskazać ludziom do wychodzenie z UPSTREAM rebase części git rebasestrony man
Dziwne. Czuję, że już tego próbowałem. W połączeniu z pewnymi zmianami - działa jak urok. Dzięki.
Arnis Lapsa,
7
@Arnis: idealny wtedy;) na push --forcewyjeździe
VonC
Użyłem BFG Repo-Cleaner, aby pozbyć się wrażliwych danych, które pozostawiły mnie z „nienazwanym” odgałęzieniem z oryginalnym plikiem na nim, po zresetowaniu do ostatniego poszukiwanego zatwierdzenia i twardego wypychania do źródła, wszystko poszło dobrze (:
Rodrirokr
Zauważ, że adres URL zatwierdzenia jest nadal aktywny (przynajmniej przez jakiś czas), więc jeśli ktoś ma adres URL zatwierdzenia (dałeś go bogu, wie dlaczego), będzie mógł uzyskać dostęp do kodu.
Idealna, elegancka, najprostsza odpowiedź. Właśnie wróciłem do ostatniego zatwierdzenia dźgnięcia, którego potrzebowałem zarówno zdalnie, jak i lokalnie
lauWM,
2
To spowodowało, że straciłem także lokalne zmiany. Nie spodziewałem się tego. Ale lepiej, niż podanie osobistego hasła do repozytorium pracy.
Airwavezx
3
możesz zapisać lokalne zmiany za pomocą git stash .... zrób kilka rzeczy ... i git stash pop (twoje lokalne zmiany powróciły)
MonTea
To daje mi błąd jako „zdalny: błąd: odmawianie
ref
@Airwavezx, co git reset --hardpowinno zrobić.
Łukasz
146
Ważne: Upewnij się, że określiłeś, które gałęzie na „git push -f”, w przeciwnym razie możesz przypadkowo zmodyfikować inne gałęzie! [*]
W tym samouczku pokazano trzy opcje . W przypadku zerwania linku zostawię tutaj główne kroki.
Upewnij się, że określiłeś, które gałęzie na "git push <remote_repo> <remote_branch> -f", albo możesz przypadkowo zmodyfikować inne gałęzie!
Nigel Sheridan-Smith
Tylko kroki 1 i 2 wykonały zadanie i odpowiedziały na oryginalne pytanie. (Nie uruchamiaj kroku 3)
Saad Benbouzid
Są to opcje dla różnych scenariuszy, a nie kroki do podjęcia. W moim przypadku interaktywny rebase (Opcja 3) zrobił to, czego szukałem.
Steve Blackwell
Musiałem jednak zrobić krok 3. Dlaczego nie powinieneś uruchomić tego @ Saada? Na szczęście mój <<remote>> był po prostu domyślnym „początkiem”, a <remote_branch> domyślnym „mistrzem”
Bart
30
Jeśli chcesz usunąć na przykład ostatnie 3zatwierdzenia, uruchom następujące polecenie, aby usunąć zmiany z systemu plików (drzewa roboczego) i zatwierdzić historię (indeks) w lokalnym oddziale:
git reset --hard HEAD~3
Następnie uruchom następujące polecenie (na komputerze lokalnym), aby zmusić zdalny oddział do przepisania historii:
Następnie można wymienić HEAD~Nw <desired-commit-id>ten sposób:
git reset --hard <desired-commit-id>
Jeśli chcesz zachować zmiany w systemie plików i po prostu zmodyfikować indeks (historię zatwierdzeń), użyj --softflagi jak git reset --soft HEAD~3. Następnie masz szansę sprawdzić najnowsze zmiany i zachować lub upuścić wszystkie lub ich części. W drugim przypadku runnig git statuspokazuje pliki zmienione od tego czasu <desired-commit-id>. Jeśli użyjesz --hardopcji, git statuspowie ci, że twój oddział lokalny jest dokładnie taki sam jak oddział zdalny. Jeśli nie używasz --hardani --soft, używany jest tryb domyślny --mixed. W tym trybie git help resetmówi:
Resetuje indeks, ale nie działające drzewo (tzn. Zmienione pliki są zachowane, ale nie są oznaczone do zatwierdzenia) i zgłasza, co nie zostało zaktualizowane.
To może być za mało za późno, ale pomogła mi fajnie brzmiąca opcja „nuklearna”. Zasadniczo za pomocą polecenia filter-branchmożesz usunąć pliki lub zmienić coś w dużej liczbie plików w całej historii git.
Nie jest za późno. Może się przydać wędrowcom z podobnymi problemami :)
Arnis Lapsa
9
Uproszczenie z odpowiedzi pctroll, podobnie na podstawie tego postu na blogu .
# look up the commit id in git log or on github, e.g. 42480f3, then do
git checkout master
git checkout your_branch
git revert 42480f3
# a text editor will open, close it with ctrl+x (editor dependent)
git push origin your_branch
# or replace origin with your remote
Działa dla mnie, dzięki. I chcę trwale usunąć jedno zatwierdzenie (np. Zawiera pwd) ze zdalnej historii oddziału, jak to zrobić?
Uśmiecha się
1
Działa również dla mnie, ale mam takie samo pytanie jak Smiles, nie chcę, aby ktokolwiek widział moje zatwierdzenie / pogłos w historii ... jak to usunąć?
Roberto Rodriguez
4
Czasami najłatwiejszym sposobem rozwiązania tego problemu jest utworzenie nowej gałęzi z miejsca, w którym wiesz, że kod jest dobry. Następnie możesz zostawić błędną historię oddziału w spokoju, na wypadek, gdybyś musiał później wybrać inne zatwierdzenia. Zapewnia to również, że nie straciłeś historii zatwierdzeń.
Z lokalnego oddziału, który popełnił błąd:
git log
skopiuj skrót zatwierdzenia, w którym chcesz, aby gałąź była w, i zamknij dziennik git
Jeśli potrzebujesz również zachować konkretne zatwierdzenie z błędnego oddziału, którego nie ma w nowym oddziale, możesz po prostu wybrać konkretny zatwierdzenie, którego potrzebujesz:
git checkout the_errant_branch
git log
Skopiuj skrót zatwierdzenia jednego zatwierdzenia, którego potrzebujesz, aby pobrać do dobrej gałęzi i zamknąć dziennik git.
Odpowiedzi:
Jesteś
git reset --hard
oddziałem lokalnym, aby usunąć zmiany z działającego drzewa i indeksu, agit push --force
Twój zmieniony oddział lokalny do pilota. ( inne rozwiązanie tutaj , obejmujące usunięcie zdalnej gałęzi i ponowne jej przekazanie)Ta SO odpowiedź ilustruje niebezpieczeństwo takiego polecenia, szczególnie jeśli ludzie polegają na odległej historii swoich lokalnych repozytoriów.
Musisz być przygotowany, aby wskazać ludziom do wychodzenie z UPSTREAM rebase części
git rebase
strony manZ Git 2.23 (sierpień 2019, dziewięć lat później) użyjesz nowego polecenia
git switch
.To znaczy: (zastąp liczbą zatwierdzeń do usunięcia)
git switch -C mybranch origin/mybranch~n
n
To przywróci indeks i działające drzewo, tak jak
git reset --hard
zrobiłby to.źródło
push --force
wyjeździegit gc
nie zawsze jest uruchamiana wystarczająco często po stronie zdalnej. Na przykład na GitHub: twitter.com/githubhelp/status/387926738161774592?lang=esPamiętaj tylko, aby użyć
last_working_commit_id
, gdy cofasz niedziałający zatwierdzenieNie możemy więc zresetować tego
commit_id
, czego nie chcemy.W takim razie musimy przesłać do zdalnej gałęzi:
źródło
git reset --hard
powinno zrobić.Ważne: Upewnij się, że określiłeś, które gałęzie na „git push -f”, w przeciwnym razie możesz przypadkowo zmodyfikować inne gałęzie! [*]
W tym samouczku pokazano trzy opcje . W przypadku zerwania linku zostawię tutaj główne kroki.
1 Cofnij pełne zatwierdzenie
2 Usuń ostatni zatwierdzenie
lub, jeśli oddział jest dostępny lokalnie
gdzie + dd61 ... jest twoim hashem zatwierdzającym, a git interpretuje x ^ jako element nadrzędny x, a + jako wymuszone nie-fastforwared push.
3 Usuń zatwierdzenie z listy
Otworzy się i edytor pokaże listę wszystkich zatwierdzeń. Usuń ten, którego chcesz się pozbyć. Ukończ bazę i wciśnij siłę, aby wykonać repo.
źródło
Jeśli chcesz usunąć na przykład ostatnie
3
zatwierdzenia, uruchom następujące polecenie, aby usunąć zmiany z systemu plików (drzewa roboczego) i zatwierdzić historię (indeks) w lokalnym oddziale:Następnie uruchom następujące polecenie (na komputerze lokalnym), aby zmusić zdalny oddział do przepisania historii:
Gratulacje! Wszystko gotowe!
Niektóre uwagi:
Możesz pobrać żądany identyfikator zatwierdzenia, uruchamiając
Następnie można wymienić
HEAD~N
w<desired-commit-id>
ten sposób:Jeśli chcesz zachować zmiany w systemie plików i po prostu zmodyfikować indeks (historię zatwierdzeń), użyj
--soft
flagi jakgit reset --soft HEAD~3
. Następnie masz szansę sprawdzić najnowsze zmiany i zachować lub upuścić wszystkie lub ich części. W drugim przypadku runniggit status
pokazuje pliki zmienione od tego czasu<desired-commit-id>
. Jeśli użyjesz--hard
opcji,git status
powie ci, że twój oddział lokalny jest dokładnie taki sam jak oddział zdalny. Jeśli nie używasz--hard
ani--soft
, używany jest tryb domyślny--mixed
. W tym trybiegit help reset
mówi:źródło
To może być za mało za późno, ale pomogła mi fajnie brzmiąca opcja „nuklearna”. Zasadniczo za pomocą polecenia
filter-branch
możesz usunąć pliki lub zmienić coś w dużej liczbie plików w całej historii git.Najlepiej to wyjaśniono tutaj .
źródło
Uproszczenie z odpowiedzi pctroll, podobnie na podstawie tego postu na blogu .
źródło
Czasami najłatwiejszym sposobem rozwiązania tego problemu jest utworzenie nowej gałęzi z miejsca, w którym wiesz, że kod jest dobry. Następnie możesz zostawić błędną historię oddziału w spokoju, na wypadek, gdybyś musiał później wybrać inne zatwierdzenia. Zapewnia to również, że nie straciłeś historii zatwierdzeń.
Z lokalnego oddziału, który popełnił błąd:
skopiuj skrót zatwierdzenia, w którym chcesz, aby gałąź była w, i zamknij dziennik git
Teraz masz nowy oddział tak, jak chcesz.
Jeśli potrzebujesz również zachować konkretne zatwierdzenie z błędnego oddziału, którego nie ma w nowym oddziale, możesz po prostu wybrać konkretny zatwierdzenie, którego potrzebujesz:
Skopiuj skrót zatwierdzenia jednego zatwierdzenia, którego potrzebujesz, aby pobrać do dobrej gałęzi i zamknąć dziennik git.
Poklep się po plecach.
źródło
źródło