Przenieś najnowsze zatwierdzenia do nowego oddziału za pomocą Git

4981

Chciałbym przenieść kilka ostatnich zatwierdzeń, które zobowiązałem się opanować do nowego oddziału i zabrać wzorca z powrotem, zanim te zatwierdzenia zostaną wykonane. Niestety mój Git-fu nie jest jeszcze wystarczająco silny, jakaś pomoc?

Tj. Jak mogę z tego wyjść

master A - B - C - D - E

do tego?

newbranch     C - D - E
             /
master A - B 
Mark A. Nicolosi
źródło
114
Uwaga: Poprosiłem przeciwny pytanie tutaj
Benjol
3
eddmann.com/posts/… ten działa
Sagar Naliyapara 25.04.17
6
Czy komentarze tutaj zostały oczyszczone? Pytam, ponieważ podczas mojej dwumiesięcznej wizyty na to pytanie zawsze przewijam ten komentarz.
Tejas Kale,

Odpowiedzi:

6449

Przeprowadzka do istniejącego oddziału

Jeśli chcesz przenieść swoje commity do istniejącego oddziału , będzie to wyglądać następująco:

git checkout existingbranch
git merge master         # Bring the commits here
git checkout master
git reset --keep HEAD~3  # Move master back by 3 commits.
git checkout existingbranch

Ta --keepopcja zachowuje wszelkie niezatwierdzone zmiany, które możesz mieć w niepowiązanych plikach, lub przerywa, jeśli zmiany te musiałyby zostać zastąpione - podobnie jak to git checkoutrobi. Jeśli zostanie przerwane, git stashzmiany i spróbuj ponownie lub użyj, --hardaby je utracić (nawet z plików, które nie zmieniły się między zatwierdzeniami!)

Przeprowadzka do nowego oddziału

Ta metoda działa, tworząc nową gałąź za pomocą pierwszego polecenia ( git branch newbranch), ale nie przełączając się na nią. Następnie wycofujemy bieżącą gałąź (master) i przełączamy na nową gałąź, aby kontynuować pracę.

git branch newbranch      # Create a new branch, containing all current commits
git reset --keep HEAD~3   # Move master back by 3 commits (Make sure you know how many commits you need to go back)
git checkout newbranch    # Go to the new branch that still has the desired commits
# Warning: after this it's not safe to do a rebase in newbranch without extra care.

Ale upewnij się, ile cofnięć. Alternatywnie, zamiast HEAD~3, możesz po prostu podać hash zatwierdzenia (lub odnośnik podobny origin/master), do którego chcesz wrócić, np .:

git reset --keep a1b2c3d4

OSTRZEŻENIE: W przypadku wersji Git 2.0 i nowszych, jeśli później git rebasenowa gałąź w gałęzi oryginalnej ( master), może być potrzebna wyraźna --no-fork-pointopcja podczas bazy, aby uniknąć utraty zatwierdzeń przeniesionych z gałęzi głównej. Po branch.autosetuprebase alwaysustawieniu jest to bardziej prawdopodobne. Szczegółowe informacje można znaleźć w odpowiedzi Johna Mellora .

Duc Filan
źródło
249
W szczególności nie próbuj cofać się dalej niż do momentu, w którym ostatnio wypychałeś zatwierdzenia do innego repozytorium, z którego ktoś mógł wyciągnąć.
Greg Hewgill
107
Zastanawiasz się, czy możesz wyjaśnić DLACZEGO to działa. Dla mnie tworzysz nową gałąź, usuwając 3 zatwierdzenia ze starej gałęzi, w której wciąż jesteś, a następnie sprawdzasz gałąź, którą utworzyłeś. Jak więc magiczne zmiany, które usunąłeś, pojawiają się w nowej gałęzi?
Jonathan Dumaine
142
@Jonathan Dumaine: Ponieważ utworzyłem nowy oddział przed usunięciem zatwierdzeń ze starego oddziału. Nadal są w nowej gałęzi.
sykora,
86
gałęzie w git są tylko znacznikami, które wskazują na zatwierdzenia w historii, nic nie jest klonowane, tworzone ani usuwane (z wyjątkiem znaczników)
knittl
218
Uwaga: nie rób tego z niezatwierdzonymi zmianami w kopii roboczej! To mnie ugryzło! :(
Adam Tuttle,
1038

Dla tych, którzy zastanawiają się, dlaczego to działa (tak jak na początku byłem):

Chcesz wrócić do C i przenieść D i E do nowej gałęzi. Oto jak to wygląda na początku:

A-B-C-D-E (HEAD)
        ↑
      master

Po git branch newBranch:

    newBranch
        ↓
A-B-C-D-E (HEAD)
        ↑
      master

Po git reset --hard HEAD~2:

    newBranch
        ↓
A-B-C-D-E (HEAD)
    ↑
  master

Ponieważ gałąź jest tylko wskaźnikiem, master wskazał na ostatnie zatwierdzenie. Kiedy tworzysz newBranch , po prostu tworzysz nowy wskaźnik do ostatniego zatwierdzenia. Następnie za pomocą git resetprzesunąłeś główny wskaźnik z powrotem o dwa zatwierdzenia. Ale ponieważ nie przeniosłeś newBranch , nadal wskazuje na zatwierdzenie, które pierwotnie zrobił.

Ryan Lundy
źródło
55
Musiałem także zrobić, git push origin master --forceaby zmiana pojawiła się w głównym repozytorium.
Dženan
9
Ta odpowiedź powoduje, że commity zostają utracone: następnym razem git rebase, 3 commity zostaną po cichu odrzucone newbranch. Zobacz moją odpowiedź, aby uzyskać szczegółowe informacje i bezpieczniejsze alternatywy.
John Mellor,
14
@John, to nonsens. Rebasing bez wiedzy o tym, co robisz, powoduje, że zobowiązania są tracone. Jeśli straciłeś zobowiązania, przepraszam za ciebie, ale ta odpowiedź nie straciła twoich zobowiązań. Zauważ, że origin/masternie ma go na powyższym schemacie. Gdybyś naciskał na, origin/mastera następnie wprowadził powyższe zmiany, na pewno wszystko byłoby śmieszne. Ale to jest problem typu „Doktorze, boli mnie, kiedy to robię”. I to nie wchodzi w zakres tego, co zadało pierwotne pytanie. Sugeruję, abyś napisał własne pytanie, aby zbadać swój scenariusz, zamiast porywać go.
Ryan Lundy,
1
@John, w swojej odpowiedzi powiedziałeś „Nie rób tego! git branch -t newbranch”. Wróć i przeczytaj odpowiedzi ponownie. Nikt tego nie sugerował.
Ryan Lundy,
1
@ Kyralessa, jasne, ale jeśli spojrzysz na diagram w pytaniu, jasne jest, że chcą newbranchoprzeć się na swoim istniejącym masteroddziale lokalnym . Po wykonaniu zaakceptowanej odpowiedzi, gdy użytkownik pobiera około uruchomieniem git rebasew newbranchgit przypomni im, że zapomniał ustawić upstream oddziału, więc będą działać git branch --set-upstream-to=masterwtedy git rebasei mają ten sam problem. Mogą równie dobrze wykorzystać git branch -t newbranchw pierwszej kolejności.
John Mellor,
454

Ogólnie...

Metoda ujawniona przez sykora jest w tym przypadku najlepszą opcją. Ale czasem nie jest najłatwiejszy i nie jest to ogólna metoda. Do ogólnej metody użyj git cherry-pick :

Aby osiągnąć to, czego chce OP, jest to dwuetapowy proces:

Krok 1 - zanotuj, które zatwierdzenia od mistrza chcesz na newbranch

Wykonać

git checkout master
git log

Zwróć uwagę na skróty (powiedzmy 3) zatwierdzeń, które chcesz newbranch. Tutaj użyję:
C zatwierdzenia: 9aa1233
D zatwierdzenia: 453ac3d
E zatwierdzenia:612ecb3

Uwaga: Możesz użyć pierwszych siedmiu znaków lub całego skrótu zatwierdzenia

Krok 2 - Włóż je do newbranch

git checkout newbranch
git cherry-pick 612ecb3
git cherry-pick 453ac3d
git cherry-pick 9aa1233

LUB (w Git 1.7.2+ użyj zakresów)

git checkout newbranch
git cherry-pick 612ecb3~1..9aa1233

git cherry-pick stosuje te trzy zmiany do newbranch.

Ivan
źródło
13
Czy OP nie próbował przejść z master do newbranch? Jeśli wybierzesz cherry podczas master, będziesz dodawał do gałęzi master - dodając w rzeczywistości zatwierdzenia, które już miał. I nie przesuwa żadnej głowy oddziału do B. Czy jest coś subtelnego i fajnego, czego nie dostaję?
RaveTheTadpole
6
Działa to bardzo dobrze, jeśli przypadkowo popełnisz niewłaściwą gałąź inną niż master, kiedy powinieneś utworzyć nową gałąź funkcji.
julianc
5
+1 za przydatne podejście w niektórych sytuacjach. Jest to dobre, jeśli chcesz tylko wyciągnąć własne zatwierdzenia (które są przeplatane z innymi) do nowej gałęzi.
Tyler V.
7
To lepsza odpowiedź. W ten sposób możesz przenosić zatwierdzenia do dowolnego oddziału.
skywinder
8
Czy kolejność zbierania wiśni jest ważna?
kon psych
328

Jeszcze inny sposób, aby to zrobić, używając tylko 2 poleceń. Utrzymuje również bieżące drzewo robocze nietknięte.

git checkout -b newbranch # switch to a new branch
git branch -f master HEAD~3 # make master point to some older commit

Stara wersja - zanim się dowiedziałamgit branch -f

git checkout -b newbranch # switch to a new branch
git push . +HEAD~3:master # make master point to some older commit 

Będąc w stanie pushna .to miły podstęp wiedzieć.

aragaer
źródło
1
Aktualny katalog. Myślę, że to zadziałałoby tylko, jeśli jesteś w głównym katalogu.
aragaer
1
Lokalny pchnięcie wywołuje uśmiech, ale po zastanowieniu, czym się git branch -ftu różni ?
jthill
2
@ GerardSexton .jest obecnym dyrektorem. git może przekazywać do ZDALNYCH adresów URL lub adresów URL GIT. path to local directoryobsługiwana jest składnia adresów URL Git. Zobacz sekcję GIT URLS w git help clone.
słaby
31
Nie wiem, dlaczego nie ma wyższej oceny. Zupełnie prosty i bez małego, ale potencjalnego niebezpieczeństwa resetu git - twardy.
Godsmith,
4
@Godsmith Domyślam się, że ludzie wolą trzy proste polecenia od dwóch nieco bardziej niejasnych poleceń. Ponadto najlepiej głosowane odpowiedzi otrzymują więcej pozytywnych opinii ze względu na to, że są wyświetlane jako pierwsze.
JS_Riddler
321

Większość poprzednich odpowiedzi jest niebezpiecznie błędna!

Nie rób tego:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

Gdy następnym razem uruchomisz git rebase(lub git pull --rebase) te 3 zatwierdzenia zostaną po cichu odrzucone newbranch! (patrz wyjaśnienie poniżej)

Zamiast tego zrób to:

git reset --keep HEAD~3
git checkout -t -b newbranch
git cherry-pick ..HEAD@{2}
  • Najpierw odrzuca 3 ostatnie zatwierdzenia ( --keepjest jak --hard, ale bezpieczniejsze, bo zawiedzie, zamiast odrzucać niezaangażowane zmiany).
  • Potem rozwidla się newbranch.
  • Następnie wiśnia wybiera te 3 zmiany z powrotem na newbranch. Skoro jesteśmy już nie odwołuje się oddział, to robi to za pomocą git za reflog : HEAD@{2}jest popełnić, że HEADodnosi się do 2 operacje temu, czyli zanim 1. wyrejestrowany newbranchi 2. używane git resetaby odrzucić 3 zobowiązuje.

Ostrzeżenie: reflog jest domyślnie włączony, ale jeśli go ręcznie wyłączyłeś (np. Używając „gołego” repozytorium git), nie będziesz mógł odzyskać 3 zatwierdzeń po uruchomieniu git reset --keep HEAD~3.

Alternatywą, która nie polega na logowaniu jest:

# newbranch will omit the 3 most recent commits.
git checkout -b newbranch HEAD~3
git branch --set-upstream-to=oldbranch
# Cherry-picks the extra commits from oldbranch.
git cherry-pick ..oldbranch
# Discards the 3 most recent commits from oldbranch.
git branch --force oldbranch oldbranch~3

(jeśli wolisz, możesz pisać @{-1}- gałąź wcześniej wypisana - zamiast oldbranch).


Wyjaśnienie techniczne

Po co git rebaseodrzucać 3 zatwierdzenia po pierwszym przykładzie? To dlatego, że git rebasebez argumentów włącza --fork-pointdomyślnie opcję, która używa lokalnego reflogu, aby spróbować być odpornym na wymuszanie wypychania gałęzi upstream.

Załóżmy, że rozgałęziłeś początek / wzorzec, gdy zawierał zatwierdzenia M1, M2, M3, a następnie sam dokonałeś trzech zatwierdzeń:

M1--M2--M3  <-- origin/master
         \
          T1--T2--T3  <-- topic

ale potem ktoś przepisuje historię, zmuszając źródło / master do usunięcia M2:

M1--M3'  <-- origin/master
 \
  M2--M3--T1--T2--T3  <-- topic

Korzystając z lokalnego dziennika, git rebasemożesz zobaczyć, że rozwidliłeś się z wcześniejszej inkarnacji gałęzi origin / master, a zatem, że zatwierdzenia M2 i M3 tak naprawdę nie są częścią twojej gałęzi tematów. Stąd rozsądnie zakłada się, że skoro M2 zostało usunięte z gałęzi upstream, nie będzie już potrzebne w gałęzi tematu, gdy gałąź tematu zostanie ponownie wydana:

M1--M3'  <-- origin/master
     \
      T1'--T2'--T3'  <-- topic (rebased)

Takie zachowanie ma sens i ogólnie jest właściwą rzeczą do zrobienia podczas bazowania.

Dlatego przyczyną niepowodzenia następujących poleceń:

git branch -t newbranch
git reset --hard HEAD~3
git checkout newbranch

to dlatego, że pozostawiają rejestr w złym stanie. Git widzi, newbranchże rozwidlił gałąź odgałęzienia w wersji, która zawiera 3 zatwierdzenia, a następnie reset --hardprzepisuje historię pobierania w górę, aby usunąć zatwierdzenia, a więc następnym razem, gdy git rebasego uruchomisz , odrzuca je jak każde inne zatwierdzenie, które zostało usunięte z pobierania.

Ale w tym konkretnym przypadku chcemy, aby te 3 zatwierdzenia były traktowane jako część gałęzi tematu. Aby to osiągnąć, musimy oddzielić się od poprzedniej wersji, która nie obejmuje 3 zatwierdzeń. To właśnie robią moje sugerowane rozwiązania, dlatego oba pozostawiają rejestr w prawidłowym stanie.

Aby uzyskać więcej informacji, zobacz definicję --fork-pointw dokumentacji git rebase i git merge-base .

John Mellor
źródło
14
Ta odpowiedź mówi „NIE rób tego!” ponad coś, czego nikt nie sugerował.
Ryan Lundy
3
Większość ludzi nie przepisuje opublikowanej historii, zwłaszcza na master. Więc nie, nie są niebezpiecznie w błędzie.
Walf
4
@ Kyralessa, do -tktórego się odnosisz, git branchdzieje się niejawnie, jeśli git config --global branch.autosetuprebase alwaysustawiłeś. Nawet jeśli nie, wyjaśniłem już , że ten sam problem występuje, jeśli skonfigurujesz śledzenie po wykonaniu tych poleceń, co OP prawdopodobnie zamierza zrobić, biorąc pod uwagę ich pytanie.
John Mellor,
2
@RockLee, tak, ogólnie sposobem na naprawę takich sytuacji jest utworzenie nowej gałęzi (newbranch2) z bezpiecznego punktu początkowego, a następnie wybranie wszystkich zatwierdzeń, które chcesz zachować (od badnewbranch do newbranch2). Wybranie Cherry da nowe skróty, więc będziesz mógł bezpiecznie zmienić bazę newbranch2 (i możesz teraz usunąć badnewbranch).
John Mellor,
2
@Walf, źle zrozumiałeś: git rebase został zaprojektowany tak, aby był odporny na przekręcanie historii. Niestety skutki uboczne tej odporności wpływają na wszystkich, nawet jeśli ani oni, ani ich poprzedni nigdy nie przepisują historii.
John Mellor
150

Znacznie prostsze rozwiązanie za pomocą git stash

Oto o wiele prostsze rozwiązanie dla zatwierdzeń do niewłaściwej gałęzi. Począwszy od gałęzi, masterktóra ma trzy błędne zatwierdzenia:

git reset HEAD~3
git stash
git checkout newbranch
git stash pop

Kiedy tego użyć?

  • Jeśli Twoim głównym celem jest wycofanie master
  • Chcesz zachować zmiany plików
  • Nie przejmujesz się wiadomościami w błędnych zatwierdzeniach
  • Jeszcze nie naciskałeś
  • Chcesz, aby było to łatwe do zapamiętania
  • Nie chcesz komplikacji, takich jak tymczasowe / nowe gałęzie, wyszukiwanie i kopiowanie skrótów zatwierdzeń oraz inne problemy

Co to robi, według numeru linii

  1. Cofa ostatnie trzy zatwierdzenia (i ich wiadomości) do master , ale pozostawia wszystkie działające pliki nietknięte
  2. Ukrywa wszystkie działające zmiany plików, czyniąc master drzewo robocze jest dokładnie równe stanowi HEAD ~ 3
  3. Przełącza do istniejącego oddziału newbranch
  4. Stosuje ukryte zmiany w katalogu roboczym i usuwa skrytkę

Możesz teraz używać git addi git commitjak zwykle. Wszystkie nowe zmiany zostaną dodane donewbranch .

Czego to nie robi

  • Nie pozostawia przypadkowych tymczasowych gałęzi zagracających twoje drzewo
  • Nie chroni błędnych komunikatów zatwierdzeń, dlatego musisz dodać nowy komunikat zatwierdzenia do tego nowego zatwierdzenia
  • Aktualizacja! Użyj strzałki w górę, aby przewijać bufor poleceń, aby ponownie zastosować wcześniejsze zatwierdzenie z komunikatem zatwierdzenia (dzięki @ARK)

Cele

OP stwierdził, że celem było „przywrócenie mistrza przed dokonaniem tych zobowiązań” bez utraty zmian, a to rozwiązanie to robi.

Robię to przynajmniej raz w tygodniu, kiedy przypadkowo dokonuję nowych zobowiązań masterzamiast develop. Zwykle mam tylko jedno zatwierdzenie wycofania, w którym to przypadku korzystamgit reset HEAD^ w linii 1 jest prostszym sposobem na wycofanie tylko jednego zatwierdzenia.

Nie rób tego, jeśli wprowadziłeś zmiany mistrza w górę

Ktoś inny mógł wyciągnąć te zmiany. Jeśli przepisujesz tylko swojego lokalnego mistrza, nie ma to wpływu, gdy zostanie on wypchnięty, ale przekazanie przepisanej historii współpracownikom może powodować problemy.

Zatrzasnąć
źródło
4
Dziękuję, bardzo się cieszę, że przeczytałem tak dużo przeszłości, aby się tutaj dostać, ponieważ jest to również dość powszechny przypadek użycia dla mnie. Czy jesteśmy tacy nietypowi?
Jim Mack
6
Wydaje mi się, że jesteśmy całkowicie typowi, a „oops, którego pomyłką przeznaczyłem przez pomyłkę” to najczęstszy przypadek użycia w przypadku potrzeby cofnięcia garści lub mniej zatwierdzeń. Na szczęście to rozwiązanie jest tak proste, że zapamiętałem je teraz.
Slam
9
To powinna być zaakceptowana odpowiedź. Jest prosty, łatwy do zrozumienia i łatwy do zapamiętania
Sina Madani
1
Nie wydaje mi się, żeby ukrywanie było konieczne. Po prostu zrobiłem to bez i działałem dobrze.
Campos,
1
Możesz także łatwo odzyskać swoje komunikaty zatwierdzenia, jeśli tak się dzieje, masz je w historii CLI (wiersza poleceń). Zdarzyło mi się mieć zarówno polecenia, jak git addi git commitpolecenia, więc wystarczyło mi trafić w strzałkę i wejść kilka razy i bum! Wszystko wróciło, ale teraz na właściwej gałęzi.
Luke Gedeon,
30

Nie „przenosi” ich w sensie technicznym, ale ma ten sam efekt:

A--B--C  (branch-foo)
 \    ^-- I wanted them here!
  \
   D--E--F--G  (branch-bar)
      ^--^--^-- Opps wrong branch!

While on branch-bar:
$ git reset --hard D # remember the SHAs for E, F, G (or E and G for a range)

A--B--C  (branch-foo)
 \
  \
   D-(E--F--G) detached
   ^-- (branch-bar)

Switch to branch-foo
$ git cherry-pick E..G

A--B--C--E'--F'--G' (branch-foo)
 \   E--F--G detached (This can be ignored)
  \ /
   D--H--I (branch-bar)

Now you won't need to worry about the detached branch because it is basically
like they are in the trash can waiting for the day it gets garbage collected.
Eventually some time in the far future it will look like:

A--B--C--E'--F'--G'--L--M--N--... (branch-foo)
 \
  \
   D--H--I--J--K--.... (branch-bar)
Sukima
źródło
1
Nie możesz użyć rebasetego samego?
Bergi,
Tak, możesz alternatywnie użyć rebasena odłączonym oddziale w powyższym scenariuszu.
Sukima
24

Aby to zrobić bez przepisywania historii (tj. Jeśli już wypchnąłeś zatwierdzenia):

git checkout master
git revert <commitID(s)>
git checkout -b new-branch
git cherry-pick <commitID(s)>

Obie gałęzie można następnie pchać bez użycia siły!

teh_senaus
źródło
Ale wtedy musisz poradzić sobie ze scenariuszem wycofania, który w zależności od okoliczności może być znacznie trudniejszy. Jeśli cofniesz zatwierdzenie w gałęzi, Git nadal zobaczy te zatwierdzenia, które miały miejsce, więc aby je cofnąć, musisz cofnąć cofnięcie. Spala to sporo osób, zwłaszcza gdy cofają scalanie i próbują scalić gałąź z powrotem, ale okazuje się, że Git uważa, że ​​już scalił tę gałąź (co jest całkowicie prawdziwe).
Makoto,
1
Właśnie dlatego wybieram zatwierdzenia na końcu, do nowej gałęzi. W ten sposób git widzi je jako nowe zatwierdzenia, co rozwiązuje problem.
teh_senaus
Jest to bardziej niebezpieczne, niż się wydaje, ponieważ zmieniasz stan historii repozytorium, nie rozumiejąc implikacji tego stanu.
Makoto,
5
Nie podążam za twoim argumentem - chodzi o to, że nie zmieniasz historii, po prostu dodajesz nowe zatwierdzenia (które skutecznie cofają ponawianie zmian). Te nowe zmiany mogą być wypychane i scalane jak zwykle.
teh_senaus
13

Miałem właśnie taką sytuację:

Branch one: A B C D E F     J   L M  
                       \ (Merge)
Branch two:             G I   K     N

Wykonałem:

git branch newbranch 
git reset --hard HEAD~8 
git checkout newbranch

Spodziewałem się, że zatwierdzę, będę Głową, ale zatwierdzę L, czy to teraz ...

Aby mieć pewność, że wylądujesz we właściwym miejscu w historii, łatwiej jest pracować z hashem zatwierdzenia

git branch newbranch 
git reset --hard #########
git checkout newbranch
Darkglow
źródło
7

Jak mogę z tego wyjść?

A - B - C - D - E 
                |
                master

do tego?

A - B - C - D - E 
    |           |
    master      newbranch

Z dwoma poleceniami

  • git branch -m master newbranch

dający

A - B - C - D - E 
                |
                newbranch

i

  • Git Branch Master B

dający

A - B - C - D - E
    |           |
    master      newbranch
Ivan
źródło
Tak, to działa i jest dość łatwe. GUI w Sourcetree jest trochę zdezorientowane zmianami wprowadzonymi w powłoce git, ale po pobraniu wszystko jest w porządku.
lars k.
Tak, są jak w pytaniu. Pierwsze kilka diagramów ma być równoważnych z tymi w pytaniu, po prostu przerysuj tak, jak chciałbym dla celów ilustracji w odpowiedzi. Zasadniczo zmień nazwę gałęzi master na newbranch i utwórz nową gałąź master tam, gdzie chcesz.
Ivan
4

Jeśli chcesz tylko przenieść wszystkie nieprzypisane zmiany do nowej gałęzi , musisz po prostu:

  1. tworzyć się nowy oddział z bieżącej:git branch new-branch-name

  2. pchnij swój nowy oddział :git push origin new-branch-name

  3. przywrócić swoje stare (aktualne) oddział do ostatniej pchania / stan stabilnygit reset --hard origin/old-branch-name

Niektóre osoby mają też inne upstreams, niż originpowinny, powinny stosować odpowiednieupstream

Shamsul Arefin Sajib
źródło
3

1) Utwórz nową gałąź, która przeniesie wszystkie twoje zmiany do nowej_gałęzi.

git checkout -b new_branch

2) Następnie wróć do starej gałęzi.

git checkout master

3) Czy git rebase

git rebase -i <short-hash-of-B-commit>

4) Następnie otwarty edytor zawiera 3 ostatnie informacje o zatwierdzeniu.

...
pick <C's hash> C
pick <D's hash> D
pick <E's hash> E
...

5) Zmień pickna dropwszystkie te 3 zmiany. Następnie zapisz i zamknij edytor.

...
drop <C's hash> C
drop <D's hash> D
drop <E's hash> E
...

6) Teraz ostatnie 3 zatwierdzenia są usuwane z bieżącej gałęzi ( master). Teraz wciśnij gałąź mocno, ze +znakiem przed nazwą gałęzi.

git push origin +master
rashok
źródło
2

Możesz to zrobić, to tylko 3 prosty krok, którego użyłem.

1) Utwórz nowy oddział, w którym chcesz zatwierdzić ostatnią aktualizację.

git branch <branch name>

2) Znajdź identyfikator ostatniego zatwierdzenia dla zatwierdzenia w nowym oddziale.

git log

3) Skopiuj notatkę identyfikatora zatwierdzenia, że ​​lista najnowszych zatwierdzeń ma miejsce na górze. więc możesz znaleźć swoje zatwierdzenie. znajdziesz to również za pośrednictwem wiadomości.

git cherry-pick d34bcef232f6c...

możesz także podać numer identyfikacyjny zatwierdzenia.

git cherry-pick d34bcef...86d2aec

Teraz twoja praca skończona. Jeśli wybierzesz prawidłowy identyfikator i poprawną gałąź, odniesiesz sukces. Zanim to zrobisz, bądź ostrożny. w przeciwnym razie może wystąpić inny problem.

Teraz możesz wcisnąć kod

git push

Pankaj Kumar
źródło
0

Inny sposób to zrobić:

[1] Zmień nazwę mastergałęzi na newbranch(zakładając, że jesteś w mastergałęzi):

git branch -m newbranch

[2] Utwórz mastergałąź z zatwierdzenia, które chcesz:

git checkout -b master <seven_char_commit_id>

np. git checkout -b master a34bc22

Saikat
źródło