Git: Jak wycisnąć wszystkie zatwierdzenia na gałęzi


315

Tworzę nowy oddział masterz:

git checkout -b testbranch

Dokonuję w nim 20 zobowiązań.

Teraz chcę zmiażdżyć te 20 zobowiązań. Robię to z:

git rebase -i HEAD~20

A jeśli nie wiem, ile zatwierdzeń? Czy jest jakiś sposób na zrobienie czegoś takiego:

git rebase -i all on this branch

6
Można zrobić git rebase -i 58333012713fc168bd70ad00d191b3bdc601fa2dwich zrobi interaktywną rebase gdzie commitnumber jest ostatni popełnić który pozostaje niezmieniony
— denns

@denns Korzystając z tej metody przy ostatnim zatwierdzeniu w gałęzi, z której korzystasz fantastycznie pracowałeś. Dzięki wielkie!
— Joshua Pinter

Odpowiedzi:


392

Innym sposobem na zmiażdżenie wszystkich zatwierdzeń jest zresetowanie indeksu do wzorcowania:

 git checkout yourBranch
 git reset $(git merge-base master yourBranch)
 git add -A
 git commit -m "one commit on yourBranch"

Nie jest to idealne, ponieważ sugeruje, że wiesz, z której gałęzi pochodzi „twoja gałąź”.
Uwaga: odnalezienie gałęzi pochodzenia nie jest łatwe / możliwe w Git ( sposób wizualny jest często najłatwiejszy , jak widać tutaj ).


EDYCJA: będziesz musiał użyć git push --force


Karlotcha Hoa dodaje w komentarzach :

Aby zresetować, możesz to zrobić

git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD)) 

[To] automatycznie korzysta z gałęzi, w której aktualnie się znajdujesz.
Jeśli go użyjesz, możesz także użyć aliasu, ponieważ polecenie nie zależy od nazwy oddziału .


2
Lepiej do kasy, aby zatwierdzić, gdzie YourBranchjest obecnie. To pozostanie YourBranchnienaruszone, kiedy to zrobiszreset
— Eugen Konkov

1
@Abdurrahim Lub otwórz git bash, a ty możesz skopiować i wkleić te polecenia!
— VonC

3
Aby zresetować, możesz zrobić, git reset $(git merge-base master $(git rev-parse --abbrev-ref HEAD))aby automatycznie użyć gałęzi, w której aktualnie się znajdujesz. Jeśli go użyjesz, możesz także użyć aliasu, ponieważ polecenie nie zależy od nazwy oddziału.
— Karlotcha Hoa

1
@Druska W przypadku rozgałęzień w Simlpe nie powinno działać poprawnie.
— VonC

1
@Shimmy tak, pod warunkiem, że wymusisz push po resecie: git push --force(i ostrzeż swoich współpracowników, jeśli jest kilka osób pracujących w tym oddziale)
— VonC

112

Sprawdź gałąź, dla której chcesz zgnieść wszystkie zatwierdzenia w jednym zatwierdzeniu. Powiedzmy, jego nazwie, feature_branch.

git checkout feature_branch

Krok 1:

Wykonaj miękki reset origin/feature_branchswojego lokalnego masteroddziału (w zależności od potrzeb możesz zresetować również za pomocą Origin / Master). Spowoduje to zresetowanie wszystkich dodatkowych zatwierdzeń w feature_branchpliku, ale bez zmiany lokalnych zmian plików.

git reset --soft master

Krok 2:

Dodaj wszystkie zmiany w katalogu git repo do nowego zatwierdzenia, które ma zostać utworzone. I to samo z komunikatem.

git add -A && git commit -m "commit message goes here"


6
To było dla mnie najbardziej niezawodne rozwiązanie - nie powodowało błędów bazy ani nie łączyło konfliktów.
— ANTARA

1
Ostrzeżenie: git dodaj -Dodaj WSZYSTKO, co masz w folderze lokalnym - do oddziału.
— David H

uwielbiam to rozwiązanie! właśnie tego chciałem!
— jacoballenwood,

1
Najlepsze rozwiązanie dla noob - nieniszczące i tylko chwilą nieoczekiwaną może być sprawdzanie za dużo, takich jak tajemnice aplikacji itp., Co nie powinno mieć znaczenia, jeśli masz odpowiedni plik
— gitignore

@NSduToit Krótka odpowiedź: Nie, nie musisz. Po wykonaniu wyżej wymienionych kroków w mojej odpowiedzi skończysz na jednym zatwierdzeniu z pewnymi zmianami kodu. Możesz myśleć o tym jak o każdym innym zatwierdzeniu z pewnymi zmianami kodu. Możesz przekazać to do swojej zdalnej gałęzi bez -fflagi.
— shanky

110

To, co robisz, jest podatne na błędy. Po prostu zrób:

git rebase -i master

co automatycznie spowoduje bazowanie tylko zatwierdzeń oddziału na bieżącym najnowszym systemie głównym.


5
dzięki, dostałem to, ale dlaczego mój system jest podatny na błędy
— użytkownik3803850,

10
Prawdopodobnie dlatego, że łatwo pomylić numer?
— Daniel Scott

13
Zgadzam się, że to twoje najlepsze rozwiązanie. ale kliknij ten link, ponieważ lepiej wyjaśnia, co musisz zrobić.
— Christo

3
Zamiast zgniatać zatwierdzenia, możesz scalić gałąź z master i wykonać reset git do origin / master, aby cofnąć scenę wszystkich commits. Pozwoliłoby to zatwierdzić istniejący kod niestacjonarny za pomocącommit -am "the whole thing!"
— nurettin

2
@nurettin Myślę, że reset origin/mastermetoda jest naprawdę zła, ponieważ jest to tak samo jak wykonywanie zatwierdzeń bezpośrednio na masterie - nie ma historii „scalania gałęzi”, nie ma opcji żądania ściągania. Odpowiedź @WaZaA jest bardziej zgodna z normalnym procesem pracy z gitem, myślę
— Drenai

79

Kolejny prosty sposób: przejdź do gałęzi początkowej i zrób merge --squash. To polecenie nie wykonuje zatwierdzenia „zgniecionego”. kiedy to zrobisz, wszystkie wiadomości zatwierdzenia Twojej Oddziału zostaną zebrane.

$ git checkout master
$ git merge --squash yourBranch
$ git commit # all commit messages of yourBranch in one, really useful
 > [status 5007e77] Squashed commit of the following: ...

1
Prawdziwe. Wspomniałem o różnicy między scalaniem - quassem a rebase -i w stackoverflow.com/a/2427520/6309
— VonC

1
Działa to, jeśli nie chcesz zgniatać gałęzi nadrzędnej, po prostu stwórz i przełącz się na nową gałąź opartą na gałęzi nadrzędnej i wykonaj scalenie squasha.
— Charlotte,

Na zdrowie kolego, świetna wskazówka!
— Nestor Milyaev

miły! tworzę gałąź „temp” z „master” najpierw do zgniatania „yourBranch”, a następnie łączę „temp” w „master”.
— lazieburd

34

Zakładając, że rozgałęziasz się od mastera, nie musisz yourBranchcały czas wchodzić w krok resetowania:

git checkout yourBranch
git reset --soft HEAD~$(git rev-list --count HEAD ^master)
git add -A
git commit -m "one commit on yourBranch"

Objaśnienie :

  • git rev-list --count HEAD ^masterzlicza zatwierdzenia, ponieważ utworzono gałąź funkcji od wzorca, np. 20
  • git reset --soft HEAD~20wykona miękki reset ostatnich 20 zatwierdzeń. To pozostawia zmiany w plikach, ale usuwa zatwierdzenia.

Zastosowanie :

W moim profilu .bash dodałem alias, aby gisquashto zrobić za pomocą jednego polecenia:

# squash all commits into one
alias gisquash='git reset --soft HEAD~$(git rev-list --count HEAD ^master)'

Po zresetowaniu i zatwierdzeniu musisz zrobić git push --force.

Wskazówka :

Jeśli używasz Gitlab> = 11.0, nie musisz już tego robić, ponieważ ma opcję zgniatania podczas łączenia gałęzi. Opcja Gitlab Squashing


15

Opierając się na przeczytaniu kilku pytań Stackoverflow i odpowiedzi na temat squashingu, myślę, że jest to dobry jeden wiersz do zgniatania wszystkich zatwierdzeń w gałęzi:

git reset --soft $(git merge-base master YOUR_BRANCH) && git commit -am "YOUR COMMIT MESSAGE" && git rebase -i master

Zakłada się, że master jest gałęzią podstawową.


1
Bardzo dziękuję, firma ma wiele ograniczeń i nie mogła bazować w zwykły sposób z edytorem, ponieważ nie było głośno, aby zapisać. Nie można również użyć funkcji squash i merge w git, ponieważ ta gałąź idzie do Lead dev do scalenia i nie podoba mu się to. Ta 1 wkładka zadziałała i uratowała bóle głowy. Wspaniała praca.
— L1ghtk3ira

10

Rozwiązanie dla osób, które wolą klikać:

  1. Zainstaluj sourcetree (jest bezpłatny)

  2. Sprawdź, jak wyglądają twoje zobowiązania. Najprawdopodobniej masz coś podobnego do tego wprowadź opis zdjęcia tutaj

  3. Kliknij prawym przyciskiem myszy na zatwierdzenie nadrzędne . W naszym przypadku jest to gałąź master.

wprowadź opis zdjęcia tutaj

  1. Możesz zgnieść zatwierdzenie z poprzednim, klikając przycisk. W naszym przypadku musimy kliknąć 2 razy. Możesz także zmienić komunikat zatwierdzenia wprowadź opis zdjęcia tutaj

  2. Rezultaty są niesamowite i jesteśmy gotowi do działania! wprowadź opis zdjęcia tutaj

Uwaga dodatkowa: Jeśli przepychałeś swoje częściowe zatwierdzenia do pilota, musisz użyć siły push po squashu


Dzięki za to!
— Kryształ,

0

Innym rozwiązaniem byłoby zapisanie wszystkich dzienników zatwierdzeń w pliku

git log> branch.log

Teraz branch.log będzie miał wszystkie identyfikatory zatwierdzeń od początku. Przewiń w dół i weź pierwszy zatwierdzenie (będzie to trudne w terminalu) za pomocą pierwszego zatwierdzenia

git reset --soft

wszystkie zobowiązania zostaną zmiażdżone


0

Reset Git, jak wspomniano wcześniej w wielu odpowiedziach, jest zdecydowanie najlepszym i najprostszym sposobem na osiągnięcie tego, co chcesz. Używam go w następującym przepływie pracy:

(w dziale rozwoju)

git fetch
git merge origin/master  #so development branch has all current changes from master
git reset origin/master  #will show all changes from development branch to master as unstaged
git gui # do a final review, stage all changes you really want
git commit # all changes in a single commit
git branch -f master #update local master branch
git push origin master #push it

0

Cały ten reset gita, twardy, miękki i wszystko inne wspomniane tutaj prawdopodobnie działa (nie dla mnie), jeśli wykonasz kroki poprawnie i jakiś dżin.
Jeśli jesteś przeciętnym Joe smo, spróbuj tego:
Jak używać git merge - quash?


Uratowałem sobie życie, i pójdę do squasha, używam tego 4 razy, odkąd się o tym dowiedziałem. Prosty, czysty i w zasadzie 1 comamnd. W skrócie:


jeśli jesteś na gałęzi, nazwijmy to „moja_nowa_funkcja” wyłącz rozwijanie, a twoje żądanie ściągnięcia ma 35 zatwierdzeń (lub jak wiele) i chcesz, aby było 1.

A. Upewnij się, że twój oddział jest aktualny, kontynuuj rozwijaj, pobieraj najnowsze oraz łącz i rozwiązuj wszelkie konflikty z „my_new_feature”
(ten krok naprawdę powinieneś zrobić tak szybko, jak to możliwe przez cały czas)

B. B. Bądź na bieżąco z rozwijaniem i rozgałęzianiem się do nowego oddziału, nazywając go „my_new_feature_squashed”

C. magia jest tutaj.
Chcesz przenieść swoją pracę z „my_new_feature” do „my_new_feature_squashed”
Więc po prostu zrób to (podczas tworzenia nowego oddziału, rozwijamy się):
git merge --squash my_new_feature

Wszystkie twoje zmiany będą teraz w twoim nowym oddziale, nie krępuj się przetestować, a następnie po prostu wykonaj 1 zatwierdzenie, wypchnij, nowy PR tego oddziału - i poczekaj na powtórzenie następnego dnia.
Nie lubisz kodować? :)


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.