2012-02-09 13 views
445

Mam dwa oddziały:Wymień lokalnym oddziałem ze zdalnym oddziału całkowicie

  1. lokalny oddział (ten, który pracuję)
  2. zdalny oddział (publiczna, tylko dobrze przetestowane popełnia tam)

Ostatnio poważnie zawiedli mojego lokalnego oddziału (Chyba każdy git-newbie był na moim miejscu w pewnym momencie)

Jak bym wymienić lokalnym oddziałem w całości z jednego pilota , więc mogę kontynuować pracę od miejsca, w którym znajduje się teraz oddział zdalny?

(I już przeszukiwane SO i sprawdzanie do odległego oddziału lokalnie nie ma żadnego wpływu)

Odpowiedz

753
  1. Upewnij się, że wyewidencjonowałeś oddział, który wymieniasz (z Zoltán's comment).
  2. Zakładając, że mistrz jest lokalny oddział jesteś zastąpienia, i że „pochodzenie/master” jest odległy oddział chcesz zresetować do:

    git reset --hard origin/master 
    

ten aktualizuje się z lokalnym oddziałem Głowa do być tą samą wersją co origin/master, a --hard zsynchronizuje również tę zmianę z indeksem i obszarem roboczym.

+3

Dzięki za twoją sugestię, jestem tak "przestraszony" używając - hard i --force już, więc właśnie wybrałem rozwiązanie, które ich nie wykorzystuje. – YemSalat

+10

@KonstantinLevin: ah tak, nazewnictwo tych opcji jest dość irytujące. 'git reset' domyślnie będzie ponownie wskazywał bieżącą gałąź i synchronizował indeks. '--soft' pominie aktualizację indeksu,' --hard' zsynchronizuje również obszar roboczy. Moim własnym doświadczeniem jest używanie '--hard' przez większość czasu, z wyjątkiem kiedy chcę cofnąć ostatnie zatwierdzenie (które jest po prostu' git reset HEAD^') – araqnid

+0

@KonstantinLevin, hard lub force jest przerażające, ale nie" branch -d " (kasować)? Podoba mi się to rozwiązanie, proste i proste do punktu. – km1

-5

Brzydkie ale prostszy sposób: usunąć folder lokalny i ponownie sklonować zdalnego repozytorium.

+8

Albo po prostu usunąć gałąź i sprawdź to ponownie. –

+0

Tak, chyba to zrobię, jeśli nie znajdę, jak to zrobić w mniej "brzydki" sposób. – YemSalat

+0

Brzydkie czasami warto wiedzieć. Chciałabym, żeby ludzie nie głosowali sprawy tylko dlatego, że nie są one konwencjonalne: musi istnieć bardziej racjonalny powód do zaniedbania ... i to powinno być dane. Git jest rzeczą, która osiąga wyniki. To nie jest jakiś święty tekst. –

2

Możesz zrobić jako @Hugo z @Laurent powiedział, lub możesz użyć git rebase, aby usunąć zatwierdzenia, które chcesz się pozbyć, jeśli wiesz, które. Zwykle używam git rebase -i head~N (gdzie N jest liczbą, pozwalającą ci manipulować ostatnimi N commitami) dla tego rodzaju operacji.

+0

Właściwie to polecenie "git rebase" zawiodło całą sprawę, potem niektóre wymusiły scalanie i twarde resetowanie. W każdym razie, to, czego szukałem, to tylko prosty sposób na przeciągnięcie całego repozytu ze zdalnego serwera bez scalania. – YemSalat

26
git branch -D <branch-name> 
git fetch <remote> <branch-name> 
git checkout -b <branch-name> --track <remote>/<branch-name> 
+0

Co robi część --track? – eonist

+2

@GitSync, Oto co 'git help branch' mówi o' --track'. 'Podczas tworzenia nowego oddziału, ustaw oddział. .remote i oddział. . Wpisy konfiguracyjne .merge, aby oznaczyć gałąź początkową jako "upstream" z nowego oddziału. Ta konfiguracja powie gitowi, aby pokazać relację między dwoma gałęziami w statusie git i git gałąź -v. Co więcej, kieruje git pull bez argumentów, aby wyciągnąć z góry, gdy nowy oddział jest wyewidencjonowany. " Naprawiłem to polecenie w odpowiedzi. Dzięki za podniesienie punktu. – Sailesh

+0

W kategoriach laika: dodaje zdalny adres URL do nowego oddziału. Są więc zsynchronizowani na zawsze. Że tak powiem. – eonist

149

To tak proste, jak trzy kroki:

  1. usuwać swoich lokalnego oddziału: git branch -d local_branch
  2. pobierze najnowszą zdalnego oddziału: git fetch origin remote_branch
  3. odbudować lokalnym oddziałem w oparciu o zdalny jednym: git checkout -b local_branch origin/remote_branch
+6

Właściwie to, co powiedział @araqnid, jest poprawne i bardziej zwięzłe. Przetestowałem to i możesz też spróbować. – adamsmith

+2

Odpowiedź @ araqnid poniżej powinna otrzymać znak kontrolny –

+0

Wow, git checkout -b local_branch origin/remote_branch is great! Zawsze robiłem to w dwóch osobnych poleceniach. dzięki! – kendepelchin

2

s s wybrana odpowiedź jest absolutnie poprawna, jednak nie pozostawiła mnie z ostatnim zatwierdzeniem/popycha ...

Więc dla mnie:

git reset --hard dev/jobmanager-tools 
git pull (did not work as git was not sure what branch i wanted) 

Ponieważ wiem, że chcesz, aby tymczasowo ustawić mój upstream oddział na kilka tygodni do konkretnego oddziału (taki sam jak ten, przerzuciłem się/wyrejestrowany wcześniej i tak ciężko kasowane)

Więc Po resecie

git branch --set-upstream-to=origin/dev/jobmanager-tools 
git pull 
git status (says--> on branch dev/jobmanager-tools 
+0

Hmm, zadziałało dobrze. Nie musiałem ciągnąć. –

0

Jeśli chcesz zaktualizować gałąź, która nie jest obecnie sprawdzany o ut można zrobić

git fetch -f origin rbranch:lbranch 
2

najbezpieczniejszym i najbardziej kompletny sposób, aby zastąpić aktualny lokalny oddział z pilota:

git stash 
git merge --abort 
git rebase --abort 
git branch -M yourBranch replaced_yourBranch 
git fetch origin yourBranch:yourBranch 
git checkout yourBranch 

Linia stash zapisuje zmiany, które nie zostały popełnione. Linia branch przesuwa gałąź do innej nazwy, zwalniając oryginalną nazwę. Linia fetch pobiera najnowszą kopię pilota. Linia checkout odtwarza oryginalną gałąź jako gałąź śledzącą.

lub jako funkcja bash:

replaceWithRemote() { 
    yourBranch=${1:-`git rev-parse --abbrev-ref HEAD`} 
    git stash 
    git merge --abort 
    git rebase --abort 
    git branch -M ${yourBranch} replaced_${yourBranch}_`git rev-parse --short HEAD` 
    git fetch origin ${yourBranch}:${yourBranch} 
    git checkout ${yourBranch} 
} 

który zmienia nazwę bieżącego oddziału do czegoś podobnego replaced_master_98d258f.

+0

Może chcieć dołączyć 'git stash pop' w tym przepływie pracy. Jeśli chcesz ponownie zastosować swoje ukryte pliki. – eonist

3

Zamień wszystko na gałąź zdalną; ale, tylko z tego samego popełnić lokalny oddział jest na:

git reset --hard origin/some-branch 

LUB, uzyskać najnowszą ze zdalnego branży i wymienić wszystko:

git fetch origin some-branch 
git reset --hard FETCH_HEAD 

Tak na marginesie, w razie potrzeby możesz usunąć niezatwierdzone pliki & katalogów, których jeszcze nie zatwierdziłeś:

git clean -fd 
0

Jak podano w wybranych wyjaśnieniach, git reset jest dobry. Ale obecnie często korzystamy z submodułów: repozytoriów wewnątrz repozytoriów. Na przykład, jeśli używasz ZF3 i jQuery w swoim projekcie, prawdopodobnie chcesz je sklonować z oryginalnych repozytoriów. W takim przypadku git reset to za mało. Musimy zaktualizować submodules do tego dokładnie wersji, które są zdefiniowane w naszym repozytorium:

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

git submodule foreach git submodule update 

git status 

jest taka sama jak przyjdziesz (CD) rekurencyjnie do katalogu roboczego każdego podmodułem i będzie działać:

git submodule update 

I to jest bardzo różni się od

git checkout master 
git pull 

ponieważ sub-moduły wskazać nie rozgałęzia ale do zatwierdzenia.

W takim przypadku, gdy ręcznie KASY jakiś oddział dla 1 lub więcej submodułów można uruchomić

git submodule foreach git pull 
+0

Proszę podać wyjaśnienie, szczególnie przy odpowiadaniu na te stare pytania. Twoja odpowiedź nie jest pomocna tak jak jest. –

+0

Przyjęta odpowiedź już proponuje 'git reset --hard'. To dodaje niewielką wartość. – florisla

Powiązane problemy