Podziel poprzednie zatwierdzenie na wiele zatwierdzeń
1222
Czy bez tworzenia gałęzi i wykonywania kilku funky pracy nad nową gałęzią jest możliwe rozbicie pojedynczego zatwierdzenia na kilka różnych zatwierdzeń po tym, jak zostało ono przypisane do lokalnego repozytorium?
Dokumenty powiązane z powyższym komentarzem są doskonałe, lepiej wyjaśnione niż poniższe odpowiedzi.
Blaisorblade,
2
Sugeruję użycie tego aliasu stackoverflow.com/a/19267103/301717 . Pozwala na podział zatwierdzenia przy użyciugit autorebase split COMMIT_ID
Jérôme Pouiller
Najłatwiejszą rzeczą do zrobienia bez interaktywnego bazowania jest (prawdopodobnie) utworzenie nowej gałęzi zaczynającej się od zatwierdzenia przed tą, którą chcesz podzielić, wybranie -n-zatwierdzenie, zresetowanie, ukrywanie, zatwierdzenie przeniesienia pliku, ponowne zastosowanie ukrywania i zatwierdzić zmiany, a następnie albo połączyć się z poprzednim oddziałem, albo wybrać kolejne zatwierdzenia. (Następnie zmień nazwę poprzedniego oddziału na obecnego szefa.) (Prawdopodobnie lepiej postępować zgodnie z radami MBO i zrobić interaktywny rebase.) (Skopiowano z odpowiedzi poniżej z 2010 r.)
William Pursell
1
Natknąłem się na ten problem po tym, jak przypadkowo zmiażdżyłem dwa commity podczas rebase we wcześniejszym zatwierdzeniu. Mój sposób to naprawić było sprowadzić zgniecione popełnienia, git reset HEAD~, git stash, a następnie git cherry-pickpierwszą popełnić w squasha, a następnie git stash pop. Mój przypadek cherry-pick jest dość specyficzny tutaj, ale git stashi git stash popjest bardzo przydatny dla innych.
Najpierw zacznij od czystego katalogu roboczego: nie git statuspowinien pokazywać żadnych oczekujących modyfikacji, usunięć ani dodatków.
Teraz musisz zdecydować, które zatwierdzenia chcesz podzielić.
A) Dzielenie ostatniego zatwierdzenia
Aby podzielić ostatnie zatwierdzenie, najpierw:
$ git reset HEAD~
Teraz przydzielaj elementy indywidualnie w zwykły sposób, tworząc tyle zmian, ile potrzebujesz.
B) Dzielenie zatwierdzenia dalej w tył
Wymaga to przekształcenia , czyli przepisania historii. Aby znaleźć poprawne zatwierdzenie, masz kilka możliwości:
Jeśli to były trzy zobowiązania, to wtedy
$ git rebase -i HEAD~3
gdzie 3jest ile to zatwierdza.
Jeśli to było dalej w drzewie, niż chcesz policzyć, to
$ git rebase -i 123abcd~
gdzie 123abcdjest SHA1 zatwierdzenia, które chcesz podzielić.
Jeśli jesteś w innej gałęzi (np. Gałąź funkcji), którą planujesz scalić w master:
$ git rebase -i master
Gdy pojawi się ekran edycji bazy, znajdź zatwierdzenie, które chcesz rozdzielić. Na początku tej linii, należy wymienić pickz edit( ew skrócie). Zapisz bufor i wyjdź. Rebase zatrzyma się teraz zaraz po zatwierdzeniu, które chcesz edytować. Następnie:
$ git reset HEAD~
Popełniaj poszczególne elementy w zwykły sposób, wytwarzając tyle zmian, ile potrzebujesz
Dziękuję za tę odpowiedź. Chciałem mieć wcześniej zatwierdzone pliki w obszarze testowym, więc instrukcje dla mnie były nieco inne. Zanim mogłem git rebase --continue, tak naprawdę musiał git add (files to be added), git commit, a następnie git stash(w przypadku pozostałych plików). Po git rebase --continueużyłem git checkout stash ., aby uzyskać pozostałe pliki
Eric Hu
18
Odpowiedź manojldsa faktycznie zawiera ten link do dokumentacji git-scm , co również bardzo wyraźnie wyjaśnia proces dzielenia zatwierdzeń.
56
Będziesz także chciał skorzystać z git add -pdodawania tylko częściowych sekcji plików, być może z eopcją edycji różnic, aby zatwierdzić tylko część przystawki. git stashjest również przydatny, jeśli chcesz kontynuować pracę, ale usunąć ją z bieżącego zatwierdzenia.
Craig Ringer
2
Jeśli chcesz podzielić i zmienić kolejność zatwierdzeń, to co lubię to najpierw podzielić, a następnie osobno zmienić kolejność za pomocą innego git rebase -i HEAD^3polecenia. W ten sposób, jeśli podział pójdzie źle, nie musisz cofać tyle pracy.
David M. Lloyd,
4
@kralyk Pliki, które zostały nowo zatwierdzone w HEAD, pozostaną na dysku po git reset HEAD~. Nie są zgubieni.
Wayne Conrad,
312
Z instrukcji git-rebase (sekcja DOTYCZĄCE ROZDZIELANIA)
W trybie interaktywnym możesz oznaczać zatwierdzenia poprzez akcję „edytuj”. Jednak nie musi to oznaczać, że git rebase oczekuje, że wynikiem tej edycji będzie dokładnie jeden zatwierdzenie. Rzeczywiście, możesz cofnąć zatwierdzenie lub dodać inne zatwierdzenia. Można tego użyć do podzielenia zatwierdzenia na dwa:
Rozpocznij interaktywny rebase z git rebase -i <commit>^ , gdzie <commit>jest zatwierdzenie, które chcesz podzielić. W rzeczywistości każdy zakres zatwierdzeń będzie działał, o ile będzie zawierał to zatwierdzenie.
Zaznacz zatwierdzenie, które chcesz podzielić, poprzez akcję „edytuj”.
Jeśli chodzi o edycję tego zatwierdzenia, wykonaj git reset HEAD^. W rezultacie HEAD jest przewijany o jeden, a indeks podąża za nim. Jednak działające drzewo pozostaje takie samo.
Teraz dodaj zmiany do indeksu, który chcesz mieć przy pierwszym zatwierdzeniu. Możesz użyć git add(ewentualnie interaktywnie) lub git gui(lub obu), aby to zrobić.
Zatwierdź bieżący indeks z dowolnym komunikatem zatwierdzenia, który jest teraz odpowiedni.
Powtarzaj dwa ostatnie kroki, aż drzewo robocze będzie czyste.
Kontynuuj zmianę bazy za pomocą git rebase --continue.
Słowo ostrzeżenia: przy takim podejściu zgubiłem komunikat zatwierdzenia.
user420667,
11
@ user420667 Tak, oczywiście. Przecież czekamy resetna zatwierdzenie - w tym wiadomość. Rozsądną rzeczą do zrobienia, jeśli wiesz, że będziesz dzielić zatwierdzenie, ale chcesz zachować część / całość jego wiadomości, jest zrobienie kopii tej wiadomości. Tak więc, git showzatwierdź przed rebaseing, lub jeśli zapomnisz lub wolisz: wróć do niego później przez reflog. Nic z tego nie zostanie „zagubione”, dopóki nie zostanie zebrane w ciągu 2 tygodni.
underscore_d
4
~i ^są różne rzeczy, nawet w systemie Windows. Nadal chcesz kursora ^, więc musisz po prostu uciec z niego odpowiednio do twojej powłoki. W PowerShell to jest HEAD`^. Za pomocą cmd.exe możesz podwoić go, aby uciec HEAD^^. W większości (wszystkich?) Powłok można otaczać cytatami takimi jak "HEAD^".
AndrewF
7
Możesz też zrobić git commit --reuse-message=abcd123. Krótka opcja to -C.
j0057
41
Użyj git rebase --interactivedo edycji tego wcześniejszego zatwierdzenia, uruchom git reset HEAD~, a następnie git add -pdodaj niektóre, następnie dokonaj zatwierdzenia, następnie dodaj kolejne i dokonaj kolejnego zatwierdzenia, tyle razy, ile chcesz. Kiedy skończysz, uruchom git rebase --continue, a będziesz miał wszystkie zatwierdzenia podziału wcześniej na swoim stosie.
Ważne : pamiętaj, że możesz się pobawić i wprowadzić wszystkie potrzebne zmiany i nie musisz się martwić utratą starych zmian, ponieważ zawsze możesz uruchomić, git reflogaby znaleźć punkt w projekcie, który zawiera żądane zmiany (nazwijmy to a8c4ab) , a następnie git reset a8c4ab.
bfb8e46 Rose Perrone 4 seconds ago ---- three
2b613bc Rose Perrone 14 seconds ago ---- two
9aac58f Rose Perrone 24 seconds ago ---- one
Powiedzmy, że chcemy podzielić drugi popełnić two.
git rebase --interactive HEAD~2
Spowoduje to wyświetlenie następującego komunikatu:
pick 2b613bc two
pick bfb8e46 three
Zmień pierwszy pickna, eaby edytować zatwierdzenie.
git reset HEAD~
git diff pokazuje nam, że właśnie przeprowadziliśmy inscenizację zatwierdzenia dokonanego dla drugiego zatwierdzenia:
diff --git a/A b/A
index 5626abf..814f4a4 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two
Dokonajmy tej zmiany i dodajmy „i trzeci” do tego wiersza w pliku A.
git add .
Zazwyczaj jest to punkt podczas interaktywnego rebase, w którym działamy git rebase --continue, ponieważ zwykle chcemy po prostu wrócić do naszego stosu zmian, aby edytować wcześniejsze zatwierdzenie. Ale tym razem chcemy stworzyć nowe zatwierdzenie. Więc uciekniemy git commit -am 'two and a third'. Teraz edytujemy plik Ai dodajemy linię two and two thirds.
git add .git commit -am 'two and two thirds'git rebase --continue
Mamy konflikt z naszym zatwierdzeniem three, więc rozwiążmy go:
Zmienimy się
one
<<<<<<< HEAD
two and a third
two and two thirds
=======
two
three
>>>>>>> bfb8e46... three
do
one
two and a third
two and two thirds
three
git add .; git rebase --continue
Teraz git log -pwygląda to tak:
commit e59ca35bae8360439823d66d459238779e5b4892
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 13:57:00 2013 -0700
three
diff --git a/A b/A
index 5aef867..dd8fb63 100644
--- a/A
+++ b/A
@@ -1,3 +1,4 @@
one
two and a third
two and two thirds
+three
commit 4a283ba9bf83ef664541b467acdd0bb4d770ab8e
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 14:07:07 2013 -0700
two and two thirds
diff --git a/A b/A
index 575010a..5aef867 100644
--- a/A
+++ b/A
@@ -1,2 +1,3 @@
one
two and a third
+two and two thirds
commit 704d323ca1bc7c45ed8b1714d924adcdc83dfa44
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 14:06:40 2013 -0700
two and a third
diff --git a/A b/A
index 5626abf..575010a 100644
--- a/A
+++ b/A
@@ -1 +1,2 @@
one
+two and a third
commit 9aac58f3893488ec643fecab3c85f5a2f481586f
Author: Rose Perrone <[email protected]>
Date: Sun Jul 7 13:56:40 2013 -0700
one
diff --git a/A b/A
new file mode 100644
index 0000000..5626abf
--- /dev/null
+++ b/A
@@ -0,0 +1 @@
+one
Poprzednie odpowiedzi obejmowały użycie git rebase -ido edycji zatwierdzenia, które chcesz podzielić, i zatwierdzanie go w częściach.
Działa to dobrze przy dzieleniu plików na różne zatwierdzenia, ale jeśli chcesz rozdzielić zmiany w poszczególnych plikach, musisz wiedzieć więcej.
Po przejściu do zatwierdzenia, które chcesz podzielić, używając go rebase -ii zaznaczając edit, masz dwie opcje.
Po użyciu git reset HEAD~przejrzyj łaty indywidualnie, używając, git add -paby wybrać te, które chcesz w każdym zatwierdzeniu
Edytuj kopię roboczą, aby usunąć niepożądane zmiany; popełnić ten stan przejściowy; a następnie cofnij pełne zatwierdzenie dla następnej rundy.
Opcja 2 jest przydatna, jeśli dzielisz duży zatwierdzenie, ponieważ pozwala sprawdzić, czy wersje tymczasowe budują się i działają poprawnie w ramach scalania. Postępuje to następująco.
Po użyciu rebase -ii editzatwierdzeniu zatwierdzenia użyj
git reset --soft HEAD~
aby cofnąć zatwierdzenie, ale pozostaw zatwierdzone pliki w indeksie. Możesz także wykonać mieszany reset, pomijając --soft, w zależności od tego, jak blisko końcowego wyniku będzie początkowe zatwierdzenie. Jedyna różnica polega na tym, czy zaczynasz od wszystkich wprowadzonych zmian, czy od wszystkich wprowadzonych.
Teraz wejdź i edytuj kod. Możesz usuwać zmiany, usuwać dodane pliki i robić wszystko, co chcesz skonstruować pierwsze zatwierdzenie szukanej serii. Możesz go również zbudować, uruchomić i potwierdzić, że masz spójny zestaw źródeł.
Gdy będziesz zadowolony, ustaw / usuń scenę z plików w razie potrzeby (lubię do git guitego celu) i zatwierdzaj zmiany za pomocą interfejsu użytkownika lub wiersza polecenia
git commit
To pierwsze zatwierdzenie zrobione. Teraz chcesz przywrócić kopię roboczą do stanu, który miał po podzieleniu zatwierdzenia, abyś mógł wprowadzić więcej zmian do następnego zatwierdzenia. Aby znaleźć sha1 edytowanego zatwierdzenia, użyj git status. W pierwszych kilku wierszach statusu zobaczysz aktualnie wykonywane polecenie rebase, w którym możesz znaleźć sha1 oryginalnego zatwierdzenia:
$ git status
interactive rebase in progress; onto be83b41
Last commands done (3 commands done):
pick 4847406 US135756: add debugging to the file download code
e 65dfb6a US135756: write data and download from remote
(see more in file .git/rebase-merge/done)
...
W tym przypadku edytowane przeze mnie zatwierdzenie ma sha1 65dfb6a. Wiedząc o tym, mogę sprawdzić zawartość tego zatwierdzenia w moim katalogu roboczym, używając formularzagit checkout która przyjmuje zarówno lokalizację, jak i lokalizację pliku. Tutaj używam .jako lokalizacji pliku do zastąpienia całej kopii roboczej:
git checkout 65dfb6a .
Nie przegap kropki na końcu!
Spowoduje to sprawdzenie i wyreżyserowanie plików po ich edycji, ale w stosunku do poprzedniego dokonanego zatwierdzenia, więc wszelkie zmiany, które już zatwierdziłeś, nie będą częścią zatwierdzenia.
Możesz albo teraz przejść do przodu i zatwierdzić go tak, jak jest, aby zakończyć podział, lub przejść ponownie, usuwając niektóre części zatwierdzenia przed wykonaniem kolejnego tymczasowego zatwierdzenia.
Jeśli chcesz ponownie użyć oryginalnej wiadomości zatwierdzenia dla jednego lub więcej zatwierdzeń, możesz użyć jej bezpośrednio z plików roboczych rebase:
git commit --file .git/rebase-merge/message
Wreszcie po zatwierdzeniu wszystkich zmian
git rebase --continue
będzie kontynuować i dokończyć operację bazowania.
Dziękuję Ci!!! To powinna być zaakceptowana odpowiedź. Zaoszczędziłbym dziś dużo czasu i bólu. Jest to jedyna odpowiedź, w której wynik ostatecznego zatwierdzenia prowadzi do tego samego stanu, co edytowany zatwierdzenie.
Doug Coburn
1
Podoba mi się sposób, w jaki używasz oryginalnej wiadomości zatwierdzenia.
Salamandar
Używając opcji 2, kiedy to robię git checkout *Sha I'm Editing* ., zawsze mówi Updated 0 paths from *Some Sha That's Not In Git Log*i nie daje żadnych zmian.
W trybie interaktywnym możesz oznaczać zatwierdzenia poprzez akcję „edytuj”. Nie musi to jednak oznaczać, że git rebaseoczekuje się , że wynikiem tej edycji będzie dokładnie jeden zatwierdzenie. Rzeczywiście, możesz cofnąć zatwierdzenie lub dodać inne zatwierdzenia. Można tego użyć do podzielenia zatwierdzenia na dwa:
Rozpocznij interaktywny rebase z git rebase -i <commit>^, gdzie <commit>jest zatwierdzenie, które chcesz podzielić. W rzeczywistości każdy zakres zatwierdzeń będzie działał, o ile będzie zawierał to zatwierdzenie.
Zaznacz zatwierdzenie, które chcesz podzielić, poprzez akcję „edytuj”.
Jeśli chodzi o edycję tego zatwierdzenia, wykonaj git reset HEAD^. W rezultacie HEAD jest przewijany o jeden, a indeks podąża za nim. Jednak działające drzewo pozostaje takie samo.
Teraz dodaj zmiany do indeksu, który chcesz mieć przy pierwszym zatwierdzeniu. Możesz do tego użyć git add(ewentualnie interaktywnie) lub git gui (lub obu).
Zatwierdź bieżący indeks z dowolnym komunikatem zatwierdzenia, który jest teraz odpowiedni.
Powtarzaj dwa ostatnie kroki, aż drzewo robocze będzie czyste.
Kontynuuj zmianę bazy za pomocą git rebase --continue.
Jeśli nie masz absolutnej pewności, że poprawki pośrednie są spójne (kompilują się, przechodzą testsuite itp.), Powinieneś użyć, git stashaby ukryć niezaangażowane zmiany po każdym zatwierdzeniu, przetestować i zmienić zatwierdzenie, jeśli poprawki są konieczne .
W systemie Windows pamiętaj, że ^jest to znak zmiany znaczenia dla wiersza poleceń: należy go podwoić. Na przykład problem git reset HEAD^^zamiast git reset HEAD^.
Frédéric
@ Frédéric: s Nigdy tego nie spotkałem. Przynajmniej w PowerShell tak nie jest. Następnie ^dwukrotne zresetowanie dwóch zatwierdzeń powyżej bieżącej HEAD.
Farway,
@ Farway, spróbuj w klasycznej linii poleceń. PowerShell to kolejna bestia, której ucieczką jest backtilt.
Frédéric
Podsumowując: "HEAD^"w cmd.exe lub PowerShell, HEAD^^w cmd.exe, HEAD`^w PowerShell. Warto dowiedzieć się, jak działają powłoki - i konkretna powłoka - (tj. Jak polecenie zamienia się w poszczególne części przekazywane do programu), aby można było dostosować polecenia online do odpowiednich znaków dla konkretnej powłoki. (Nie dotyczy Windows.)
AndrewF
11
Teraz w najnowszym TortoiseGit na Windows możesz to zrobić bardzo łatwo.
Otwórz okno dialogowe bazy danych, skonfiguruj je i wykonaj następujące czynności.
Kliknij prawym przyciskiem myszy zatwierdzenie, które chcesz podzielić, i wybierz „ Edit” (spośród operacji wyboru, squash, usuń ...).
Kliknij „ Start”, aby rozpocząć bazowanie.
Gdy dojdzie do zatwierdzenia do podziału, zaznacz przycisk „ Edit/Split” i kliknij Amendbezpośrednio „ ”. Zostanie otwarte okno dialogowe zatwierdzenia.
Odznacz pliki, które chcesz umieścić w osobnym zatwierdzeniu.
Edytuj komunikat zatwierdzenia, a następnie kliknij „ commit”.
Dopóki nie będzie plików do zatwierdzenia, okno dialogowe zatwierdzania będzie otwierane raz za razem. Gdy nie będzie już więcej pliku do zatwierdzenia, nadal będzie Cię pytać, czy chcesz dodać jeszcze jedno zatwierdzenie.
Przydałoby się nieco więcej kontekstu, w jaki sposób podejść do problemów, niż samo podanie RTFM byłoby nieco bardziej pomocne.
Jordan Dea-Mattson,
8
Pamiętaj, że jest też git reset --soft HEAD^. Jest podobny do git reset(domyślnie --mixed), ale zachowuje zawartość indeksu. Tak więc, jeśli dodałeś / usunąłeś pliki, masz je już w indeksie.
Okazuje się, że jest bardzo przydatny w przypadku gigantycznych zmian.
Oto jak podzielić jeden zatwierdzenie w IntelliJ IDEA , PyCharm , PhpStorm itp
W oknie dziennika kontroli wersji wybierz zatwierdzenie, które chcesz podzielić, kliknij prawym przyciskiem myszy i wybierz Interactively Rebase from Here
zaznacz ten, który chcesz podzielić edit, kliknijStart
Rebasing
Powinieneś zobaczyć żółty znacznik, co oznacza, że HEAD jest ustawiony na to zatwierdzenie. Kliknij zatwierdzenie prawym przyciskiem myszy, wybierzUndo Commit
Teraz te zatwierdzenia wróciły do obszaru przeciwności, możesz je następnie zatwierdzić osobno. Po zatwierdzeniu wszystkich zmian stare zatwierdzenie staje się nieaktywne.
Najłatwiejszą rzeczą do zrobienia bez interaktywnego bazowania jest (prawdopodobnie) utworzenie nowej gałęzi zaczynającej się od zatwierdzenia przed tą, którą chcesz podzielić, wybranie -n-zatwierdzenie, zresetowanie, ukrywanie, zatwierdzenie przeniesienia pliku, ponowne zastosowanie ukrywania i zatwierdzić zmiany, a następnie albo połączyć się z poprzednim oddziałem, albo wybrać kolejne zatwierdzenia. (Następnie zmień nazwę poprzedniej gałęzi na obecną.) (Prawdopodobnie lepiej postępować zgodnie z radami MBO i zrobić interaktywny rebase.)
zgodnie ze standardami SO w dzisiejszych czasach należy to zakwalifikować jako brak odpowiedzi; ale to może być pomocne dla innych, więc jeśli nie masz nic przeciwko, przenieś to do komentarzy do oryginalnego postu
YakovL,
@YakovL Wydaje się rozsądny. Na zasadzie minimalnego działania nie usunę odpowiedzi, ale nie sprzeciwiłbym się, gdyby zrobił to ktoś inny.
William Pursell,
byłoby to o wiele łatwiejsze niż wszystkie rebase -isugestie. Myślę jednak, że nie zwróciło to uwagi na brak jakiegokolwiek formatowania. Może mógłbyś to przejrzeć, skoro masz 126 tys. Punktów i prawdopodobnie wiesz, jak to zrobić. ;)
Minęło ponad 8 lat, ale może i tak ktoś mu to pomoże. Byłem w stanie załatwić sprawę bez rebase -i. Chodzi o to, aby doprowadzić git do tego samego stanu, w jakim był przedtem git commit:
# first rewind back (mind the dot,# though it can be any valid path,# for instance if you want to apply only a subset of the commit)
git reset --hard <previous-commit>.# apply the changes
git checkout <commit-you-want-to-split># we're almost there, but the changes are in the index at the moment,# hence one more step (exactly as git gently suggests):# (use "git reset HEAD <file>..." to unstage)
git reset
Po tym zobaczysz to błyszczące, Unstaged changes after reset:a Twoje repo jest w stanie, jakbyś miał zamiar zatwierdzić wszystkie te pliki. Od teraz możesz łatwo zatwierdzić to ponownie, jak zwykle. Mam nadzieję, że to pomoże.
git autorebase split COMMIT_ID
git reset HEAD~
,git stash
, a następniegit cherry-pick
pierwszą popełnić w squasha, a następniegit stash pop
. Mój przypadek cherry-pick jest dość specyficzny tutaj, alegit stash
igit stash pop
jest bardzo przydatny dla innych.Odpowiedzi:
git rebase -i
zrobię to.Najpierw zacznij od czystego katalogu roboczego: nie
git status
powinien pokazywać żadnych oczekujących modyfikacji, usunięć ani dodatków.Teraz musisz zdecydować, które zatwierdzenia chcesz podzielić.
A) Dzielenie ostatniego zatwierdzenia
Aby podzielić ostatnie zatwierdzenie, najpierw:
Teraz przydzielaj elementy indywidualnie w zwykły sposób, tworząc tyle zmian, ile potrzebujesz.
B) Dzielenie zatwierdzenia dalej w tył
Wymaga to przekształcenia , czyli przepisania historii. Aby znaleźć poprawne zatwierdzenie, masz kilka możliwości:
Jeśli to były trzy zobowiązania, to wtedy
gdzie
3
jest ile to zatwierdza.Jeśli to było dalej w drzewie, niż chcesz policzyć, to
gdzie
123abcd
jest SHA1 zatwierdzenia, które chcesz podzielić.Jeśli jesteś w innej gałęzi (np. Gałąź funkcji), którą planujesz scalić w master:
Gdy pojawi się ekran edycji bazy, znajdź zatwierdzenie, które chcesz rozdzielić. Na początku tej linii, należy wymienić
pick
zedit
(e
w skrócie). Zapisz bufor i wyjdź. Rebase zatrzyma się teraz zaraz po zatwierdzeniu, które chcesz edytować. Następnie:Popełniaj poszczególne elementy w zwykły sposób, wytwarzając tyle zmian, ile potrzebujesz
źródło
git rebase --continue
, tak naprawdę musiałgit add (files to be added)
,git commit
, a następniegit stash
(w przypadku pozostałych plików). Pogit rebase --continue
użyłemgit checkout stash .
, aby uzyskać pozostałe plikigit add -p
dodawania tylko częściowych sekcji plików, być może ze
opcją edycji różnic, aby zatwierdzić tylko część przystawki.git stash
jest również przydatny, jeśli chcesz kontynuować pracę, ale usunąć ją z bieżącego zatwierdzenia.git rebase -i HEAD^3
polecenia. W ten sposób, jeśli podział pójdzie źle, nie musisz cofać tyle pracy.git reset HEAD~
. Nie są zgubieni.Z instrukcji git-rebase (sekcja DOTYCZĄCE ROZDZIELANIA)
źródło
~
zamiast^
.reset
na zatwierdzenie - w tym wiadomość. Rozsądną rzeczą do zrobienia, jeśli wiesz, że będziesz dzielić zatwierdzenie, ale chcesz zachować część / całość jego wiadomości, jest zrobienie kopii tej wiadomości. Tak więc,git show
zatwierdź przedrebase
ing, lub jeśli zapomnisz lub wolisz: wróć do niego później przezreflog
. Nic z tego nie zostanie „zagubione”, dopóki nie zostanie zebrane w ciągu 2 tygodni.~
i^
są różne rzeczy, nawet w systemie Windows. Nadal chcesz kursora^
, więc musisz po prostu uciec z niego odpowiednio do twojej powłoki. W PowerShell to jestHEAD`^
. Za pomocą cmd.exe możesz podwoić go, aby uciecHEAD^^
. W większości (wszystkich?) Powłok można otaczać cytatami takimi jak"HEAD^"
.git commit --reuse-message=abcd123
. Krótka opcja to-C
.Użyj
git rebase --interactive
do edycji tego wcześniejszego zatwierdzenia, uruchomgit reset HEAD~
, a następniegit add -p
dodaj niektóre, następnie dokonaj zatwierdzenia, następnie dodaj kolejne i dokonaj kolejnego zatwierdzenia, tyle razy, ile chcesz. Kiedy skończysz, uruchomgit rebase --continue
, a będziesz miał wszystkie zatwierdzenia podziału wcześniej na swoim stosie.Ważne : pamiętaj, że możesz się pobawić i wprowadzić wszystkie potrzebne zmiany i nie musisz się martwić utratą starych zmian, ponieważ zawsze możesz uruchomić,
git reflog
aby znaleźć punkt w projekcie, który zawiera żądane zmiany (nazwijmy toa8c4ab
) , a następniegit reset a8c4ab
.Oto seria poleceń pokazujących, jak to działa:
mkdir git-test; cd git-test; git init
teraz dodaj plik
A
vi A
dodaj tę linię:
one
git commit -am one
następnie dodaj ten wiersz do A:
two
git commit -am two
następnie dodaj ten wiersz do A:
three
git commit -am three
teraz plik A wygląda następująco:
i nasze
git log
wygląda następująco (cóż, używamgit log --pretty=oneline --pretty="%h %cn %cr ---- %s"
Powiedzmy, że chcemy podzielić drugi popełnić
two
.git rebase --interactive HEAD~2
Spowoduje to wyświetlenie następującego komunikatu:
Zmień pierwszy
pick
na,e
aby edytować zatwierdzenie.git reset HEAD~
git diff
pokazuje nam, że właśnie przeprowadziliśmy inscenizację zatwierdzenia dokonanego dla drugiego zatwierdzenia:Dokonajmy tej zmiany i dodajmy „i trzeci” do tego wiersza w pliku
A
.git add .
Zazwyczaj jest to punkt podczas interaktywnego rebase, w którym działamy
git rebase --continue
, ponieważ zwykle chcemy po prostu wrócić do naszego stosu zmian, aby edytować wcześniejsze zatwierdzenie. Ale tym razem chcemy stworzyć nowe zatwierdzenie. Więc uciekniemygit commit -am 'two and a third'
. Teraz edytujemy plikA
i dodajemy liniętwo and two thirds
.git add .
git commit -am 'two and two thirds'
git rebase --continue
Mamy konflikt z naszym zatwierdzeniem
three
, więc rozwiążmy go:Zmienimy się
do
git add .; git rebase --continue
Teraz
git log -p
wygląda to tak:źródło
Poprzednie odpowiedzi obejmowały użycie
git rebase -i
do edycji zatwierdzenia, które chcesz podzielić, i zatwierdzanie go w częściach.Działa to dobrze przy dzieleniu plików na różne zatwierdzenia, ale jeśli chcesz rozdzielić zmiany w poszczególnych plikach, musisz wiedzieć więcej.
Po przejściu do zatwierdzenia, które chcesz podzielić, używając go
rebase -i
i zaznaczającedit
, masz dwie opcje.Po użyciu
git reset HEAD~
przejrzyj łaty indywidualnie, używając,git add -p
aby wybrać te, które chcesz w każdym zatwierdzeniuEdytuj kopię roboczą, aby usunąć niepożądane zmiany; popełnić ten stan przejściowy; a następnie cofnij pełne zatwierdzenie dla następnej rundy.
Opcja 2 jest przydatna, jeśli dzielisz duży zatwierdzenie, ponieważ pozwala sprawdzić, czy wersje tymczasowe budują się i działają poprawnie w ramach scalania. Postępuje to następująco.
Po użyciu
rebase -i
iedit
zatwierdzeniu zatwierdzenia użyjaby cofnąć zatwierdzenie, ale pozostaw zatwierdzone pliki w indeksie. Możesz także wykonać mieszany reset, pomijając --soft, w zależności od tego, jak blisko końcowego wyniku będzie początkowe zatwierdzenie. Jedyna różnica polega na tym, czy zaczynasz od wszystkich wprowadzonych zmian, czy od wszystkich wprowadzonych.
Teraz wejdź i edytuj kod. Możesz usuwać zmiany, usuwać dodane pliki i robić wszystko, co chcesz skonstruować pierwsze zatwierdzenie szukanej serii. Możesz go również zbudować, uruchomić i potwierdzić, że masz spójny zestaw źródeł.
Gdy będziesz zadowolony, ustaw / usuń scenę z plików w razie potrzeby (lubię do
git gui
tego celu) i zatwierdzaj zmiany za pomocą interfejsu użytkownika lub wiersza poleceniaTo pierwsze zatwierdzenie zrobione. Teraz chcesz przywrócić kopię roboczą do stanu, który miał po podzieleniu zatwierdzenia, abyś mógł wprowadzić więcej zmian do następnego zatwierdzenia. Aby znaleźć sha1 edytowanego zatwierdzenia, użyj
git status
. W pierwszych kilku wierszach statusu zobaczysz aktualnie wykonywane polecenie rebase, w którym możesz znaleźć sha1 oryginalnego zatwierdzenia:W tym przypadku edytowane przeze mnie zatwierdzenie ma sha1
65dfb6a
. Wiedząc o tym, mogę sprawdzić zawartość tego zatwierdzenia w moim katalogu roboczym, używając formularzagit checkout
która przyjmuje zarówno lokalizację, jak i lokalizację pliku. Tutaj używam.
jako lokalizacji pliku do zastąpienia całej kopii roboczej:Nie przegap kropki na końcu!
Spowoduje to sprawdzenie i wyreżyserowanie plików po ich edycji, ale w stosunku do poprzedniego dokonanego zatwierdzenia, więc wszelkie zmiany, które już zatwierdziłeś, nie będą częścią zatwierdzenia.
Możesz albo teraz przejść do przodu i zatwierdzić go tak, jak jest, aby zakończyć podział, lub przejść ponownie, usuwając niektóre części zatwierdzenia przed wykonaniem kolejnego tymczasowego zatwierdzenia.
Jeśli chcesz ponownie użyć oryginalnej wiadomości zatwierdzenia dla jednego lub więcej zatwierdzeń, możesz użyć jej bezpośrednio z plików roboczych rebase:
Wreszcie po zatwierdzeniu wszystkich zmian
będzie kontynuować i dokończyć operację bazowania.
źródło
git checkout *Sha I'm Editing* .
, zawsze mówiUpdated 0 paths from *Some Sha That's Not In Git Log*
i nie daje żadnych zmian.git rebase --interactive
można użyć do podzielenia zatwierdzenia na mniejsze zatwierdzenia. Dokumenty Git dotyczące bazy danych zawierają zwięzły opis procesu - Dzielenie zobowiązań :źródło
^
jest to znak zmiany znaczenia dla wiersza poleceń: należy go podwoić. Na przykład problemgit reset HEAD^^
zamiastgit reset HEAD^
.^
dwukrotne zresetowanie dwóch zatwierdzeń powyżej bieżącej HEAD."HEAD^"
w cmd.exe lub PowerShell,HEAD^^
w cmd.exe,HEAD`^
w PowerShell. Warto dowiedzieć się, jak działają powłoki - i konkretna powłoka - (tj. Jak polecenie zamienia się w poszczególne części przekazywane do programu), aby można było dostosować polecenia online do odpowiednich znaków dla konkretnej powłoki. (Nie dotyczy Windows.)Teraz w najnowszym TortoiseGit na Windows możesz to zrobić bardzo łatwo.
Otwórz okno dialogowe bazy danych, skonfiguruj je i wykonaj następujące czynności.
Edit
” (spośród operacji wyboru, squash, usuń ...).Start
”, aby rozpocząć bazowanie.Edit/Split
” i kliknijAmend
bezpośrednio „ ”. Zostanie otwarte okno dialogowe zatwierdzenia.commit
”.Bardzo pomocny, dzięki TortoiseGit!
źródło
Możesz zrobić interaktywną bazę
git rebase -i
. Strona podręcznika ma dokładnie to, czego chcesz:http://git-scm.com/docs/git-rebase#_splitting_commits
źródło
Pamiętaj, że jest też
git reset --soft HEAD^
. Jest podobny dogit reset
(domyślnie--mixed
), ale zachowuje zawartość indeksu. Tak więc, jeśli dodałeś / usunąłeś pliki, masz je już w indeksie.Okazuje się, że jest bardzo przydatny w przypadku gigantycznych zmian.
źródło
Oto jak podzielić jeden zatwierdzenie w IntelliJ IDEA , PyCharm , PhpStorm itp
W oknie dziennika kontroli wersji wybierz zatwierdzenie, które chcesz podzielić, kliknij prawym przyciskiem myszy i wybierz
Interactively Rebase from Here
zaznacz ten, który chcesz podzielić
edit
, kliknijStart Rebasing
Powinieneś zobaczyć żółty znacznik, co oznacza, że HEAD jest ustawiony na to zatwierdzenie. Kliknij zatwierdzenie prawym przyciskiem myszy, wybierz
Undo Commit
Teraz te zatwierdzenia wróciły do obszaru przeciwności, możesz je następnie zatwierdzić osobno. Po zatwierdzeniu wszystkich zmian stare zatwierdzenie staje się nieaktywne.
źródło
Najłatwiejszą rzeczą do zrobienia bez interaktywnego bazowania jest (prawdopodobnie) utworzenie nowej gałęzi zaczynającej się od zatwierdzenia przed tą, którą chcesz podzielić, wybranie -n-zatwierdzenie, zresetowanie, ukrywanie, zatwierdzenie przeniesienia pliku, ponowne zastosowanie ukrywania i zatwierdzić zmiany, a następnie albo połączyć się z poprzednim oddziałem, albo wybrać kolejne zatwierdzenia. (Następnie zmień nazwę poprzedniej gałęzi na obecną.) (Prawdopodobnie lepiej postępować zgodnie z radami MBO i zrobić interaktywny rebase.)
źródło
rebase -i
sugestie. Myślę jednak, że nie zwróciło to uwagi na brak jakiegokolwiek formatowania. Może mógłbyś to przejrzeć, skoro masz 126 tys. Punktów i prawdopodobnie wiesz, jak to zrobić. ;)Myślę, że to najlepszy sposób, którego używam
git rebase -i
. Stworzyłem film, aby pokazać kroki dzielenia zatwierdzenia: https://www.youtube.com/watch?v=3EzOz7e1ADIźródło
Jeśli masz to:
W przypadku popełnienia niektórych treści w zatwierdzeniu B:
Ale chcesz podzielić B na C - D i uzyskać ten wynik:
Możesz na przykład podzielić zawartość w ten sposób (zawartość z różnych katalogów w różnych zatwierdzeniach) ...
Zresetuj gałąź z powrotem do zatwierdzenia przed tym do podziału:
Utwórz pierwsze zatwierdzenie (C):
Utwórz drugie zatwierdzenie (D):
źródło
Minęło ponad 8 lat, ale może i tak ktoś mu to pomoże. Byłem w stanie załatwić sprawę bez
rebase -i
. Chodzi o to, aby doprowadzić git do tego samego stanu, w jakim był przedtemgit commit
:Po tym zobaczysz to błyszczące,
Unstaged changes after reset:
a Twoje repo jest w stanie, jakbyś miał zamiar zatwierdzić wszystkie te pliki. Od teraz możesz łatwo zatwierdzić to ponownie, jak zwykle. Mam nadzieję, że to pomoże.źródło
Krótkie omówienie niezbędnych poleceń, ponieważ w zasadzie wiem, co robić, ale zawsze zapominam o właściwej składni:
Podziękowania dla posta na blogu Emmanuela Bernarda .
źródło