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?

Koblas
źródło
36
Dobrym źródłem informacji na temat tego, jak to zrobić, jest Pro Git § 6.4 Git Tools - Przepisywanie historii , w sekcji „Dzielenie się zobowiązaniami”.
2
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.
SOFe

Odpowiedzi:

1797

git rebase -i zrobię to.

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

$ git rebase --continue
Wayne Conrad
źródło
2
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.

MBO
źródło
12
W systemie Windows używasz ~zamiast ^.
Kevin Kuszyk
13
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.

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:

one
two
three

i nasze git logwygląda następująco (cóż, używamgit log --pretty=oneline --pretty="%h %cn %cr ---- %s"

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
Rose Perrone
źródło
38

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.

  1. Po użyciu git reset HEAD~przejrzyj łaty indywidualnie, używając, git add -paby wybrać te, które chcesz w każdym zatwierdzeniu

  2. 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.

Andy Mortimer
źródło
3
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.
Noumenon
18

git rebase --interactivemożna użyć do podzielenia zatwierdzenia na mniejsze zatwierdzenia. Dokumenty Git dotyczące bazy danych zawierają zwięzły opis procesu - Dzielenie zobowiązań :

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 .


źródło
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.
    Edytuj / Podziel zatwierdzenie
  • 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.

Bardzo pomocny, dzięki TortoiseGit!

Mikaël Mayer
źródło
10

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

manojlds
źródło
14
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.

zabójca
źródło
3

Oto jak podzielić jeden zatwierdzenie w IntelliJ IDEA , PyCharm , PhpStorm itp

  1. W oknie dziennika kontroli wersji wybierz zatwierdzenie, które chcesz podzielić, kliknij prawym przyciskiem myszy i wybierz Interactively Rebase from Here

  2. zaznacz ten, który chcesz podzielić edit, kliknijStart Rebasing

  3. Powinieneś zobaczyć żółty znacznik, co oznacza, że ​​HEAD jest ustawiony na to zatwierdzenie. Kliknij zatwierdzenie prawym przyciskiem myszy, wybierzUndo Commit

  4. 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.

bzuo
źródło
2

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.)

William Pursell
źródło
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ć. ;)
erikbwork
1

Jeśli masz to:

A - B <- mybranch

W przypadku popełnienia niektórych treści w zatwierdzeniu B:

/modules/a/file1
/modules/a/file2
/modules/b/file3
/modules/b/file4

Ale chcesz podzielić B na C - D i uzyskać ten wynik:

A - C - D <-mybranch

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:

git checkout mybranch
git reset --hard A

Utwórz pierwsze zatwierdzenie (C):

git checkout B /modules/a
git add -u
git commit -m "content of /modules/a"

Utwórz drugie zatwierdzenie (D):

git checkout B /modules/b
git add -u
git commit -m "content of /modules/b"
Martin G.
źródło
Co jeśli są zatwierdzenia powyżej B?
CoolMind,
1

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.

Stanislav E. Govorov
źródło
0

Krótkie omówienie niezbędnych poleceń, ponieważ w zasadzie wiem, co robić, ale zawsze zapominam o właściwej składni:

git rebase -i <sha1_before_split>
# mark the targeted commit with 'edit'
git reset HEAD^
git add ...
git commit -m "First part"
git add ...
git commit -m "Second part"
git rebase --continue

Podziękowania dla posta na blogu Emmanuela Bernarda .

Sparkofska
źródło