Jak sklonować wszystkie odległe gałęzie w Git?


4129

Mam gałąź masteri developmentgałąź, obie przesyłane do GitHub . Mam cloned, pulled i fetched, ale pozostają w stanie dostać coś innego niż mastertyłu oddziału.

Jestem pewien, że brakuje mi czegoś oczywistego, ale przeczytałem instrukcję i wcale nie czerpię radości.


133
Zaakceptowana odpowiedź tutaj ( git branch -a) pokazuje gałęzie na pilocie, ale jeśli spróbujesz sprawdzić którekolwiek z nich, będziesz w stanie „odłączonej HEAD”. Następna odpowiedź w dół (drugi najbardziej pozytywny) odpowiada na inne pytanie (a mianowicie: jak wyciągnąć wszystkie gałęzie, i to znowu działa tylko dla tych, które śledzisz lokalnie). Kilka komentarzy wskazuje, że można przeanalizować git branch -awyniki za pomocą skryptu powłoki, który lokalnie śledziłby wszystkie zdalne gałęzie. Podsumowanie: Nie ma natywnego sposobu na robienie tego, co chcesz, i tak może nie być tak świetny pomysł.
Dzień Davis Waterbury,

5
Może po prostu skopiuj cały folder w staromodny sposób? scp some_user@example.com:/home/some_user/project_folder ~Nie jestem pewien, czy to rozwiązanie działa w przypadku github ...
snapfractalpop 26.09.12

19
Zamiast mówić „Sklonowałem, pociągnąłem i pobierałem”, znacznie lepiej, aby pokazać nam dokładnie te polecenia , które wykonałeś.
Bob Gilmore,

57
Zawsze zastanawia mnie, dlaczego „klonowanie” nie jest dokładnie taką kopią. Jeśli jest to dokładny klon, czy wszystkie gałęzie nie powinny być częścią lokalnego repozytorium? Chodzi mi o to, czy nie jest to jeden z powodów rozpowszechniania? Więc kiedy coś zniknie, nadal masz pełną kopię wszystkiego. Czy też tak zwany „zdalny” naprawdę jest już częścią lokalnego repozytorium?
huggie

21
Widząc wszystkie opinie, odpowiedzi, komentarze na temat odpowiedzi i zadziwiającą liczbę wyświetleń, myślę, że nadszedł czas, aby git dodał polecenie, aby to zrobić. Masz rację, dokładnie moje myśli.
Sнаđошƒаӽ

Odpowiedzi:


4557

Najpierw sklonuj zdalne repozytorium Git i włóż do niego cd :

$ git clone git://example.com/myproject
$ cd myproject

Następnie spójrz na lokalne oddziały w swoim repozytorium:

$ git branch
* master

Ale w twoim repozytorium są inne gałęzie! Możesz je zobaczyć za pomocą -aflagi:

$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental

Jeśli chcesz po prostu rzucić okiem na odgałęzienie, możesz to sprawdzić bezpośrednio:

$ git checkout origin/experimental

Ale jeśli chcesz pracować nad tym oddziałem, musisz utworzyć lokalny oddział śledzenia, który jest wykonywany automatycznie przez:

$ git checkout experimental

i zobaczysz

Branch experimental set up to track remote branch experimental from origin.
Switched to a new branch 'experimental'

Ta ostatnia linia rzuca niektórym ludziom: „Nowa gałąź” - co? To tak naprawdę oznacza, że ​​gałąź jest pobierana z indeksu i tworzona lokalnie dla Ciebie. Poprzednia linia jest rzeczywiście bardziej pouczające, jak mówi, że oddział jest skonfigurowany do śledzenia zdalnego oddział, który zwykle oznacza pochodzenie / branch_name oddział

Teraz, jeśli spojrzysz na swoje lokalne oddziały, zobaczysz to:

$ git branch
* experimental
  master

Możesz faktycznie śledzić więcej niż jedno zdalne repozytorium za pomocą git remote.

$ git remote add win32 git://example.com/users/joe/myproject-win32-port
$ git branch -a
* master
  remotes/origin/HEAD
  remotes/origin/master
  remotes/origin/v1.0-stable
  remotes/origin/experimental
  remotes/win32/master
  remotes/win32/new-widgets

W tym momencie sprawy stają się dość szalone, więc biegnij, gitkaby zobaczyć, co się dzieje:

$ gitk --all &

119
Jak ktoś może automatycznie utworzyć wszystkie odległe gałęzie, np. Eksperymentalne dla źródła / eksperymentalne?
Cristian Ciupitu,

54
Cristian: Zawsze tworzyłem gałąź „foo” dla każdego źródła „origin / foo”, ale doprowadziło to do dwóch problemów: (1) Skończyło się z wieloma naprawdę nieaktualnymi gałęziami śledzącymi, które były wiele zmian za odpowiadającą gałęzią zdalną oraz (2) w starszych wersjach git, uruchomienie „git push” spróbowałoby wypchnąć wszystkie moje lokalne gałęzie do zdalnego, nawet gdy te gałęzie były przestarzałe. Więc teraz przechowuję lokalne oddziały tylko dla rzeczy, które aktywnie rozwijam i uzyskuję bezpośredni dostęp do gałęzi origin / *, jeśli potrzebuję informacji na ich temat. (To powiedziawszy, możesz użyć skryptu powłoki do parsowania 'git branch -a'.)
emk

49
„git fetch <nazwa-oryginalna> <nazwa-gałęzienia>” sprowadza gałąź lokalnie dla ciebie.

137
Dobra odpowiedź, ale trochę mija pytanie. Szukałem liniowca, który sprawdziłby wszystkie odległe gałęzie.
cmcginty,

32
Pytanie dotyczyło klonowania wszystkich odległych gałęzi, a nie ich sprawdzania. I, jak zauważyłem powyżej, naprawdę nie chcesz tworzyć więcej lokalnych gałęzi śledzenia niż jest to konieczne, ponieważ gdy stają się naprawdę przestarzałe, mogą powodować bóle głowy.
emk

822

Jeśli masz wiele zdalnych gałęzi, które chcesz pobrać jednocześnie:

$ git pull --all

Teraz możesz kasować dowolną gałąź, tak jak potrzebujesz, bez konieczności odwiedzania zdalnego repozytorium.


12
Jeśli wykonam klonowanie git, mam lokalną gałąź główną i 10 gałęzi „zdalnych”. Więc ta odpowiedź Gabe była bardzo pomocna i odpowiada na pytanie.
basZero

38
pobiera tylko zdalne gałęzie, które zostały dodane lokalnie, a nie żadną gałąź zdalną
jujule,

33
Pierwsze polecenie jest zbędne. Po prostu git pull --allzrobi to samo - po prostu nie da się pobrać dwa razy. I infosec812 ma rację, że to i tak nie odpowiada na pytanie. Zastanawiam się, skąd tyle głosów.
Sven Marnach,

6
Kiedy to zrobiłem git remote update, a potem spróbowałem git branch, widzę tylko lokalne oddziały. Ale jeśli to zrobię git branch -a, mogę teraz zobaczyć odległe gałęzie i mogę zrobić, git pull <branchname>aby uzyskać gałąź, którą chcę. - Wylądowałem na tym pytaniu z wyszukiwarki Google i ta odpowiedź rozwiązuje mój problem.
WNRosenberg

38
Nie jest to wcale pomocne, nie wyciąga żadnych zdalnych gałęzi poza tym, że istnieje.
Avinash R

446

Ten skrypt Bash pomógł mi:

#!/bin/bash
for branch in $(git branch --all | grep '^\s*remotes' | egrep --invert-match '(:?HEAD|master)$'); do
    git branch --track "${branch##*/}" "$branch"
done

Stworzy gałęzie śledzące dla wszystkich gałęzi zdalnych, z wyjątkiem głównego (które prawdopodobnie otrzymałeś z oryginalnego polecenia klonowania). Myślę, że nadal będziesz musiał zrobić

git fetch --all
git pull --all

być pewnym.

Jedna linijka : git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs
jak zwykle: przetestuj w konfiguracji przed skopiowaniem wszechświata rm -rf, jaki znamy

Kredyty dla jednej linijki przejdź do interfejsu użytkownika


19
To jest naprawdę bliskie bycia idealnym rozwiązaniem. Jedyną rzeczą, która poprawiłaby to, byłoby gdyby ta funkcjonalność była wbudowana jako opcja w git.
Deven Phillips

51
„One liner”: git branch -a | grep -v HEAD | perl -ne 'chomp($_); s|^\*?\s*||; if (m|(.+)/(.+)| && not $d{$2}) {print qq(git branch --track $2 $1/$2\n)} else {$d{$_}=1}' | csh -xfs jak zwykle: przetestuj w konfiguracji przed kopiowaniemrm -rf universe as we know it
cfi

4
To polecenie tworzy gałęzie funkcji ze zdalnych jako normalne gałęzie (nie gałęzie cech) - jak to naprawić?
Alex2php,

4
jeśli napotkasz problemy z „/” w nazwach gałęzi, poniżej znajdziesz rozwiązanie, używając aliasu git. patrz odpowiedź: „nikt” na „odpowiedział 15 maja 13 'o 11:02”
wemu

8
Przycinam tylko, remotes/origin/aby zachować przestrzenie nazw:for BRANCH in $(git branch -a | grep remotes | grep -v HEAD | grep -v master); do git branch --track "${BRANCH#remotes/origin/}" "${BRANCH}"; done
kgadek

348

--mirrorWydaje się, że użycie opcji powoduje remoteprawidłowe skopiowanie gałęzi śledzących. Jednak ustawia repozytorium jako samo repozytorium, więc musisz później przekształcić je z powrotem w normalne repozytorium.

git clone --mirror path/to/original path/to/dest/.git
cd path/to/dest
git config --bool core.bare false
git checkout anybranch

Odwołanie: Git FAQ: Jak sklonować repozytorium ze wszystkimi zdalnie śledzonymi oddziałami?


7
Wiesz, to wydaje się być całkiem dobrą odpowiedzią, mimo że nie ma głosów. Czy są jakieś pułapki, aby to zrobić w ten sposób? Musiałem jawnie pobrać gałąź po uruchomieniu tych poleceń.
pętla

27
To w połączeniu z git push --mirror są dokładnie tym, czego potrzebowałem, aby utworzyć dokładną kopię zdalnego repozytorium git podczas przechodzenia z github.com do instalacji github w przedsiębiorstwie. Dzięki!
Jacob Fike,

3
@Dave: Dodaj git checkoutostatnią komendę, aby w końcu pobrać nagłówek bieżącej gałęzi na sklonowanym repozytorium. To świetna odpowiedź, zdecydowanie najlepsza. Bądź odważny, w końcu doprowadzimy cię na szczyt :-)
cfi

3
@Dave: Hm. Zastanawiam się nad tym: --mirror to coś więcej niż konfiguracja wszystkich gałęzi jako śledzonych. Kopiuje wszystkie referencje z źródła, a następnie git remote updatezrobi to ponownie. Zachowanie zmian ciągnie. Wróciłem do przekonania, że ​​pełna kopia wymaga skryptu o jednym wierszu.
cfi

5
git clone --mirrorjest bardzo dobry do tworzenia kopii zapasowych repozytoriów git ^ _ ^
TrinitronX

220

Możesz łatwo przejść do gałęzi bez użycia fantazyjnej składni „git checkout -b somebranch origin / somebranch”. Możesz po prostu zrobić:

git checkout somebranch

Git automatycznie zrobi właściwą rzecz:

$ git checkout somebranch
Branch somebranch set up to track remote branch somebranch from origin.
Switched to a new branch 'somebranch'

Git sprawdzi, czy gałąź o tej samej nazwie istnieje w dokładnie jednym pilocie, a jeśli tak, śledzi ją w taki sam sposób, jakbyś wyraźnie wskazał, że jest to gałąź zdalna. Ze strony podręcznika git-checkout w Git 1.8.2.1:

Jeśli <branch> nie zostanie znaleziony, ale istnieje dokładnie gałąź śledzenia w jednym pilocie (nazwij ją <remote>) o pasującej nazwie, traktuj ją jako równoważną do

$ git checkout -b <branch> --track <remote>/<branch>

1
Więc jeśli nazwa gałęzi, którą jesteś checkoutjest identyczna z nazwą gałęzi zdalnej, wszystko po „/”, to git utworzy gałąź o tej samej nazwie, wszystko po „/”, „śledzenie” tego zdalnego ? I przez śledzenie, mamy na myśli: git push, git pull, itd. Zostaną wykonane na tym pilocie? Jeśli jest to poprawne, rozwiń swoją odpowiedź o więcej informacji, ponieważ zgadzam się z @Daniel, ta odpowiedź zasługuje na więcej powtórzeń.
Gerard Roche,

5
@BullfrogBlues, odpowiedź na wszystkie twoje pytania wydaje się tak (używam git v7.7.7.4). Zgadzam się, że to zachowanie powinno być lepiej znane. (Nie ma go w instrukcji dla tej wersji gita.) Tak naprawdę to nie lubię tego zachowania, wolę dostać błąd i muszę powiedzieć git checkout --track origin/somebranchwprost.
dubiousjim

3
@dubiousjim: Właściwie to jest w instrukcji. git-checkout (1) mówi: „Jeśli nie znaleziono <odgałęzienia>, ale istnieje dokładnie gałąź śledzenia w dokładnie jednym zdalnym (nazwij to <remote>) o pasującej nazwie, traktuj jako odpowiednik 'git checkout -b <gałąź > --track <remote> / <branch> '”(Git V.1.8.1.1).
sleske

Potrzebujemy $ git pull * <remote> / * - gdzie „*” jest znakiem wieloznacznym, więc ciągnie wszystkie gałęzie, w tym te, które nie są jeszcze w systemie lokalnym. Jak to zrobić? Czy naprawdę powinniśmy sprawdzać / pobierać wszystkie gałęzie, aby pobrać kod do naszego lokalnego systemu?
JosephK

98

Jeżeli chodzi o,

$ git checkout -b eksperymentalne pochodzenie / eksperymentalne

za pomocą

$ git checkout -t origin/experimental

lub bardziej szczegółowe, ale łatwiejsze do zapamiętania

$ git checkout --track origin/experimental

może być lepiej, jeśli chodzi o śledzenie zdalnego repozytorium.


Masz na myśli, że drugą formę łatwiej zapamiętać i nie ma innej różnicy?
aderchox

79

Operacja pobierania powinna uzyskać wszystkie zdalne gałęzie, ale nie utworzy dla nich lokalnych gałęzi. Jeśli używasz gitk, powinieneś zobaczyć zdalne gałęzie opisane jako „piloty / origin / dev” lub coś podobnego.

Aby utworzyć gałąź lokalną na podstawie gałęzi zdalnej, wykonaj następujące czynności:

git checkout -b dev refs / remotes / origin / dev

Który powinien zwrócić coś takiego:

Konfiguracja oddziału skonfigurowana do śledzenia zdalnych referencji / pilotów / pochodzenia / dev oddziału.
Przeniesiono do nowej gałęzi „dev”

Teraz, gdy jesteś w gałęzi programistów, polecenie „git pull” zaktualizuje lokalnego programistę do tego samego punktu, co gałąź zdalnych programistów. Pamiętaj, że pobierze wszystkie gałęzie, ale tylko tę, na której jesteś, pociągnij tylko na szczyt drzewa.


14
Nie potrzebujesz tutaj referencji / pilotów. git checkout -b dev origin / dev będzie działać poprawnie.
emk

3
To zawsze działa: git checkout -b newlocaldev --track origin/dev. Jeśli chcesz, aby lokalny oddział miał taką samą nazwę jak zdalny, a zdalny nie ma trudnej nazwy, możesz pominąć -b newlocaldev. Przy domyślnym branch.autosetupmergeustawieniu konfiguracji i przy założeniu, że nie masz nazwy lokalnego oddziału dev, te dwie komendy mogą zrobić to samo: git checkout -b dev origin/devpo prostu git checkout dev. Wreszcie, git checkout origin/devnie tworzy nowej gałęzi, ale po prostu wprowadza cię w stan odłączonego HEAD.
dubiousjim

Co dzieje się, gdy pilot już nie istnieje, ale Git jest zbyt głupi, aby uznać, że został usunięty? Zakłada się, że zaktualizowano i git branch -anadal wyświetla listę jako gałąź zdalna.
jww

I robimy to dla dziesiątek oddziałów?
JosephK

59

Po wykonaniu polecenia „git clone git: // location” wszystkie gałęzie i tagi są pobierane.

Aby pracować nad konkretną gałęzią zdalną, zakładając, że jest to zdalny początek:

git checkout -b branch origin/branchname

2
Doceniam twoją notatkę „wszystkie gałęzie i tagi są pobierane”. Zamierzałem skomentować, że twoja odpowiedź jest błędna, ale potem to sprawdziłem i stwierdziłem, że masz całkowitą rację. W pewien sposób udzieliłeś najkrótszej odpowiedzi - jeśli sklonowałeś, już ją masz. Miły. Można spróbować dodać: spróbuj $ git branch -adowiedzieć się, jakie zdalne gałęzie są już dostępne.
Jan Vlcinsky,

Zobacz także odpowiedź, którą zamieściłem. Może to być pomocne, jeśli wiesz, że będziesz chciał pracować lokalnie na wielu zdalnych oddziałach i nie będziesz musiał ich sprawdzać jeden po drugim.
lacostenycoder,

Czy możesz mi wyjaśnić, jaka jest różnica między git checkout -b master origin/masteri git checkout --track origin/masterproszę?
aderchox

1
@aderchox Obecnie myślę, że żaden.
elmarco

58

Użyj aliasów. Chociaż nie ma natywnych linijek Git, możesz zdefiniować własne jako

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

a następnie użyj go jako

git clone-branches

Dzięki. To faktycznie klonuje wszystkie odległe gałęzie, w przeciwieństwie do kilku innych odpowiedzi
FearlessHyena

50

Dlaczego widzisz tylko „master”

git clonepobiera wszystkie zdalne gałęzie, ale nadal uważa je za „zdalne”, nawet jeśli pliki znajdują się w nowym repozytorium. Jest jeden wyjątek od tego, że proces klonowania tworzy lokalną gałąź o nazwie „master” ze zdalnej gałęzi o nazwie „master”. Domyślnie git branchpokazuje tylko lokalne oddziały, dlatego widzisz tylko „master”.

git branch -apokazuje wszystkie gałęzie, w tym gałęzie zdalne .


Jak zdobyć lokalne oddziały

Jeśli naprawdę chcesz pracować nad oddziałem, prawdopodobnie będziesz chciał mieć jego „lokalną” wersję. Aby po prostu utworzyć oddziały lokalne ze zdalnych oddziałów (bez ich sprawdzania, a tym samym zmiany zawartości katalogu roboczego) , możesz to zrobić w następujący sposób:

git branch branchone origin/branchone
git branch branchtwo origin/branchtwo
git branch branchthree origin/branchthree

W tym przykładzie branchonejest nazwą lokalnego oddziału, który tworzysz na podstawie origin/branchone; jeśli zamiast tego chcesz utworzyć lokalne oddziały o różnych nazwach, możesz to zrobić:

git branch localbranchname origin/branchone

Po utworzeniu oddziału lokalnego możesz go zobaczyć za pomocą git branch(pamiętaj, że nie musisz -awidzieć oddziałów lokalnych).


Jeśli origin/branchoneistnieje, możesz także użyć git checkout branchonedo utworzenia lokalnego oddziału o tej samej nazwie i ustawienia zdalnego śledzenia.
Evan

47

Nie jest to zbyt skomplikowane, bardzo proste i proste kroki są następujące;

git fetch origin Spowoduje to przeniesienie wszystkich zdalnych oddziałów do twojego lokalnego.

git branch -a Spowoduje to wyświetlenie wszystkich zdalnych gałęzi.

git checkout --track origin/<branch you want to checkout>

Sprawdź, czy jesteś w pożądanej gałęzi, wykonując następujące polecenie;

git branch

Dane wyjściowe będą się podobać;

*your current branch 
some branch2
some branch3 

Zwróć uwagę na znak *, który oznacza bieżącą gałąź.


1
Dzięki, suraj. Powód, ponieważ nie głosowano zbyt wiele. I pytający nie przyjmuje odpowiedzi.
Sam

„Git fetch origin” nie przyniósł żadnej ze zdalnych gałęzi do mojej lokalnej - czy są gdzieś ukryte? Czytanie wszystkich powyższych odpowiedzi sprawiło mi ból głowy. Szukamy „git fetch all oddział to local”. Aby to zrobić, musi istnieć sposób na uniknięcie skryptów bash.
JosephK

1
Zaraz po uruchomieniu „git fetch origin”, wyświetli on takie wyjście w twoim terminalu - „* [nowa gałąź] nazwa_gałęzi -> pochodzenie / nazwa_gałęzi”, ale po uruchomieniu „git gałąź” pokaże tylko twój lokalny gałęzie zamiast tego, aby zobaczyć wszystkie gałęzie, możesz zrobić „git gałąź -a”, a następnie, aby przełączyć się na gałąź zdalną, musisz uruchomić „git checkout --track origin / <gałąź, którą chcesz wyewidencjonować>”. Mam nadzieję że to pomoże. :-)
Sam

4
Suraj, bo pytanie brzmiało: jak „klonować wszystkie zdalne gałęzie” - a nie jak ręcznie aktualizować pojedynczo. Wydaje się, że nie ma odpowiedzi na rzeczywiste pytanie - tylko sposoby na pisanie, jeśli masz dużo gałęzi.
JosephK

47

Lepiej późno niż wcale, ale oto najlepszy sposób na to:

mkdir repo
cd repo
git clone --bare path/to/repo.git .git
git config --unset core.bare
git reset --hard

W tym momencie masz pełną kopię zdalnego repo ze wszystkimi jego gałęziami (sprawdź za pomocą git branch). Możesz użyć --mirrorzamiast tego, --barejeśli twoje zdalne repo ma własne piloty.


Podczas edycji tutaj coś poszło nie tak. Teraz ta odpowiedź nie ma sensu. „ --bare” Wymienione w ostatnim zdaniu nie istnieje na podanej liście poleceń.
Cerran,

czerpiąc z odpowiedzi Dave'a poniżej. Używanie „git config --bool core.bare false” zamiast „git config unset core.bare” wydaje się wykonywać zadanie.
Zmieszany Vorlon,

Mam error: key does not contain a section: unset. Odpowiedź Dave'a działa lepiej.
olibre

To git config --unset core.barewłaściwie ... Dla mnie wydaje się to najczystszym rozwiązaniem ze wszystkich przedstawionych tutaj odpowiedzi. Szkoda, że ​​ma tak mało głosów poparcia ...
Dirk Hillbrecht

1
Dzięki @ChrisSim Zgadzam się git config --bool core.bare false. Dlatego zamiast tego polecam odpowiedź Dave'a . Co sądzisz o odpowiedzi Dave'a ? Pozdrawiam
olibre

39

Po prostu zrób to:

$ git clone git://example.com/myproject
$ cd myproject
$ git checkout branchxyz
Branch branchxyz set up to track remote branch branchxyz from origin.
Switched to a new branch 'branchxyz'
$ git pull
Already up-to-date.
$ git branch
* branchxyz
  master
$ git branch -a
* branchxyz
  master
  remotes/origin/HEAD -> origin/master
  remotes/origin/branchxyz
  remotes/origin/branch123

Widzisz, „git clone git: //example.com/myprojectt” pobiera wszystko, nawet gałęzie, musisz je tylko sprawdzić, wtedy twoja lokalna gałąź zostanie utworzona.


25

Aby uzyskać wszystkie gałęzie, wystarczy użyć „git clone”.

git clone <your_http_url>

Nawet jeśli widzisz tylko gałąź master, możesz użyć „git branch -a”, aby zobaczyć wszystkie gałęzie.

git branch -a

I możesz przejść do dowolnej gałęzi, którą już masz.

git checkout <your_branch_name>

Nie martw się, że po „git clone” nie musisz łączyć się ze zdalnym repozytorium, „git branch -a” i „git checkout” mogą zostać pomyślnie uruchomione po zamknięciu Wi-Fi. Udowodniono więc, że po wykonaniu „git clone” skopiował on już wszystkie gałęzie ze zdalnego repozytorium. Po tym nie potrzebujesz zdalnego repo, twój lokalny ma już wszystkie kody oddziałów.


Bardzo wyraźna odpowiedź tutaj. Wielu ludzi myliło się na ten temat.
XMAN,

Chciałbym poprzeć twoje stwierdzenie „można uruchomić z powodzeniem po zamknięciu Wi-Fi”. „git clone” naprawdę powoduje, że repo zawiera wszystkie gałęzie.
bvgheluwe

Świetna, jasna, prosta odpowiedź.
Amr

24

A git clonema skopiować całe repozytorium. Spróbuj go sklonować, a następnie uruchom git branch -a. Powinien zawierać listę wszystkich gałęzi. Jeśli następnie chcesz przejść do gałęzi „foo” zamiast „master”, użyj git checkout foo.


1
Możesz uruchamiać polecenia git z łącznikiem lub bez niego. Działa zarówno „git-branch”, jak i „git branch”.
Peter Boughton,

21
Być może ta odpowiedź została udzielona dawno temu, kiedy git działał inaczej, ale myślę, że dziś jest myląca. git clonepobiera wszystkie zdalne gałęzie, ale tworzy tylko lokalną gałąź master. Ponieważ git branchpokazuje tylko oddziały lokalne, musisz git branch -atakże zobaczyć oddziały zdalne.
Cerran,

Dziękuję Ci. Jest to rodzaj dziwnego domyślnego zachowania IMO. Po prostu napiszę to na bardziej tajemniczy żart. Jeśli pobierał gałęzie, dlaczego miałby je ukrywać podczas wywoływania gałęzi git?
Adam Hughes,

1
@Cerran, dzięki; Zaktualizowałem odpowiednio swoją odpowiedź.
MattoxBeckman

„pobiera wszystkie zdalne gałęzie, ale tworzy tylko lokalną gałąź master”. Potrzebuję pomocy w zrozumieniu tego. Wygląda na to, że git clone NIE klonuje żadnych gałęzi oprócz master, tak jak kiedy robisz „git branch -a”, pokazuje, że gałąź „develop” znajduje się tylko na „pilotach / origin / develop”. To musi być powiedzenie, że nie masz tej gałęzi nigdzie lokalnie, istnieje ona tylko na początku, prawda?
John Little

19

Użyj mojego narzędzia git_remote_branch (potrzebujesz Ruby zainstalowanego na twoim komputerze). Został zbudowany specjalnie, aby ułatwić zdalne manipulowanie gałęziami.

Za każdym razem, gdy wykonuje operację w Twoim imieniu, drukuje ją na czerwono na konsoli. Z czasem w końcu wbijają się w twój mózg :-)

Jeśli nie chcesz, aby grb uruchamiał polecenia w Twoim imieniu, po prostu użyj funkcji „wyjaśnij”. Polecenia zostaną wydrukowane na konsoli zamiast wykonane dla Ciebie.

Na koniec wszystkie polecenia mają aliasy, aby ułatwić zapamiętywanie.

Zauważ, że jest to oprogramowanie alfa ;-)

Oto pomoc po uruchomieniu pomocy grb:

git_remote_branch wersja 0.2.6

  Stosowanie:

  grb utwórz nazwę gałęzi [serwer_początku] 

  grb opublikuj nazwa_gałęzi [serwer_początkowy] 

  grb zmień nazwę nazwa_ gałęzi [serwer_początkowy] 

  grb usuń nazwa_gałęzi [serwer_początkowy] 

  grb track nazwa_gałęzi [serwer_początkowy] 



  Uwagi:
  - Jeśli serwer_początkowy nie jest określony, zakłada się nazwę „pochodzenie” 
    (domyślnie git)
  - Funkcja zmiany nazwy zmienia nazwę bieżącej gałęzi

  Wyjaśnij meta-polecenie: możesz również wstawić dowolne polecenie za pomocą 
słowo kluczowe „wyjaśnij”. Zamiast wykonać polecenie, git_remote_branch
po prostu wyświetli listę poleceń, które musisz uruchomić, aby wykonać 
ten cel.

  Przykład: 
    grb wyjaśnić stworzyć
    grb wyjaśni, stwórz github my_branch

  Wszystkie polecenia mają również aliasy:
  utwórz: utwórz, nowy
  delete: usuń, zniszcz, zabij, usuń, rm
  opublikuj: opublikuj, zdalnie
  rename: zmiana nazwy, rn, mv, move
  śledzenie: śledzenie, śledzenie, chwytanie, pobieranie

6
Słowo dla mądrych: Wygląda na to, że ten projekt został porzucony w czasie, gdy opublikowano tę odpowiedź. Nie mogę znaleźć żadnych aktualizacji po 2008 roku. Zastrzegam emptor i tak dalej. Jeśli się mylę, mam nadzieję, że ktoś dokona edycji i udostępni bieżący wskaźnik, ponieważ chciałbym mieć takie narzędzie pod ręką.
bradheintz

@bradheintz sprawdź tę odpowiedź, ustawia alias git: stackoverflow.com/a/16563327/151841
user151841

19

wszystkie odpowiedzi, które tu widziałem, są poprawne, ale istnieje znacznie czystszy sposób klonowania repozytorium i wyciągania wszystkich gałęzi na raz.

Po sklonowaniu repozytorium wszystkie informacje o gałęziach są faktycznie pobierane, ale gałęzie są ukryte. Za pomocą polecenia

$ git branch -a

możesz wyświetlić wszystkie gałęzie repozytorium i za pomocą polecenia

$ git checkout -b branchname origin/branchname

możesz następnie „ręcznie” pobrać je pojedynczo.


Jednak jeśli chcesz sklonować repozytorium z wieloma gałęziami, wszystkie przedstawione powyżej sposoby są długie i żmudne w odniesieniu do znacznie czystszego i szybszego sposobu, który zamierzam pokazać, chociaż jest to trochę skomplikowane. Aby to osiągnąć, musisz wykonać trzy kroki:

  1. Pierwszy krok

utwórz nowy pusty folder na swoim komputerze i klonuj kopię lustrzaną folderu .git z repozytorium:

$ cd ~/Desktop && mkdir my_repo_folder && cd my_repo_folder
$ git clone --mirror https://github.com/planetoftheweb/responsivebootstrap.git .git

lokalne repozytorium w folderze my_repo_folder jest nadal puste, jest teraz tylko ukryty folder .git, który można zobaczyć za pomocą polecenia „ls -alt” z terminala.

  1. Drugi krok

przełącz to repozytorium z pustego (pustego) do zwykłego, zmieniając wartość logiczną „gołą” konfiguracji git na false:

$ git config --bool core.bare false
  1. Trzeci krok

Chwyć wszystko, co znajduje się w bieżącym folderze i utwórz wszystkie gałęzie na komputerze lokalnym, dzięki czemu jest to normalne repo.

$ git reset --hard

Teraz możesz po prostu wpisać polecenie „git branch” i możesz zobaczyć, że wszystkie gałęzie zostały pobrane.

Jest to szybki sposób klonowania repozytorium git ze wszystkimi gałęziami jednocześnie, ale nie jest to coś, co chcesz zrobić dla każdego projektu w ten sposób.


Nie podoba mi się to, że używasz słowa „pobierz” w… „pobierz” je ręcznie, pojedynczo . Wszystkie informacje zostały już pobrane po sklonowaniu repozytorium. Jedyne, co należy zrobić, to utworzyć lokalne gałęzie śledzenia (co jest również możliwe w trybie offline, co dowodzi, że wszystkie informacje znajdują się w repozytorium).
bvgheluwe

@bvgheluwe dlatego jest w cudzysłowie.
FedericoCapaldo

15

Klonowanie z lokalnego repozytorium nie będzie działać w przypadku git clone i git fetch: wiele gałęzi / tagów pozostanie nierozwiniętych.

Aby uzyskać klon ze wszystkimi gałęziami i tagami.

git clone --mirror git://example.com/myproject myproject-local-bare-repo.git

Aby uzyskać klon ze wszystkimi gałęziami i tagami, ale także z kopią roboczą:

git clone --mirror git://example.com/myproject myproject/.git
cd myproject
git config --unset core.bare
git config receive.denyCurrentBranch updateInstead
git checkout master

13

OK, kiedy klonujesz swoje repozytorium, masz tam wszystkie oddziały ...

Jeśli to zrobisz git branch, są jakby ukryte ...

Więc jeśli chcesz zobaczyć nazwę wszystkich gałęzi, po prostu dodaj --allflagę w ten sposób:

git branch --all lub git branch -a

Jeśli tylko zameldujesz się w oddziale, otrzymasz wszystko, czego potrzebujesz.

Ale co jeśli gałąź utworzona przez kogoś innego po sklonowaniu?

W takim przypadku po prostu wykonaj:

git fetch

i sprawdź ponownie wszystkie gałęzie ...

Jeśli chcesz pobierać i kasować w tym samym czasie, możesz:

git fetch && git checkout your_branch_name

Utworzyłem również poniższy obrazek, aby uprościć to, co powiedziałem:

git branch - wszystko, aby uzyskać wszystkie gałęzie


3
Istnieje różnica między „masz to” a „widzisz”. git branch -all NIE będzie już wyświetlał zdalnych gałęzi po usunięciu zdalnego repozytorium.
Gustave

12

Patrząc na jedną z odpowiedzi na pytanie, zauważyłem, że można go skrócić:

for branch in  `git branch -r | grep -v 'HEAD\|master'`; do  
 git branch --track ${branch##*/} $branch;
done

Ale uwaga, jeśli jedna ze zdalnych gałęzi zostanie nazwana np. Admin_master, nie zostanie pobrana!

Dzięki bigfish za oryginalny pomysł


Możesz poprawić wyrażenie regularne lub użyć Awk zamiast grep, aby ulepszyć filtr, aby uniknąć fałszywych trafień.
tripleee

wszystkie gałęzie to „origin \ my_branch_name”, co nie jest zdecydowanie tym, czego chcę.
Sнаđошƒаӽ

Nie widziałem wcześniej konstrukcji $ {branch ## * /} - wygląda na naprawdę przydatną - jakiś pomysł, gdzie mogę dowiedzieć się więcej na ten temat? nigdzie nie można znaleźć pod bash. Dzięki.
SaminOz


10

Aby skopiować i wkleić do wiersza poleceń:

git checkout master ; remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch -D $brname ; git checkout -b $brname $remote/$brname ; done ; git checkout master

Dla większej czytelności:

git checkout master ;
remote=origin ;
for brname in `
    git branch -r | grep $remote | grep -v master | grep -v HEAD 
    | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do
    git branch -D $brname ;
    git checkout -b $brname $remote/$brname ;
done ;
git checkout master


Spowoduje to:

  1. sprawdź master (abyśmy mogli usunąć gałąź, na której jesteśmy)
  2. wybierz pilota do kasy (zmień go na dowolny pilot)
  3. zapętlić wszystkie gałęzie pilota oprócz master i HEAD
    1. usuń oddział lokalny (abyśmy mogli sprawdzić wymuszone aktualizacje oddziałów)
    2. sprawdź gałąź ze zdalnego
  4. sprawdź master (ze względu na to)

Na podstawie odpowiedzi z VonC .


10

Napisałem te małe funkcje Powershell, aby móc sprawdzić wszystkie moje gałęzie git, które są zdalnie pochodzenia.

Function git-GetAllRemoteBranches {
     iex "git branch -r"                       <# get all remote branches #> `
     | % { $_ -Match "origin\/(?'name'\S+)" }  <# select only names of the branches #> `
     | % { Out-Null; $matches['name'] }        <# write does names #>
}


Function git-CheckoutAllBranches {
    git-GetAllRemoteBranches `
        | % { iex "git checkout $_" }          <# execute ' git checkout <branch>' #>
}

Więcej funkcji git można znaleźć w moim repozytorium ustawień git


9

Oto odpowiedź, która używa awk. Ta metoda powinna wystarczyć, jeśli zostanie użyta w nowym repozytorium.

git branch -r | awk -F/ '{ system("git checkout " $NF) }'

Istniejące gałęzie zostaną po prostu wyewidencjonowane lub zadeklarowane jako już w nim zawarte, ale filtry można dodać, aby uniknąć konfliktów.

Można go również modyfikować, aby wywoływał jawne git checkout -b <branch> -t <remote>/<branch>polecenie.

Ta odpowiedź następująco Nikos C. „s pomysł .


Alternatywnie możemy zamiast tego określić zdalną gałąź. Jest to oparte na murphytalk „s odpowiedź .

git branch -r | awk '{ system("git checkout -t " $NF) }'

Zgłasza krytyczne komunikaty o błędach dotyczące konfliktów, ale widzę je jako nieszkodliwe.


Oba polecenia można aliasować.

Korzystanie nikt dydaktycznego odpowiedzi jako punkt odniesienia, możemy mieć następujące polecenia, aby utworzyć aliasy:

git config --global alias.clone-branches '! git branch -r | awk -F/ "{ system(\"git checkout \" \$NF) }"'
git config --global alias.clone-branches '! git branch -r | awk "{ system(\"git checkout -t \" \$NF) }"'

Osobiście użyłbym track-alllub track-all-branches.


Chciałem ci tylko podziękować.
Działa

8

Musiałem zrobić dokładnie to samo. Oto mój skrypt Ruby .

#!/usr/bin/env ruby

local = []
remote = {}

# Prepare
%x[git reset --hard HEAD]
%x[git checkout master] # Makes sure that * is on master.
%x[git branch -a].each_line do |line|
  line.strip!
  if /origin\//.match(line)
     remote[line.gsub(/origin\//, '')] = line
   else
     local << line
   end
end
# Update 
remote.each_pair do |loc, rem|
  next if local.include?(loc)
  %x[git checkout --track -b #{loc} #{rem}]
end
%x[git fetch]

Zobacz odpowiedź, którą zamieściłem poniżej, aby w ogóle uniknąć uruchamiania tego skryptu.
lacostenycoder

8

Żadna z tych odpowiedzi go nie ogranicza, z wyjątkiem użytkownika, że ​​nikt nie jest na dobrej drodze.

Miałem problem z przenoszeniem repozytorium z jednego serwera / systemu na inny. Kiedy sklonowałem repozytorium, utworzyło ono tylko lokalną gałąź dla mastera, więc kiedy przełączyłem na nowy pilot, tylko gałąź master została wypchnięta.

Dlatego te dwie metody były BARDZO przydatne. Mam nadzieję, że pomogą komuś innemu.

Metoda 1:

git clone --mirror OLD_REPO_URL
cd new-cloned-project
mkdir .git
mv * .git
git config --local --bool core.bare false
git reset --hard HEAD
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

Metoda 2:

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'
git clone OLD_REPO_URL
cd new-cloned-project
git clone-branches
git remote add newrepo NEW_REPO_URL
git push --all newrepo
git push --tags newrepo

8

git clone --mirror na oryginalnym repozytorium działa dobrze w tym celu.

git clone --mirror /path/to/original.git
git remote set-url origin /path/to/new-repo.git
git push -u origin

7

Git zwykle (gdy nie jest określony) pobiera wszystkie gałęzie i / lub tagi (odnośniki, patrz:) git ls-refsz jednego lub więcej innych repozytoriów wraz z obiektami niezbędnymi do uzupełnienia ich historii. Innymi słowy, pobiera obiekty, które są osiągalne przez obiekty już pobrane. Zobacz: co tak git fetchnaprawdę robi?

Czasami możesz mieć oddziały / tagi, które nie są bezpośrednio połączone z bieżącym, więc git pull --all/ git fetch --allnie pomoże w takim przypadku, ale możesz je wymienić według:

git ls-remote -h -t origin

i pobierz je ręcznie, znając nazwy referencyjne.

Aby pobrać je wszystkie , spróbuj:

git fetch origin --depth=10000 $(git ls-remote -h -t origin)

Ten --depth=10000parametr może pomóc, jeśli masz płytkie repozytorium.

Następnie sprawdź ponownie wszystkie swoje oddziały:

git branch -avv

Jeśli powyższe nie pomoże, musisz ręcznie dodać brakujące gałęzie do listy śledzenia (ponieważ w jakiś sposób się zgubiły):

$ git remote -v show origin
...
  Remote branches:
    master      tracked

przez git remote set-branches:

git remote set-branches --add origin missing_branch

więc może pojawić się remotes/originpo pobraniu:

$ git remote -v show origin
...
  Remote branches:
    missing_branch new (next fetch will store in remotes/origin)
$ git fetch
From github.com:Foo/Bar
 * [new branch]      missing_branch -> origin/missing_branch

Rozwiązywanie problemów

Jeśli nadal nie możesz uzyskać niczego innego niż gałąź główna, sprawdź następujące elementy:

  • Sprawdź dokładnie swoje piloty ( git remote -v), np
    • Sprawdź git config branch.master.remoteto origin.
    • Sprawdź, czy originwskazuje właściwy adres URL za pośrednictwem: git remote show origin(zobacz ten post ).

7

Na początku 2017 r. Odpowiedź w tym komentarzu działa:

git fetch <origin-name> <branch-name>obniża gałąź dla ciebie. Chociaż nie powoduje to ściągnięcia wszystkich gałęzi naraz, możesz pojedynczo wykonać tę gałąź.


Wymaga to pobrania każdej gałęzi pojedynczo. Niezbyt dobrze, jeśli masz dużo oddziałów.
lacostenycoder,

6

Oto kolejne krótkie polecenie jednowierszowe, które tworzy oddziały lokalne dla wszystkich oddziałów zdalnych:

(git branch -r | sed -n '/->/!s#^  origin/##p' && echo master) | xargs -L1 git checkout

Działa także poprawnie, jeśli śledzone są już lokalne oddziały. Możesz zadzwonić po raz pierwszy git clonelub później.

Jeśli nie musisz mieć mastergałęzi wyewidencjonowanej po klonowaniu, użyj

git branch -r | sed -n '/->/!s#^  origin/##p'| xargs -L1 git checkout
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.