Jak „wyciągnąć” do gałęzi, która nie jest obecna?

126

Kiedy biegniesz git pullpo mastergałęzi, zwykle ciągnie origin/master. Jestem w innej gałęzi o nazwie newbranch, ale muszę uruchomić polecenie, które wykonuje polecenie git pullod origin/masterdo, masterale nie mogę uruchomić git checkoutzmiany wybranej gałęzi, dopóki nie zakończy się ściąganie. Czy jest na to sposób?

Aby dać trochę informacji, repozytorium przechowuje witrynę internetową. Dokonałem pewnych zmian newbranchi wdrożyłem je, przełączając witrynę na newbranch. Teraz te zmiany zostały włączone do mastergałęzi, próbuję również przełączyć witrynę z powrotem do mastergałęzi. W tym momencie, newbranchi origin/mastersą identyczne, ale masterpozostaje w tyle origin/masteri musi zostać zaktualizowana. Problem w tym, że jeśli robię to w tradycyjny sposób:

$ git checkout master
   # Uh oh, production website has now reverted back to old version in master
$ git pull
   # Website is now up to date again

Muszę osiągnąć to samo, co powyżej ( git checkout master && git pull), ale bez zmiany katalogu roboczego na wcześniejszą wersję podczas procesu.

Malvineous
źródło
@phi: Nie sądzę, żeby to zadziałało, ponieważ jestem w newbranchśrodku i nie ma tam nic do ukrycia!
Malvineous
Klonowałbym do nowego katalogu, łączyłbym newbranch z master, łączył mastera z powrotem w newbranch, a następnie git pull z miejsca, w którym się znajdujesz. Mistrz i nowa gałąź będą takie same.
AET
@aet Mógłby to zrobić teraz w swoim bieżącym katalogu, robiąc to git fetch; git merge origin/masterod wewnątrz newbranch. Sklonowanie całej drugiej kopii repozytorium nie przynosi żadnych korzyści.
meagar
3
blisko spokrewnione: stackoverflow.com/questions/3216360/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

5

Masz drzewo robocze, którego nie chcesz dotykać, więc użyj innego. Clone jest tani, jest do tego stworzony.

git fetch origin master       # nice linear tree
git clone . ../wip -b master  # wip's `origin/master` is my `master`
cd ../wip                     # .
git pull origin origin/master # merge origin's origin/master
git push origin master        # job's done, turn it in.
cd ../main
rm -rf ../wip                 # wip was pushed here, wip's done

git checkout master           # payload

Problem ze wszystkimi innymi odpowiedziami tutaj polega na tym, że w rzeczywistości nie pociągają one za sobą. Jeśli potrzebujesz skonfigurowanego łączenia lub ponownego bazowania, potrzebujesz innego drzewa roboczego i powyższej procedury. W przeciwnym razie po prostu git fetch; git checkout -B master origin/masterzrobi.

jthill
źródło
2
Po uruchomieniu git checkout masterwyewidencjonujesz starą mastergałąź, ponieważ nie zrobiłeś git pullw mainfolderze synchronizacji z origin / master. To jest to, czego staram się uniknąć.
Malvineous
Wyewidencjonowanie dokonane przez klona pochodzi ze starego mastera, ale to wyewidencjonowanie jest do katalogu, którego serwer WWW nie ogląda. Master checkout na końcu to w pełni scalony master, który został wypchnięty z wip.
jthill
W wierszu 6 wypychasz scalone (zaktualizowane) z masterpowrotem do origin, ale nie sądzę, aby Twoje ostateczne pobranie było takie zaktualizowane master. Nie ma git pullpotrzeby aktualizowania mastergałęzi w mainkatalogu, więc jeśli czegoś mi brakuje, twoje polecenia nie różnią się od zwykłego uruchamiania git checkout masteri pobierania starego masterdrzewa. Jeśli przyjrzysz się uważnie, nie uruchamiasz żadnych poleceń w mainkatalogu, które komunikują się z nadrzędnym strumieniem (z wyjątkiem linii 1, która jest uruchamiana przed wprowadzeniem jakichkolwiek zmian w repozytorium).
Malvineous
cóż, możesz wypróbować to na repozytorium testowym lub sprawdzić dokumenty push.
jthill
1
@jwg w porównaniu z czym, proszę? Upewnij się, że spełniasz wszystkie określone potrzeby OP.
jthill
163

Prosta: Aktualizacja z odległego oddziału do chwili obecnej nie sprawdził-out oddziału kapitana :

git fetch origin master:master

gdzie origin jest twoim pilotem i aktualnie jesteś sprawdzany w jakiejś gałęzi, np . dev .

Jeśli chcesz zaktualizować swój obecny oddział oprócz określonego oddziału za jednym razem:

git pull origin master:master
Martin Peter
źródło
4
Hm, wydaje się, że to nie zawsze działa; Właśnie zostałem poproszony o połączenie z moją gałęzią WIP.
underscore_d
@underscore_d to samo dla mnie.
Greg,
1
Pracował dla mnie ... jeśli podpowiada scalenie, to wyobrażam sobie, że w twoim oddziale są zmiany, które aktualizujesz, a które nie są związane z pochodzeniem
przejrzyj
2
Jak to ma działać? To nie działa dla mnie, po prostu próbuje scalić źródło / wzorzec w mojej aktualnie wyewidencjonowanej gałęzi.
mhogerheijde
3
To ciągnie mistrza do bieżącej gałęzi. To zdecydowanie NIE jest to, o co się prosi. Jeśli zmienisz pull na fetch, będzie to dokładnie to, o co jest proszone.
Jeff Wolski
90

Odpowiedź na to pytanie znajduje się tutaj: Scal, aktualizuj i ściągaj gałęzie Git bez korzystania z płatności

# Merge local branch foo into local branch master,
# without having to checkout master first.
# Here `.` means to use the local repository as the "remote":
git fetch . foo:master

# Merge remote branch origin/foo into local branch foo,
# without having to checkout foo first:
git fetch origin foo:foo
Tomasz
źródło
2
To jest najlepsze, ponieważ działa z niezatwierdzonymi zmianami lokalnymi.
Tomasz Gandor
2
Jeśli chcesz po prostu nadążyć za najnowszymi zmianami, to byś zrobił git fetch origin master:master. git fetchsamo w sobie zakładałoby, że zamierzasz zaktualizować bieżącą gałąź, a nie inną gałąź.
John Leidegren
2
To najprostsza i najbardziej bezpośrednia odpowiedź. To powinna być akceptowana odpowiedź IMO.
Keego,
@JohnLeidegren - z wyjątkiem tego, że nie zawsze działa zgodnie z przeznaczeniem. Zobacz komentarze do stackoverflow.com/a/42902058/274579 odpowiedzi.
ysap
22

Jak się okazuje, odpowiedź jest zwodniczo prosta:

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

To pozwala na aktualizację masteroddział bez przełączania do niego, aż po to został zaktualizowany.

Malvineous
źródło
11
To nie robi tego, o co prosiłeś.
jthill
Jak mówi powyższy komentarz, pytanie, które zadałeś, nie jest w rzeczywistości pytaniem, na które ostatecznie odpowiedziałeś. Powinieneś zaktualizować swoje pytanie, aby mniej konkretnie dotyczyło scalania do gałęzi bez sprawdzania go, a bardziej przejścia bezpośrednio do najnowszej wersji gałęzi dostępnej na pilocie bez uprzedniego sprawdzania starej wersji.
meagar
1
To absolutna odpowiedź, której tu szukałem :)
Sophistifunk
1
Nie tego chciał OP, ale pomógł mi, szczerze mówiąc.
Marcel Bro
1
@anoniim, nie to, czego chciał OP? Masz na myśli OP, który właśnie odpowiedział na to pytanie?
smac89
12

Martwisz się czymś, czego nie można naprawić, ponieważ operacje Git nie są atomowe. Zawsze będziesz mieć dziurę, w której twój katalog roboczy jest w połowie drogi między gałęziami, nawet jeśli zaktualizujesz master bez wcześniejszego przełączenia się na niego. Dlatego Git nie jest narzędziem do wdrażania .

Ponieważ w rzeczywistości nie zatwierdzasz kodu w swoim środowisku produkcyjnym (mam nadzieję), nie musisz w rzeczywistości sprawdzać gałęzi. Możesz po prostu zrobić a, git fetchaby zaktualizować swoje zdalne referencje, a następnie git checkout origin/masterprzenieść katalog roboczy bezpośrednio do zatwierdzenia aktualnie wskazywanego przez origin/master. To wprowadzi cię w stan odłączonej głowy, ale znowu, ponieważ nie wprowadzasz kodu, to nie ma znaczenia.

To jest najmniejsza dziura, którą dostaniesz, ale jak powiedziałem, dziura nadal istnieje; checkoutnie jest atomowy.

meagar
źródło
Rozumiem ograniczenia używania gita do wdrożenia, problem polega na tym, że w tym przypadku dziura będzie trwała minuty, a nie mniej niż jedną sekundę. Niezły pomysł na sprawdzenie, origin/masterale to może po prostu załatwić sprawę.
Malvineous
Co sprawia, że ​​dziura ma „minuty”? Pobieranie danych przez sieć? Po prostu zrób to, git fetchzanim zrobisz cokolwiek innego i wyeliminuj rzeczywisty transfer danych.
meagar
Trwa kilka minut, ponieważ (teraz) nieśledzony plik zostałby nadpisany przez wcześniejsze zatwierdzenie. Więc muszę skopiować plik, zrobić rzeczy git, a następnie umieścić go z powrotem. „Długość minut” wynika z mojej szybkości pisania. (Tak, mogłem to
napisać,
3

Możesz użyć do tego update-ref:

git fetch
git update-ref refs/heads/master origin/master
git checkout master

Zauważ, że spowodowałoby to odrzucenie wszelkich lokalnych zatwierdzeń w gałęzi master. W twoim przypadku ich nie będzie, więc to jest w porządku. Dla innych osób, które próbują to zrobić, gdy są lokalne zatwierdzenia, nie sądzę, aby było to możliwe, ponieważ scalanie można uruchomić tylko w bieżącej gałęzi.

Philip Beber
źródło
Czy byłoby to równoważne git branch --force master origin/master? To zmusza lokalną głowę masterdo wskazywania na głowę originsmaster
Keego
2

Rozwiązanie Malvineous działa dla mnie

$ git fetch                           # Update without changing any files
$ git branch -d master                # Remove out-of-date 'master' branch
$ git checkout --track origin/master  # Create and check out up-to-date 'master' branch

Po prostu podaj błąd


warning: not deleting branch 'master' that is not yet merged to
         'refs/remotes/origin/master', even though it is merged to HEAD.
error: The branch 'master' is not fully merged.
If you are sure you want to delete it, run 'git branch -D master'.

Więc uruchamiam z opcją -D

dzięki

Sebastian Oscar Lopez
źródło
0

git fetch origin master:master

  • „Pulls” (faktycznie pobiera) master.
  • Jeśli masz na swoim koncie zmiany master, które nie zostały jeszcze przesłane, origin/masterzostanie scalony z Twoim mistrzem.
  • Jeśli występują konflikty scalania, musisz je najpierw rozwiązać.
Luzian
źródło