Przenieś istniejącą, niezaangażowaną pracę do nowego oddziału w Git


3125

Zacząłem prace nad nową funkcją i po krótkim kodowaniu zdecydowałem, że ta funkcja powinna mieć swoją gałąź.

Jak przenieść istniejące niezatwierdzone zmiany do nowej gałęzi i zresetować obecną?

Chcę zresetować moją obecną gałąź, zachowując dotychczasową pracę nad nową funkcją.


Ten sam interesujący temat stackoverflow.com/q/556923/269514 ?
Gilberto

Odpowiedzi:


3640

Użyj następujących opcji:

git checkout -b <new-branch>

Spowoduje to pozostawienie obecnego oddziału w obecnej postaci, utworzenie i pobranie nowego oddziału oraz zachowanie wszystkich zmian. Następnie możesz wprowadzać zmiany w plikach, aby zatwierdzić:

git add <files>

i zobowiązaj się do nowego oddziału za pomocą:

git commit -m "<Brief description of this commit>"

Zmiany w katalogu roboczym i zmiany wprowadzone w indeksie nie należą jeszcze do żadnej gałęzi . To zmienia gałąź, w której kończyłyby się te modyfikacje.

Nie resetujesz oryginalnej gałęzi, pozostanie ona taka, jaka jest. Ostatnie zatwierdzenie <old-branch>pozostanie takie samo. Dlatego ty, checkout -ba następnie dokonaj.


Aktualizacja 2020 / Git 2.23

Git 2.23 dodaje nową switchpodkomendę, próbując usunąć pewne zamieszanie wynikające z przeciążenia użycia checkout(przełączanie gałęzi, przywracanie plików, odłączanie HEAD itp.)

Począwszy od tej wersji Git, zamień powyższe polecenie na:

git switch -c <new-branch>

Zachowanie jest identyczne i pozostaje niezmienione.


15
Dla pewności muszę zatwierdzić niedokończoną funkcję PRZED zresetowaniem mojego oryginalnego oddziału? Czy te niezatwierdzone pliki zostaną zachowane bez względu na popełnienie?
Dane O'Connor,

192
FYI: zmiany w katalogu roboczym i zmiany w indeksie nie należą do gałęzi. git checkout -b <new branch>zmiany, w których zmiany te miałyby się zakończyć.
Jakub Narębski

152
Jeśli masz już oddział i chcesz przenieść zmiany do istniejącego oddziału, sprawdź stackoverflow.com/questions/556923/...
Chirantan

14
Jeśli chcesz zepchnąć swój nowy oddział do zdalnego repozytorium: stackoverflow.com/questions/2765421/...
Dewayne,

10
@JDSmith: niezamierzone zmiany NIE należą do żadnego oddziału. Zamieszkują tylko w katalogu roboczym git checkout ./ git reset --hardbędzie nieodwracalny usunąć je
Knittla

329

Alternatywnie:

  1. Zapisz bieżące zmiany w skrytce tymczasowej:

    $ git stash

  2. Utwórz nową gałąź w oparciu o tę skrytkę i przejdź do nowej gałęzi:

    $ git stash branch <new-branch> stash@{0}

Wskazówka: użyj klawisza Tab, aby zmniejszyć wpisywanie nazwy skrytki.


51
Jeśli druga gałąź już istnieje, możesz po prostu przejść do niej za pomocą kasy git stash apply.
Archonic

6
Nie rozumiem podpowiedzi „Wskazówka: użyj klawisza Tab, aby zmniejszyć wpisywanie nazwy skrytki”. Czy nazwa „skrytka @ {0}” nie jest nazwą? Nie mogę uruchomić go pomyślnie.
Herbert,

7
Dlaczego jest to lepsze niż zaakceptowana odpowiedź stackoverflow.com/a/1394804/754997 ?
Chris Page

10
Nie rozumiem, dlaczego jest to lepsze niż zaakceptowana odpowiedźgit checkout -b <new branch name>
Noitidart,

6
Nie musisz tego robić git add -Aprzed składowaniem.
vichle

48

Jeśli podczas kodowania dokonywałeś zatwierdzeń w głównej gałęzi, ale teraz chcesz przenieść te zatwierdzenia do innej gałęzi, jest to szybki sposób:

  1. Skopiuj swoją bieżącą historię do nowego oddziału, przynosząc również wszelkie niezatwierdzone zmiany:

    git checkout -b <new-feature-branch>
    
  2. Teraz zmuś oryginalną „niechlujną” gałąź do wycofania: (bez przełączania się na nią)

    git branch -f <previous-branch> <earlier-commit-id>
    

    Na przykład:

    git branch -f master origin/master
    

    lub jeśli dokonałeś 4 zatwierdzeń:

    git branch -f master HEAD~4
    

Ostrzeżenie: git branch -f master origin/master będzie zresetować informacje śledzenia dla tego oddziału. Jeśli więc skonfigurowałeś swójmasteroddział tak, aby działał w innym miejscuorigin/master, konfiguracja zostanie utracona.

Ostrzeżenie: Istnieje również niebezpieczeństwo, jeśli dokonasz zmiany bazy po rozgałęzieniu, co opisano tutaj . Jedynym sposobem, aby tego uniknąć, jest utworzenie nowej historii przy użyciu cherry-pick. Ten link opisuje najbezpieczniejszą głupią metodę . Jeśli masz niezatwierdzone zmiany, możesz chciećgit stashna początku igit stash popna końcu.


6
Odpowiada to na pytanie, które nieco różni się od pytania zadanego przez operację. Postanowiłem umieścić tutaj tę odpowiedź, ponieważ to tutaj przywiodł mnie Google, gdy szukałem odpowiedzi. Rzeczywiste pytanie dotyczące tej sytuacji znajduje się tutaj .
joeytwiddle

26

Typowy scenariusz jest następujący: zapomniałem utworzyć nową gałąź dla nowej funkcji i wykonałem całą pracę w starej gałęzi funkcji. Powierzyłem całą „starą” pracę gałęzi master i chcę, aby moja nowa gałąź wyrosła z „master”. Nie dokonałem ani jednego zatwierdzenia mojej nowej pracy. Oto struktura gałęzi: „master” -> „Old_feature”

git stash 
git checkout master
git checkout -b "New_branch"
git stash apply

18

Jeśli go zatwierdzisz, możesz również wybrać pojedynczy identyfikator zatwierdzenia. Robię to często, kiedy zaczynam pracę w trybie master, a następnie chcę utworzyć lokalny oddział, zanim przejdę do mojego źródła /.

git cherry-pick <commitID>

Jest wiele rzeczy, które możesz zrobić z cherry-pick, jak opisano tutaj , ale może to być dla ciebie przypadek użycia.


2
Ładniejsze rozwiązanie do przeniesienia częściowych zmian do nowej gałęzi ... ponieważ możesz teraz zatwierdzić to, co chcesz, ukryć wszystkie inne zmiany, sprawdzić gałąź, z której chcesz rozgałęzić się, wybrać te, które zatwierdzasz do nowej gałęzi, cofnij się w oryginalnym oddziale, mocno zresetuj zatwierdzenie, a następnie wykonaj ukryty pop, dodaj, zatwierdz i śpiewaj alleluja.
Meredith,

1
@Meredith, haha, coś takiego. To świetnie, chyba że planujesz zmiany na przyszłość ... i kto to zrobi;)
hasło

1

Może to być pomocne dla wszystkich korzystających z narzędzi do GIT

Komenda

Zmień gałąź - przeniesie twoje zmiany do nowej gałęzi. Następnie możesz zatwierdzić zmiany.

 $ git checkout -b <new-branch>

TortoiseGIT

Kliknij repozytorium prawym przyciskiem myszy, a następnie użyj TortoiseGit-> Switch / Checkout

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

SourceTree

Użyj przycisku „Do kasy”, aby zmienić gałąź. Zobaczysz przycisk „kasy” u góry po kliknięciu gałęzi. Zmiany z bieżącego oddziału zostaną zastosowane automatycznie. Następnie możesz je popełnić.

wprowadź opis zdjęcia tutaj


0

Użyłem @Robin odpowiedzi i listy wszystkiego, co zrobiłem,

git status                               <-- review/list uncommitted changes
git stash                                <-- stash uncommitted changes
git stash branch <new-branch> stash@{1}  <-- create a branch from stash
git add .                                <-- add local changes
git status                               <-- review the status; ready to commit
git commit -m "local changes ..."        <-- commit the changes
git branch --list                        <-- see list of branches incl the one created above
git status                               <-- nothing to commit, working tree (new-branch) is clean
git checkout <old-branch>                <-- switch back

! Jeśli repozytorium ma więcej niż jedną skrytkę, sprawdź, którą zastosować do nowej gałęzi:

git stash list  
  stash@{0}: WIP on ...  
  stash@{1}: WIP on ...

i sprawdź poszczególne skrytki,

git stash show stash@{1}

Lub sprawdź wszystkie skrytki jednocześnie:

git stash list -p

0

Jest teraz naprawdę łatwy sposób, aby to zrobić za pomocą GitHub Desktop, ponieważ nie sądzę, aby była to wcześniej funkcja.

Wszystko, co musisz zrobić, to przejść do nowej gałęzi w GitHub Desktop, a poprosi Cię o pozostawienie zmian w bieżącej gałęzi (która zostanie ukryta) lub przeniesienie zmian ze sobą do nowej gałęzi. Wystarczy wybrać drugą opcję, aby wprowadzić zmiany do nowego oddziału. Następnie możesz zatwierdzić jak zwykle.

GitHub Desktop

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.