Jak zredukować całe repozytorium do pierwszego zatwierdzenia?
Mogę zmienić podstawę do pierwszego zatwierdzenia, ale to dałoby mi 2 zatwierdzenia. Czy istnieje sposób na odniesienie do zatwierdzenia przed pierwszym?
git
rebase
git-rebase
squash
git-rewrite-history
Verhogen
źródło
źródło
--root
tak naprawdę nie jest najlepszym rozwiązaniem do zgniatania wszystkich zatwierdzeń, jeśli jest ich wiele): Czy połączyć pierwsze dwa zatwierdzenia z repozytorium Git? .Odpowiedzi:
Być może najłatwiejszym sposobem jest po prostu utworzenie nowego repozytorium z bieżącym stanem kopii roboczej. Jeśli chcesz zachować wszystkie komunikaty zatwierdzeń, które możesz zrobić,
git log > original.log
a następnie edytować je dla początkowego komunikatu zatwierdzenia w nowym repozytorium:lub
źródło
git rebase -i --root
. Patrz: stackoverflow.com/a/9254257/109618Od wersji 1.6.2 możesz używać
git rebase --root -i
.Dla każdego zatwierdzenia oprócz pierwszego zmień
pick
nasquash
.źródło
squash
do wszystkich zatwierdzeń. Najpierw musi byćpick
.Aktualizacja
Zrobiłem alias
git squash-all
.Przykładowe zastosowania :
git squash-all "a brand new start"
.Zastrzeżenie : pamiętaj, aby podać komentarz, w przeciwnym razie użyty zostanie domyślny komunikat zatwierdzenia „Nowy początek”.
Lub możesz utworzyć alias za pomocą następującego polecenia:
Jedna wkładka
Uwaga : tutaj „
A new start
” to tylko przykład, możesz swobodnie używać własnego języka.TL; DR
Nie musisz zgniatać, użyj,
git commit-tree
aby stworzyć sierocą zmianę i idź z nią.Wyjaśnić
utwórz pojedynczy zatwierdzenie przez
git commit-tree
Co
git commit-tree HEAD^{tree} -m "A new start"
to jest:Wyrażenie
HEAD^{tree}
oznacza obiekt drzewa odpowiadającyHEAD
, a mianowicie czubek bieżącej gałęzi. zobacz drzewa obiektów i popełnić-obiektów .zresetuj bieżącą gałąź do nowego zatwierdzenia
Następnie
git reset
po prostu zresetuj bieżącą gałąź do nowo utworzonego obiektu zatwierdzenia.W ten sposób nic nie jest dotykane w obszarze roboczym, ani nie ma potrzeby korzystania z bazy / squash, co czyni go naprawdę szybkim. Potrzebny czas nie ma znaczenia dla wielkości repozytorium ani głębokości historii.
Odmiana: nowe repozytorium z szablonu projektu
Jest to przydatne do utworzenia „początkowego zatwierdzenia” w nowym projekcie przy użyciu innego repozytorium jako szablonu / archetype / seed / skeleton. Na przykład:
Pozwala to uniknąć dodawania repozytorium szablonu jako zdalnego (
origin
lub w inny sposób) i zwija historię repozytorium szablonu do początkowego zatwierdzenia.źródło
git push -f
do propagacji.git clone
. Jeśli dodać--hard
dogit reset
i przełącznikHEAD
zeFETCH_HEAD
wgit commit-tree
można utworzyć początkowy popełnić po pobraniu repo szablonu. Zredagowałem odpowiedź z sekcją na końcu demonstrującą to.${1?Please enter a message}
Jeśli wszystko, co chcesz zrobić, to zmiażdżyć wszystkie swoje commity do głównego zatwierdzenia, a potem
może działać, jest to niepraktyczne dla dużej liczby commits (na przykład setek commits), ponieważ operacja rebase prawdopodobnie będzie działać bardzo wolno, aby wygenerować listę zatwierdzeń interaktywnego edytora rebase, a także uruchomić sam rebase.
Oto dwa szybsze i bardziej wydajne rozwiązania, gdy zgniatasz dużą liczbę zatwierdzeń:
Alternatywne rozwiązanie nr 1: gałęzie osierocone
Możesz po prostu utworzyć nową gałąź osieroconą na końcu (tj. Najnowszym zatwierdzeniu) twojej aktualnej gałęzi. Ta gałąź sieroca tworzy początkowe zatwierdzenie katalogu głównego całkowicie nowego i osobnego drzewa historii zatwierdzeń, co w rzeczywistości jest równoważne zmiażdżeniu wszystkich twoich zatwierdzeń:
Dokumentacja:
Alternatywne rozwiązanie # 2: miękki reset
Innym skutecznym rozwiązaniem jest po prostu użycie mieszanego lub miękkiego resetu do głównego zatwierdzenia
<root>
:Dokumentacja:
źródło
git push origin master --force
.git push --force
Spowoduje to utworzenie osieroconego zatwierdzenia z drzewem HEAD i wyprowadzenie jego nazwy (SHA-1) na standardowym wyjściu. Następnie zresetuj tam swój oddział.
źródło
git reset $(git commit-tree HEAD^{tree} -m "commit message")
ułatwiłoby to.echo "message" | git commit-tree "HEAD^{tree}"
Oto, jak to zrobiłem, na wypadek, gdyby zadziałało to dla kogoś innego:
Pamiętaj, że zawsze istnieje ryzyko zrobienia czegoś takiego i nigdy nie jest to zły pomysł, aby utworzyć gałąź składowania przed rozpoczęciem.
Zacznij od zalogowania
Przewiń do pierwszego zatwierdzenia, skopiuj SHA
Zamień
<#sha#>
w / SHA skopiowane z dziennikaUpewnij się, że wszystko jest zielone, w przeciwnym razie uruchom
git add -A
Zmień wszystkie bieżące zmiany w bieżącym pierwszym zatwierdzeniu
Teraz wymusz push tę gałąź, a ona zastąpi to, co tam jest.
źródło
Czytałem coś o stosowaniu przeszczepów, ale nigdy nie analizowałem tego zbyt wiele.
W każdym razie możesz ręcznie zgnieść ostatnie 2 zatwierdzenia za pomocą czegoś takiego:
źródło
Najprościej jest użyć polecenia „hydraulika”,
update-ref
aby usunąć bieżącą gałąź.Nie można użyć,
git branch -D
ponieważ ma zawór bezpieczeństwa, aby zatrzymać usuwanie aktualnego odgałęzienia.Powoduje to powrót do stanu „początkowego zatwierdzenia”, w którym możesz zacząć od nowego początkowego zatwierdzenia.
źródło
Po pierwsze, zmiksuj wszystkie swoje zobowiązania w jednym zatwierdzeniu, używając
git rebase --interactive
. Teraz masz dwa zobowiązania do zgniecenia. Aby to zrobić, przeczytaj dowolny z nichźródło
W jednym wierszu z 6 słów
źródło
git help checkout
o--orphan
git help checkout --orphan
utwórz kopię zapasową
zresetować do określonego zatwierdzenia
następnie dodaj wszystkie pliki do inscenizacji
zatwierdzanie bez aktualizacji wiadomości
pchnij nowy oddział zgniecionymi zobowiązaniami do repo
źródło
<root>
zatwierdzenie, do którego zresetowano ponownie.git commit --amend --no-edit
zatwierdzi wszystkie zmiany w bieżącym zatwierdzeniu, które<root>
nie wymaga edycji komunikatu zatwierdzenia.Do zgniatania za pomocą przeszczepów
Dodaj plik
.git/info/grafts
, umieść tam skrót zatwierdzenia, który chcesz stać się Twoim rootemgit log
zacznie teraz od tego zatwierdzeniaAby działało to „prawdziwie”
git filter-branch
źródło
Ta odpowiedź poprawia się w przypadku kilku powyżej (proszę głosować na nie), zakładając, że oprócz utworzenia jednego zatwierdzenia (brak historii bez rodziców), chcesz również zachować wszystkie dane dotyczące tego zatwierdzenia:
Oczywiście zatwierdzenie SHA nowego / pojedynczego zatwierdzenia ulegnie zmianie, ponieważ reprezentuje nową (nie) historię, stając się rodzicielską / zatwierdzeniem root.
Można to zrobić, czytając
git log
i ustawiając niektóre zmienne dlagit commit-tree
. Zakładając, że chcesz utworzyć pojedyncze zatwierdzeniemaster
w nowym oddzialeone-commit
, zachowując powyższe dane zatwierdzenia:źródło
Aby to zrobić, możesz zresetować swoje lokalne repozytorium git do pierwszego hashtagu zatwierdzenia, więc wszystkie zmiany po tym zatwierdzeniu zostaną wycofane ze sceny, a następnie możesz zatwierdzić za pomocą opcji --amend.
A jeśli to konieczne, edytuj pierwsze zatwierdzenie i zapisz plik.
źródło
Dla mnie działało to tak: miałem w sumie 4 zatwierdzenia i użyłem interaktywnego rebase:
Pozostało pierwsze zatwierdzenie i wziąłem 3 ostatnie zatwierdzenia.
Jeśli utkniesz w edytorze, który pojawi się obok, zobaczysz coś takiego:
Musisz wziąć pierwsze zatwierdzenie i zgnieść innych. Co powinieneś mieć to:
W tym celu użyj przycisku INSERT, aby zmienić tryb „wstaw” i „edytuj”.
Aby zapisać i wyjść z edytora, użyj
:wq
. Jeśli kursor znajduje się między tymi wierszami zatwierdzenia lub gdzieś indziej, wciśnij ESC i spróbuj ponownie.W rezultacie miałem dwa zatwierdzenia: pierwsze, które pozostało, a drugie z komunikatem „To jest kombinacja 3 zatwierdzeń”.
Sprawdź szczegóły tutaj: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit
źródło
Zwykle robię to w ten sposób:
Upewnij się, że wszystko zostało zatwierdzone, i zapisz najnowszy identyfikator zatwierdzenia na wypadek, gdyby coś poszło nie tak, lub utwórz oddzielną gałąź jako kopię zapasową
Uruchom,
git reset --soft `git rev-list --max-parents=0 --abbrev-commit HEAD`
aby zresetować głowę do pierwszego zatwierdzenia, ale pozostaw indeks bez zmian. Wszystkie zmiany od pierwszego zatwierdzenia będą teraz wydawać się gotowe do zatwierdzenia.Uruchom,
git commit --amend -m "initial commit"
aby zmienić swoje zatwierdzenie do pierwszego zatwierdzenia i zmienić komunikat zatwierdzenia, lub jeśli chcesz zachować istniejący komunikat zatwierdzenia, możesz uruchomićgit commit --amend --no-edit
Uruchom,
git push -f
aby wymusić wprowadzenie zmianźródło