Jak usunąć pierwszy commit w git?

179

Jestem ciekawy, jak usunąć pierwszy commit w git.

Jaka jest rewizja przed popełnieniem jakiejkolwiek rzeczy? Czy ta wersja ma nazwę lub tag?

Jian Weihang
źródło
2
Na początek z git, powinieneś wiedzieć, że wersja jest bez znaczenia. Możesz mówić o zatwierdzeniach lub ich względnych SHA. Poza tym, dlaczego chcesz to zrobić? Na pierwszym zatwierdzeniu wszystko jest zbudowane. Możesz zgnieść kilka zatwierdzeń razem, w tym pierwsze zatwierdzenie, które stanie się nowym pierwszym zatwierdzeniem, ale co to znaczy nawet usunąć pierwszy zatwierdzenie (lub usunąć każde oprócz ostatniego)?
Shahbaz
@Shahbaz yeah, to najlepszy sposób, spójrz tutaj na przykład: ariejan.net/2011/07/05/git-squash-your-latests-commits-into-one
timaschew
5
Możesz użyć git rebase -i --root. Zobacz następującą odpowiedź SO, aby uzyskać szczegółowe informacje: stackoverflow.com/questions/2246208/ ...
MKroehnert
Ta odpowiedź ma poprawne rozwiązanie, aby usunąć zatwierdzenie root z bieżącej gałęzi:git filter-branch --parent-filter "sed 's/-p <the_commit>//'" HEAD
Jody Bruchon

Odpowiedzi:

320

Dla mnie najbezpieczniejszym sposobem jest użycie update-refpolecenia:

git update-ref -d HEAD

Usunie to odniesienie o nazwie HEAD, więc zresetuje (delikatnie, nie stracisz pracy) wszystkie twoje zatwierdzenia z twojej aktualnej gałęzi .

Jeśli chcesz scalić pierwszy commit z drugim, możesz użyć rebasepolecenia:

git rebase -i --root

Ostatnim sposobem może być utworzenie gałęzi osieroconej, gałęzi o tej samej zawartości, ale bez historii zmian, i zatwierdzenie nowej zawartości na niej:

git checkout --orphan <new-branch-name>
tzi
źródło
7
Szkoda, że ​​nie jest to akceptowana odpowiedź. Szkoda również, że większość trafień w Google mówi mniej więcej „nie można cofnąć pierwszego zatwierdzenia”. To załatwiło sprawę dla mnie. Dzięki!
danielpops
1
Dzięki @danielpops za wsparcie! Warto zauważyć, że odpowiedziałem na to pytanie 3 lata później. W międzyczasie Git ewoluował.
tzi
Użyłem rebase, oznaczyłem drugie zatwierdzenie jako „squash”, a następnie wykonałem polecenie --force push to origin. Dzięki!
Philip Atz,
1
git update-ref -d HEAD to najbezpieczniejszy sposób na usunięcie całej historii, a nie tylko początkowego zatwierdzenia.
user1767316
Zrobiłem to i usunąłem wszystkie moje pliki, które dodałem do pierwszego zatwierdzenia. Smutny. Przynajmniej nie było to dużo
Wiaczesław Ciwina
42

Nie ma nic przed pierwszym zatwierdzeniem, ponieważ każde zatwierdzenie odnosi się do zatwierdzenia rodzica. To sprawia, że ​​pierwsze zatwierdzenie jest wyjątkowe (zatwierdzenie osierocone), więc nie ma możliwości odniesienia się do poprzedniego „stanu”.

Więc jeśli chcesz naprawić zatwierdzenie, możesz po prostu git commit --amend: to zmodyfikuje zatwierdzenie bez tworzenia kolejnego.

Jeśli chcesz zacząć wszystko od nowa, usuń .gitrepozytorium i utwórz kolejne zgit init

Charles B.
źródło
7
Ta odpowiedź jest nieprawidłowa: JEST sposób na powrót do stanu sprzed pierwszego zatwierdzenia. Zobacz odpowiedź tzi poniżej.
David Nelson,
2
--amendRównież nie zaktualizuje autor prawidłowo jeśli początkowo skonfigurowana. To jest to, czego potrzebowałem, więc użyłem zaakceptowanej odpowiedzi, a następnie po prostu wykonałem nowy commit.
Mark Edington,
11
# Check out to a temporary branch:
git checkout --orphan TEMP_BRANCH

# Add all the files:
git add -A

# Commit the changes:
git commit -am "Initial commit"

# Delete the old branch:
git branch -D master

# Rename the temporary branch to master:
git branch -m master

# Finally, force update to our repository:
git push -f origin master
Megha Sahu
źródło
3
Brak odpowiedzi: pytanie brzmiało „jak usunąć pierwszy zatwierdzenie”, a nie „jak usunąć wszystko oprócz ostatniego zatwierdzenia”.
peterh - Przywróć Monikę
1
Właśnie tego szukałem. Dzięki!
Krzysztof Tomaszewski
6

Możesz po prostu edytować swoje pierwsze zatwierdzenie (ponieważ w repozytorium git zawsze jest pierwsze zatwierdzenie). Rozważ użycie git commit --amend --reset-authorzamiast zwykłego git commit --amend.

Max Beikirch
źródło
1
Brak odpowiedzi: pytanie miało na celu usunięcie pierwszego zatwierdzenia, a nie modyfikowanie właściwości ostatniego.
peterh - Przywróć Monikę
@ peterh-ReinstateMonica Dla wyjaśnienia: zatwierdzenia mogą być zmieniane podczas interaktywnej rebase, aby całkowicie zmienić ich zawartość, ale aby zmienić autora, należy podać również opcję --reset-author. Dzięki temu możesz całkowicie zastąpić pierwsze zatwierdzenie według własnych upodobań. Zobacz także odpowiedź Charlesa B.
Max Beikirch
3

Szukałem sposobu na cofnięcie wszystkich zatwierdzeń git z repozytorium, jakby nigdy się nie wydarzyły.

Rebasing będzie działał do pewnego momentu. Jednak pierwsze (chronologicznie najstarsze zatwierdzenie git) zawsze będzie problematyczne, ponieważ nie ma elementu nadrzędnego, więc wystąpi błąd.

Żadna z tych odpowiedzi nie rozwiązała tego za mnie. Ale po wielu poszukiwaniach i próbach i błędach okazało się, że to działa!

git update-ref -d HEAD
git push origin master -f

Mam nadzieję, że to ci pomoże. Miłego dnia.

kp123
źródło
1
Aby było jasne dla każdego, kto przeczyta tę odpowiedź: powoduje to usunięcie każdego zatwierdzenia, ale OP chce usunąć tylko pierwsze zatwierdzenie dokonane w repozytorium; nie uruchamiaj tego, aby usunąć pierwsze zatwierdzenie, ponieważ spowoduje to usunięcie WSZYSTKICH zatwierdzeń.
Jody Bruchon
2

Możesz też:

  1. Przejdź do oddziału, który chcesz zatrzymać (powiedzmy programista) git checkout dev
  2. Teraz usuń gałąź, którą chcesz zresetować git branch -D master
  3. Teraz utwórz pustą gałąź o tej samej nazwie git checkout --orphan master

Oczywiście wszystko to będzie zależeć od twojego przypadku, ale jeśli masz więcej niż jedną gałąź, usunięcie .gitkatalogu nie ma sensu.

kumarharsh
źródło
3
Po wykonaniu tej czynności musisz usunąć gałąź w zdalnym przed wypchnięciem. W przeciwnym razie, próbując pushować, pojawi się ten błąd:! [odrzucono] master -> master (non-fast-forward) - błąd: nie udało się przesłać niektórych odnośników do '[email protected]: r1 / r2.git' - wskazówka: aktualizacje zostały odrzucone, ponieważ końcówka Twojej bieżącej gałęzi to za - podpowiedź: jego zdalny odpowiednik. Zintegruj zdalne zmiany (np. Podpowiedź: 'git pull ...') przed ponownym wciśnięciem ... - Jeśli wykonasz git pull, wszystkie zatwierdzenia wrócą.
dxvargas
2

Jeśli chcesz zachować inne gałęzie, ale na przykład sprawić, by mastergałąź zaczynała się od nowa bez wspólnej historii do innych gałęzi, jednym bezpiecznym sposobem na osiągnięcie tego jest utworzenie nowego repozytorium i wypchnięcie jego zawartości do starego:

cd ..
git init newrepo
cd newrepo
# make some initial commits
git push ../oldrepo master:newmaster

Spowoduje to newmasterutworzenie gałęzi w starym repozytorium, której historia nie jest wspólna dla żadnej z innych gałęzi. Oczywiście, można po prostu nadpisać master, jak również, z git push -f.

Jeśli chcesz zniszczyć wszystkie gałęzie i całą istniejącą zawartość, po prostu uruchom

rm -rf .git/
user1338062
źródło
1
Brak odpowiedzi: OP chciał usunąć pierwsze zatwierdzenie i nie rozpoczynać nowego repozytorium git z bieżącym drzewem roboczym jako początkowym zatwierdzeniem.
peterh - Przywróć Monikę
@peterh Zgadzam się, że git rebase --rootjest to prawdopodobnie to, czego chciał OP, ale biorąc pod uwagę, że ta odpowiedź ma dwa głosy za, powstrzymam się od jej usuwania, jeśli ktoś nadal uzna ją za istotną.
user1338062
Myślę, że ta odpowiedź jest dokładnie trafna - jeśli chcesz usunąć pierwszy commit w jakiejś gałęzi, a jest tylko jeden commit! (Ale chcesz również zachować pozostałe zatwierdzenia w innych gałęziach; chcesz również to zrobić, aby zmiany trafiły do ​​Bitbucket lub Github, a nie tylko lokalnie). Uważam, że ta odpowiedź jest jednym ze sposobów, aby to zrobić, i Myślę, że to może być jedyny sposób, aby to zrobić. (Dzieje się tak, ponieważ - o ile widzę - nie ma sposobu, aby wymusić wypchnięcie lokalnego oddziału bez zatwierdzeń na zdalny oddział z niektórymi zatwierdzeniami).
MikeBeaton
0

Jeśli właśnie go zatwierdziłeś, ale nie pchnąłeś, po prostu usuń katalog .git i git initjeszcze raz ...

Ali Sajid
źródło
@peterh Tak, to prawda. Zakładasz (myślę), że pytanie OP dotyczy chęci usunięcia pierwszego zatwierdzenia, ale zachowania kolejnych zatwierdzeń. Inną możliwością (która moim zdaniem doskonale pasuje do pytania OP - i na którą ta odpowiedź jest odpowiedź) jest chęć usunięcia pierwszego i jedynego zatwierdzenia z gałęzi, przywracając go z powrotem do całkowicie pustego.
MikeBeaton
@MikeBeaton Masz rację. Usuwam komentarz, ale potem muszę zagłosować, aby zamknąć pytanie jako niejasne. Uwaga, chociaż tylko ja dostałem ten komentarz, ale za mną jest 40000 gości, a znaczna część z nich znalazła to pytanie w google - i nie dostali tego, czego chcieli.
peterh - Przywróć Monikę
To wydaje się ekstremalne. Usunąć pytanie? Czy nie można (całkiem dobrze) argumentować, że pełną odpowiedzią na całkowicie rozsądne pytanie jest to, że istnieją dwa różne podejścia, które należy przyjąć, w zależności od tego, czy ... itd.? (Mam na myśli, na przykład, chciałbym wiedzieć, jak usunąć pierwsze zatwierdzenie, gdy nie jest to jedyne zatwierdzenie, a także jak usunąć pierwsze zatwierdzenie, gdy jest to jedyne zatwierdzenie. Z pewnością nie jest to oczywiste i na pewno zależy po szczegółach dotyczących implementacji, okazuje się, że w każdym przypadku potrzebne są naprawdę inne podejścia.)
MikeBeaton
0

Odpowiedź na pytanie zależy od tego, czy:

  • Chcesz usunąć pierwsze I TYLKO zatwierdzenie na gałęzi (pozostawiając inne gałęzie bez zmian), czy też

  • Chcesz usunąć pierwsze zatwierdzenie w jakiejś gałęzi, pozostawiając „na miejscu” kolejne zatwierdzenia (i pozostałe gałęzie).

Drugi z nich jest stosunkowo prostszy. Zasadniczo musisz zmienić bazę na rootowanie - większość odpowiedzi tutaj dotyczy sposobów, aby to zrobić.

Wykonanie drugiej (usunięcie pierwszego i jedynego zatwierdzenia z gałęzi, a pozostawienie innych gałęzi w spokoju) jest trudniejsze. Lub przynajmniej szczególnie trudniej, jeśli chcesz, aby tak się stało i aby zmiana została odzwierciedlona z powrotem w GitHub lub Bitbucket. Nie ma (o ile wiem) w Gicie żadnego sposobu, aby wypchnąć lub wymusić wypchnięcie gałęzi bez zatwierdzeń. Nie ma również (znowu, o ile widzę) żadnego sposobu na utworzenie nowej, pustej gałęzi bez zatwierdzeń w GitHub lub Bitbucket. Więc zasadniczo musisz utworzyć nowe repozytorium, aby utworzyć całkowicie pustą gałąź, a następnie dodać z powrotem gałęzie, które chcesz (w tym zatwierdzenia, które chcesz) - zgodnie z odpowiedzią @ user1338062.

Więc mam nadzieję, że ta odpowiedź wyjaśnia, jakie mogą nie być oczywiste - że istnieją dwa różne podejścia, które muszą być podjęte, na dwóch różnych (mniej lub bardziej rozsądnych) scenariuszy, które są zarówno rzeczy, które warto być w stanie zrobić, aby w pełni opanować robienie tego, o co prosi PO.

MikeBeaton
źródło