Musisz zresetować gałąź git do wersji początkowej


439

Przez przypadek pracowałem nad oddziałem, przez który nie powinienem był być przez jakiś czas, więc rozgałęziłem się, nadając mu odpowiednią nazwę. Teraz chcę zastąpić gałąź, w której nie powinienem był być w wersji z pochodzenia (github). Czy jest na to łatwy sposób? Próbowałem usunąć gałąź, a następnie zresetować gałąź śledzenia, ale to po prostu daje mi wersję, nad którą pracowałem ponownie.



Z Git 2,23 (sierpień 2019) git switch -C mybranch origin/mybranch. Zobacz moją zredagowaną odpowiedź poniżej
VonC

Odpowiedzi:


814

Jeśli jeszcze nie wysłałeś do źródła, możesz zresetować gałąź do gałęzi upstream za pomocą:

git checkout mybranch
git reset --hard origin/mybranch

(Upewnij się, że odwołujesz się do ostatniego zatwierdzenia w oddzielnym oddziale, tak jak wspomniałeś w swoim pytaniu)

Zauważ, że zaraz po resecie mybranch@{1}odnosi się do starego zatwierdzenia, przed resetowaniem.

Ale jeśli już wypchnąłeś, zobacz „ Utwórz gałąź git i przywróć oryginał do stanu wyjściowego ” dla innych opcji.


Z Git 2,23 (sierpień 2019) , to byłoby jedno polecenie: git switch.
Mianowicie:git switch -C mybranch origin/mybranch

Przykład

C:\Users\vonc\git\git>git switch -C master origin/master
Reset branch 'master'
Branch 'master' set up to track remote branch 'master' from 'origin'.
Your branch is up to date with 'origin/master'.

To przywraca indeks i drzewo robocze, tak jak git reset --hardby to zrobiło.


Jak komentował Brad Herman , A reset --hardby usunąć nowy plik lub zresetować zmodyfikowanego pliku do HEAD .

W rzeczywistości, aby mieć pewność, że zaczniesz od „czystego konta”, git clean -f -dpo resecie zapewnione będzie działające drzewo dokładnie identyczne z gałęzią, którą właśnie zresetowałeś.


Ten post na blogu sugeruje te aliasy ( mastertylko dla oddziału, ale możesz je dostosować / rozszerzyć):

[alias]
   resetorigin = !git fetch origin && git reset --hard origin/master && git clean -f -d
   resetupstream = !git fetch upstream && git reset --hard upstream/master && git clean -f -d

Następnie możesz wpisać:

git resetupstream

lub

git resetorigin

26
spowoduje to USUWANIE NIEZNANYCH / ZNACZONYCH zmian (z --hard)
Peter Ehrlich

5
Użyłem tego git reset --hard origin/mybranchpolecenia kilka razy, gdy nie dbałem o żadne lokalne zmiany i chciałem tylko czystej kopii, która pasowałaby do źródła. Jednak dzisiaj to nie zadziałało - wciąż miałem garść nowych, nie zainscenizowanych plików, a git obiecał mi, że jest w HEAD. Uwaga o git clean -f -dnaprawiła to, usuwając wszystkie nowe pliki, których nie chciałam.
Matthew Clark

@MatthewClark To jest oczekiwane: patrz komentarz na stackoverflow.com/q/4327708/6309
VonC

1
Świetny! Również wiele razy git reset --hard HEAD
wracałem

Czy jest to również możliwe w przypadku sourctree?
Lonzak,

20

Zakładając, że tak się stało:

# on branch master
vi buggy.py                 # you edit file
git add buggy.py            # stage file
git commit -m "Fix the bug" # commit
vi tests.py                 # edit another file but do not commit yet

Wtedy zdajesz sobie sprawę, że wprowadzasz zmiany w niewłaściwej gałęzi.

git checkout -b mybranch    # you create the correct branch and switch to it

Ale masternadal wskazuje na twoje zatwierdzenie. Chcesz, aby wskazywał wcześniej.

Rozwiązanie

Najprostszym sposobem jest:

git branch --force master origin/master

Innym sposobem jest:

git checkout master
git reset --soft origin/master
git checkout mybranch

Pamiętaj, że użycie reset --hardspowoduje utratę niezatwierdzonych zmian ( tests.pyw moim przykładzie).


Wydaje się to bezpieczniejsze niż w mojej odpowiedzi;) +1
VonC

8

Mam prywatne repozytorium na serwerze i regularnie dokonuję na nim zmiany bazy / wymuszam, co wymaga częstego resetowania lokalnego oddziału na innym komputerze. Dlatego stworzyłem następujący alias „catchup”, który pozwala to zrobić dla bieżącej gałęzi. W przeciwieństwie do drugiej odpowiedzi w tym aliasie nie ma na stałe wpisanej nazwy oddziału.

Trzymaj się mocno.

[alias]
  catchup = "!f(){ echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \"; read -r ans; if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)); else echo \"catchup aborted\"; fi }; f"

Prawidłowo sformatowane (nie będzie działać z nowymi wierszami w .gitconfig) wygląda następująco:

"
!f(){
  echo -n \"reset \\033[0;33m$(git symbolic-ref -q --short HEAD)\\033[0m to \\033[0;33m$(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD))\\033[0m? (Y/n) \";
  read -r ans;
  if [ \"$ans\" = \"y\" -o \"$ans\" = \"Y\" -o -z \"$ans\" ]; then
    git reset --hard $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD));
  else
    echo \"catchup aborted\";
  fi
}; f
"
  • \\033[0;33mI \\033[0mjest dla podkreślenia aktualnej gałęzi i upstream kolorem.
  • $(git symbolic-ref -q --short HEAD) jest bieżącą nazwą oddziału
  • $(git for-each-ref --format='%(upstream:short)' $(git symbolic-ref -q HEAD)) jest powyżej bieżącego oddziału.

Ponieważ reset jest potencjalnie niebezpiecznym połączeniem (szczególnie z opcją --hard, utracisz wszelkie nieprzyjęte zmiany), najpierw mówi ci, co zamierza zrobić. Na przykład, jeśli korzystasz z gałęzi dev-container ze zdalnym qcpp / dev-container i wejdziesz git catchup, pojawi się monit:

zresetować dev-container do qcpp / dev-container? (T / n)

Jeśli następnie wpiszesz y lub po prostu naciśniesz return, nastąpi reset. Jeśli wpiszesz cokolwiek innego, reset nie zostanie przeprowadzony.

Jeśli chcesz być super bezpieczny i programowo zapobiegać utracie niestabilnych / niezaangażowanych zmian, możesz dodatkowo ulepszyć powyższy alias, sprawdzając indeks różnic .

Obowiązkowe słowo ostrzeżenia: jeśli pracujesz na publicznym repozytorium, na którym pracują inni ludzie i potrzebujesz tego aliasu, robisz to źle ™ .


1

Próbowałem tego i nie zresetowałem mojej aktualnej gałęzi do mojego zdalnego githuba. Poszukałem go i znalazłem https://itsyndicate.org/blog/how-to-use-git-force-pull-properly/

co sugerowało

git fetch origin master
git reset --hard origin/master

Chciałem zresetować moją gałąź v8, więc zrobiłem to

git fetch origin v8
git reset --hard origin/v8

i zadziałało


Dobrze, że wspomniałeś o pobieraniu. Zrobiłem to raz bez i wszystko zresetowałem 2 lata temu :)
Adam
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.