Как клонировать все удаленные ветки в Git?


4130

У меня есть masterи developmentветка, оба подтолкнули на GitHub . Я cloned, pulled и fetched, но я не могу получить ничего, кроме masterответвления.

Я уверен, что упускаю что-то очевидное, но я прочитал руководство и совсем не радуюсь.


133
Принятый ответ здесь ( git branch -a) показывает вам ветви на удаленном компьютере, но если вы попытаетесь проверить какие-либо из них, вы окажетесь в состоянии «отключенный ГОЛОВ». Следующий ответ «вниз» (второе по популярности) отвечает на другой вопрос (а именно: как вытянуть все ветви, и, опять же, это работает только для тех, кого вы отслеживаете локально). В некоторых комментариях указывается, что вы можете анализировать git branch -aрезультаты с помощью сценария оболочки, который будет локально отслеживать все удаленные ветви. Резюме: не существует мерзкого способа сделать то, что вы хотите, и в любом случае это может быть не очень хорошей идеей.
День Дэвиса Уотербери

5
Может быть, просто скопировать всю папку по старинке? scp some_user@example.com:/home/some_user/project_folder ~Не уверен, что это решение работает для github, хотя ..
snapfractalpop

19
Вместо того чтобы сказать «я клонировал, вытащил и получил», гораздо лучше показать нам точные команды, которые вы выполнили.
Боб Гилмор

57
Меня всегда удивляет, почему «клон» не является точной копией. Если это точный клон, не должны ли все ветви быть частью локального репозитория? Я имею в виду, не является ли это одной из точек распространения? Поэтому, когда что-то исчезло, у вас все еще есть полная копия. Или это так называемый «удаленный» действительно уже является частью локального хранилища?
Хагги

21
Видя все положительные отзывы, ответы, комментарии к ответам и ошеломляющее количество просмотров, я думаю, пришло время добавить команду для этого. И верно, ты @huggie, мои мысли точно.
Snađошƒаӽ

Ответы:


4557

Сначала клонируйте удаленный репозиторий Git и перейдите в него:

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

Далее посмотрите на локальные ветки в вашем репозитории:

$ git branch
* master

Но есть другие ветки, скрывающиеся в вашем хранилище! Вы можете увидеть это, используя -aфлаг:

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

Если вы просто хотите быстро взглянуть на ветку upstream, вы можете проверить это непосредственно:

$ git checkout origin/experimental

Но если вы хотите работать с этой веткой, вам нужно создать локальную ветку отслеживания, которая выполняется автоматически:

$ git checkout experimental

и ты увидишь

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

Эта последняя строка бросает некоторых людей: "Новая ветвь" - а? На самом деле это означает, что ветка берется из индекса и создается для вас локально. Предыдущая линия на самом деле более информативная, он говорит вам , что филиал создается для отслеживания удаленного филиала, что обычно означает происхождение / branch_name филиал

Теперь, если вы посмотрите на свои местные филиалы, вот что вы увидите:

$ git branch
* experimental
  master

На самом деле вы можете отслеживать более одного удаленного хранилища, используя 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

В этот момент все становится довольно сумасшедшим, поэтому бегите gitkпосмотреть, что происходит:

$ gitk --all &

119
Как кто-то может автоматически создать все удаленные ветви, например, экспериментальные для происхождения / экспериментальные?
Кристиан Чиупиту

54
Кристиан: Раньше я всегда создавал ветку 'foo' для каждой ветки 'origin / foo', но это приводило к двум проблемам: (1) Я получал множество действительно устаревших ветвей отслеживания, которые были много коммитов за соответствующей удаленной веткой и (2) в более старых версиях git запуск git push попытался перенести все мои локальные ветви на удаленный компьютер, даже если эти ветви были устаревшими. Так что теперь я сохраняю локальные ветки только для тех вещей, которые активно развиваю, и получаю доступ к веткам origin / * напрямую, если мне нужна информация о них. (Тем не менее, вы можете использовать сценарий оболочки для анализа 'git branch -a'.)
emk

49
"git fetch <origin-name> <branch-name>" выводит ветку локально для вас.

137
Хороший ответ, но вроде пропускает вопрос. Я искал однострочник для проверки всех удаленных филиалов.
cmcginty

32
Речь шла о клонировании всех удаленных веток, а не об их проверке. И, как я отмечал выше, вы действительно не хотите создавать больше локальных веток отслеживания, чем это необходимо, потому что, когда они становятся действительно устаревшими, они могут вызвать головные боли.
Emk

822

Если у вас есть много удаленных веток, которые вы хотите получить сразу, выполните:

$ git pull --all

Теперь вы можете оформить любую ветку, как вам нужно, не обращаясь к удаленному хранилищу.


12
Если я делаю git clone, у меня есть ветка master и 10 веток "remote". Таким образом, этот ответ Гейба был очень полезным и отвечает на вопрос.
basZero

38
это только выборка удаленных филиалов , которые были локально добавлены не какой - либо удаленный филиал
jujule

33
Первая команда избыточна. Просто git pull --allсделаю то же самое - просто не получу дважды. И Infosec812 прав, что это не отвечает на вопрос в любом случае. Интересно, как это вызвало столько голосов.
Свен Марнах

6
После того, как я сделал git remote update, а затем попытался git branch, я вижу только местные филиалы. Но если я это сделаю, git branch -aто теперь я вижу удаленные ветви и могу git pull <branchname>получить нужную ветку. - Я попал на этот вопрос из поиска Google, и этот ответ решает мою проблему.
WNRosenberg

38
Это совсем не полезно, не тянет никакие удаленные ветви кроме существующих.
Avinash R

446

Этот скрипт Bash помог мне:

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

Он создаст ветви отслеживания для всех удаленных ветвей, кроме главной (которую вы, вероятно, получили из исходной команды клона). Я думаю, вам все еще нужно сделать

git fetch --all
git pull --all

чтобы быть уверенным.

Один лайнер : 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
Как обычно: протестируйте в своей настройке перед копированием rm -rf Universe, как мы его знаем

Кредиты на однострочник переходят на пользователя cfi


19
Это очень близко к идеальному решению. Единственное, что могло бы сделать его лучше, это если бы эта функция была встроена как опция в git.
Девен Филлипс

51
«Один вкладыш»: 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 как обычно: протестируйте в своей настройке перед копированиемrm -rf universe as we know it
cfi

4
Эта команда создает ветви функций из удаленных как обычные ветви (не ветви функций) - как это исправить?
Alex2php

4
если вы столкнулись с проблемами с "/" в именах веток, есть решение ниже с использованием псевдонима git. см. ответ "никто" на "ответил 15 мая 13 в 11:02"
wemu

8
Я remotes/origin/for BRANCH in $(git branch -a | grep remotes | grep -v HEAD | grep -v master); do git branch --track "${BRANCH#remotes/origin/}" "${BRANCH}"; done
обрезаю

348

Использование этой --mirrorопции позволяет правильно копировать remoteветви отслеживания. Тем не менее, он устанавливает репозиторий как пустой репозиторий, поэтому вам придется впоследствии превратить его в обычный репозиторий.

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

Ссылка: Git FAQ: Как мне клонировать репозиторий со всеми удаленно отслеживаемыми ветками?


7
Вы знаете, что это действительно хороший ответ, хотя у него нет голосов. Есть ли подводные камни, чтобы сделать это таким образом? Я должен был явно оформить ветку после выполнения этих команд.
цикл

27
Это в сочетании с git push --mirror - это как раз то, что мне нужно для создания точной копии удаленного git-репо при переходе с github.com к установке github для предприятий. Спасибо!
Джейкоб Фике

3
@Dave: добавьте git checkoutпоследнюю команду в качестве последней для окончательной проверки заголовка текущей ветви в клонированном репо. Это отличный ответ, безусловно, лучший. Будь храбрым, в конце концов мы доберемся до вершины :-)
Cfi

3
@Dave: Хм. У меня вторые мысли: --mirror делает больше, чем просто настраивает отслеживание всех веток. Он копирует все ссылки из источника и последующие git remote updateбудут делать это снова. Поведение тяги меняется. Я снова верю, что полная копия требует однострочного сценария.
Cfi

5
git clone --mirrorочень хорошо подходит для резервного копирования ваших репозиториев git ^ _ ^
TrinitronX

220

Вы можете легко переключиться на ветку, не используя причудливый синтаксис "git checkout -b somebranch origin / somebranch". Вы можете просто сделать:

git checkout somebranch

Git автоматически сделает правильные вещи:

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

Git проверит, существует ли ветвь с тем же именем на одном удаленном сервере, и если это так, он отслеживает ее так же, как если бы вы явно указали, что это удаленная ветвь. Из справочной страницы git-checkout Git 1.8.2.1:

Если <branch> не найден, но существует отслеживающая ветвь ровно в одном удаленном (называемом <remote>) с соответствующим именем, обрабатывать как эквивалент

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

1
Итак, если имя вашей ветки checkoutсовпадает с именем удаленной ветки, все после «/», то git создаст ветку с тем же именем, все после «/», «отслеживания» этого удаленного ? И слежения, мы имеем в виду: git push, git pullи т.д. , будет сделано на этом пульте дистанционного управления? Если это правильно, то добавьте в свой ответ больше информации, потому что я согласен с @Daniel, этот ответ заслуживает большего количества повторений.
Жерар Рош

5
@BullfrogBlues, ответ на все ваши вопросы, кажется, да (я использую git v1.7.7.4). Я согласен, что это поведение должно быть лучше известно. (Это не в руководстве для этой версии git.) Мне на самом деле не нравится это поведение, я предпочел бы получить ошибку и должен сказать git checkout --track origin/somebranchпрямо.
dubiousjim

3
@dubiousjim: На самом деле, это в руководстве. git-checkout (1) говорит: «Если <branch> не найден, но существует отслеживающая ветвь ровно в одном удаленном (называемом <remote>) с подходящим именем, обрабатывать как эквивалент 'git checkout -b <branch > --track <remote> / <branch> '"(Git V.1.8.1.1).
Слёске

Нам нужно $ git pull * <remote> / * - где «*» - это подстановочный знак, поэтому он вытягивает все ветви, включая те, которые еще не находятся в локальной системе. Как это сделать? Мы действительно должны проверять / извлекать каждую ветку только для того, чтобы получить код для нашей локальной системы?
JosephK

98

Что касается,

$ git checkout -b экспериментальное происхождение / экспериментальное

с помощью

$ git checkout -t origin/experimental

или более многословный, но легче запомнить

$ git checkout --track origin/experimental

может быть лучше, с точки зрения отслеживания удаленного хранилища.


То есть вы имеете в виду, что вторую форму легче запомнить, а другой разницы нет?
aderchox

79

Выборка, которую вы делаете, должна получить все удаленные ветви, но она не создаст для них локальные ветви. Если вы используете gitk, вы должны увидеть удаленные ветви, описанные как «remotes / origin / dev» или что-то подобное.

Чтобы создать локальную ветку на основе удаленной ветки, сделайте что-то вроде:

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

Который должен вернуть что-то вроде:

Ветвь dev настроена для отслеживания удаленных веток refs / remotes / origin / dev.
Перешел на новую ветку "dev"

Теперь, когда вы находитесь в ветке dev, "git pull" обновит ваш локальный dev до той же точки, что и удаленная ветка dev. Обратите внимание, что он выберет все ветви, но потянет только ту, на которой вы находитесь, на вершину дерева.


14
Вам не нужны ссылки / пульты здесь. git checkout -b dev origin / dev будет работать нормально.
Емк

3
Это всегда будет работать git checkout -b newlocaldev --track origin/dev. Если вы хотите, чтобы локальная ветвь имела то же имя, что и удаленная, а удаленная не имеет хитрого имени, вы можете опустить -b newlocaldev. При настройке branch.autosetupmergeконфигурации по умолчанию и при условии, что у вас нет локальной ветви dev, эти две команды могут делать одно git checkout -b dev origin/devи то же: и просто git checkout dev. Наконец, git checkout origin/devне создает новую ветку, а просто переводит вас в отключенное состояние HEAD.
dubiousjim

Что происходит, когда пульт больше не существует, но Git слишком глуп, чтобы признать, что он удален? Предполагается, что вы обновили и git branch -aпродолжает перечислять его как удаленную ветвь.
1916

И мы делаем это для десятков филиалов?
JosephK

59

Когда вы делаете «git clone git: // location», все ветки и теги выбираются.

Чтобы работать поверх определенной удаленной ветви, предполагая, что это удаленный источник:

git checkout -b branch origin/branchname

2
Я ценю вашу заметку "все ветки и теги извлечены". Я собирался прокомментировать ваш ответ, который был неправильным, но потом я проверил его и обнаружил, что вы совершенно правы. Таким образом, вы дали самый короткий ответ - если вы клонировали, у вас уже есть. Ницца. Можно попытаться добавить: попытаться $ git branch -aузнать, какие удаленные филиалы уже доступны.
Ян Влчинский

Посмотрите на ответ, который я опубликовал. Это может быть полезно, если вы знаете, что хотите работать локально во многих удаленных филиалах и вам не нужно проверять их по одному.
lacostenycoder

Можете ли вы объяснить мне, в чем разница git checkout -b master origin/masterи git checkout --track origin/masterпожалуйста?
aderchox

1
@aderchox В настоящее время я думаю, что нет.
Эльмарко

58

Используйте псевдонимы. Хотя в Git нет ни одной нативной строки, вы можете определить свою собственную как

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

а затем использовать его как

git clone-branches

Спасибо. Это фактически клонирует все удаленные ветви в отличие от некоторых других ответов
FearlessHyena

50

Почему вы видите только «мастер»

git cloneзагружает все удаленные ветви, но все еще считает их «удаленными», даже если файлы находятся в вашем новом хранилище. Есть одно исключение, которое заключается в том, что процесс клонирования создает локальную ветвь с именем "master" из удаленной ветки с именем "master". По умолчанию git branchотображаются только локальные ветви, поэтому вы видите только «master».

git branch -aпоказывает все ветви, в том числе удаленные .


Как получить местные филиалы

Если вы действительно хотите работать с веткой, вам, вероятно, понадобится ее «локальная» версия. Чтобы просто создать локальные ветки из удаленных ветвей (не проверяя их и, тем самым, не изменяя содержимое вашего рабочего каталога) , вы можете сделать это следующим образом:

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

В этом примере branchoneэто имя локальной ветви, на основе которой вы создаете origin/branchone; если вместо этого вы хотите создать локальные ветви с разными именами, вы можете сделать это:

git branch localbranchname origin/branchone

Как только вы создали локальную ветку, вы можете увидеть ее с помощью git branch(помните, вам не нужно -aвидеть локальные ветви).


Если origin/branchoneсуществует, вы также можете просто использовать git checkout branchoneдля создания локальной ветки с тем же именем и установить его для отслеживания удаленного.
Эван

47

Это не слишком сложно, очень простые и понятные шаги заключаются в следующем;

git fetch origin Это приведет все удаленные филиалы к вашему локальному.

git branch -a Это покажет вам все удаленные ветви.

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

Проверьте, находитесь ли вы в нужной ветке, с помощью следующей команды;

git branch

Вывод понравится;

*your current branch 
some branch2
some branch3 

Обратите внимание на знак *, который обозначает текущую ветвь.


1
Спасибо, Сурадж. Причина, потому что его не было проголосовано много. И ответ не принимается спрашивающим.
Сэм

«Происхождение git fetch» ​​не принесло ни одной из удаленных веток в мой локальный каталог - или они где-то спрятаны? Чтение всех ответов выше доставило мне головную боль. Мы ищем "git доставить все ветки на локальные". Для этого должен быть способ, кроме bash-скриптов.
JosephK

1
Сразу после того, как вы выполните «git fetch origin», в вашем терминале будет отображаться вывод, подобный этому: «* [new branch] branch_name -> origin / branch_name», но когда вы запустите «git branch», он покажет вам только ваш локальный вместо этого вместо ветвей, чтобы увидеть все ветви, вы можете выполнить «git branch -a», а затем переключиться на удаленную ветку, вам нужно запустить «git checkout --track origin / <branch, которую вы хотите оформить>». Надеюсь это поможет. :-)
Сэм

4
Сурадж, потому что вопрос был в том, как «клонировать все удаленные ветви», а не в том, как вручную обновлять по одному. Похоже, нет ответа на реальный вопрос - просто способы много печатать, если у вас много веток.
JosephK

47

Лучше поздно, чем никогда, но вот лучший способ сделать это:

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

На данный момент у вас есть полная копия удаленного репо со всеми его ветками (проверьте с помощью git branch). Вы можете использовать --mirrorвместо, --bareесли ваше удаленное репо имеет свои собственные пульты.


Что-то пошло не так во время редактирования здесь. Теперь этот ответ не имеет смысла. « --bare», Упомянутое в последнем предложении, не существует в данном списке команд.
Серран

принимая от Дейва ответ ниже. Использование 'git config --bool core.bare false' вместо 'git config unset core.bare', кажется, делает эту работу.
растерянный ворлонец

У меня есть error: key does not contain a section: unset. В ответ Дейва работает лучше.
olibre

Это на git config --unset core.bareсамом деле ... Мне кажется, это самое чистое решение из всех представленных здесь в ответах. Жаль, что у него так мало голосов ...
Дирк Хиллбрехт

1
Спасибо @ChrisSim, я согласен git config --bool core.bare false. Вот почему я рекомендую вместо Дейва ответ . Что вы думаете об ответе Дейва ? Приветствия
olibre

39

Просто сделай это:

$ 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

Вы видите, «git clone git: //example.com/myprojectt» извлекает все, даже ветви, вам просто нужно оформить их, тогда будет создана ваша локальная ветка.


25

Вам нужно всего лишь использовать "git clone", чтобы получить все ветки.

git clone <your_http_url>

Даже если вы видите только главную ветку, вы можете использовать «git branch -a», чтобы увидеть все ветви.

git branch -a

И вы можете переключиться на любую ветку, которая у вас уже есть.

git checkout <your_branch_name>

Не беспокойтесь, что после «git clone» вам не нужно подключаться к удаленному репо, «git branch -a» и «git checkout» могут быть успешно запущены при закрытии вашего wifi. Итак, доказано, что когда вы делаете «git clone», он уже скопировал все ветви из удаленного репо. После этого вам не нужно удаленное репо, ваш локальный уже имеет коды всех филиалов.


Очень четкий ответ здесь. Многие люди запутались в этой теме.
XMAN

Я хотел бы подтвердить ваше заявление "может быть успешно запущен, когда вы закрываете свой Wi-Fi". «git clone» действительно приводит к репо, содержащему все ветви.
bvgheluwe

Отличный четкий прямой ответ.
Амр

24

git cloneПредполагается скопировать весь репозиторий. Попробуйте клонировать его, а затем запустите git branch -a. Следует перечислить все ветви. Если затем вы хотите переключиться на ветку "foo" вместо "master", используйте git checkout foo.


1
Вы можете запускать команды git с дефисом или без него. Оба "git-branch" и "git branch" будут работать.
Питер Боутон

21
Возможно, этот ответ был дан давным-давно, когда git работал по-другому, но я думаю, что он вводит в заблуждение сегодня. git cloneзагружает все удаленные ветки, но делает только локальную ветку master. Так как git branchпоказывает только локальные ветви, вам также нужно git branch -aвидеть удаленные ветви.
Серран

Спасибо. Это своего рода странное поведение по умолчанию IMO. Я просто приписываю это мелочам. Если он скачал ветки, почему он скрывал их при вызове git branch?
Адам Хьюз

1
@Cerran, спасибо; Я обновил свой ответ соответственно.
MattoxBeckman

msgstr "загружает все удалённые ветки, но делает только локальную ветку master". Мне нужна помощь, чтобы понять это. Похоже, что git clone НЕ клонирует никакие ветки, кроме master, так как когда вы делаете "git branch -a", это показывает, что ветвь "development" находится только в "remotes / origin / development". Должно быть, это говорит о том, что у вас нет этой ветки где-либо локально, она существует только в настоящее время, верно?
Джон Литтл

19

Используйте мой инструмент git_remote_branch (вам нужен Ruby, установленный на вашем компьютере). Он создан специально для упрощения работы с удаленными ветвями.

Каждый раз, когда он выполняет операцию от вашего имени, он печатает ее красным на консоли. Со временем они наконец втыкаются в ваш мозг :-)

Если вы не хотите, чтобы grb запускал команды от вашего имени, просто используйте функцию объяснения. Команды будут напечатаны на вашей консоли, а не выполнены для вас.

Наконец, все команды имеют псевдонимы для упрощения запоминания.

Обратите внимание, что это альфа-программа ;-)

Вот справка, когда вы запускаете grb help:

git_remote_branch версия 0.2.6

  Применение:

  grb создать имя_в ветви [origin_server] 

  grb publish branch_name [origin_server] 

  GRB переименовать имя_расхода [origin_server] 

  grb удалить имя_власти [origin_server] 

  GRB-трек имя_сервера [origin_server] 



  Ноты:
  - Если origin_server не указан, предполагается, что имя 'origin' 
    (Git по умолчанию)
  - Функция переименования переименовывает текущую ветку

  Мета-команда объяснения: вы также можете добавить любую команду с помощью 
Ключевое слово «объяснить». Вместо выполнения команды, git_remote_branch
просто выведет список команд, которые нужно выполнить для выполнения 
эта цель.

  Пример: 
    грб объяснить создать
    GRB объяснить создать my_branch GitHub

  Все команды также имеют псевдонимы:
  создать: создать, новый
  удалить: удалить, уничтожить, убить, удалить, RM
  публиковать: публиковать, remotize
  переименовать: переименовать, рн, мв, двигаться
  отслеживать: отслеживать, следовать, захватить, получить

6
Слово мудрому: похоже, этот проект был заброшен примерно во время публикации этого ответа. Я не могу найти никаких обновлений после 2008 года. Будьте бдительны и все такое. Если я ошибаюсь, я надеюсь, что кто-то отредактирует и предоставит текущий указатель, потому что я хотел бы иметь такой удобный инструмент.
Bradheintz

@bradheintz проверьте этот ответ, он создает псевдоним git: stackoverflow.com/a/16563327/151841
user151841

19

все ответы, которые я видел здесь, верны, но есть гораздо более чистый способ клонировать репозиторий и вытащить все ветви одновременно.

Когда вы клонируете репозиторий, вся информация о ветвях фактически загружается, но ветви скрыты. С помощью команды

$ git branch -a

Вы можете показать все ветви хранилища, и с помощью команды

$ git checkout -b branchname origin/branchname

затем вы можете «загрузить» их вручную по одному.


Однако, когда вы хотите клонировать репо с большим количеством веток, все вышеприведенные способы являются длительными и утомительными в отношении гораздо более чистого и быстрого способа, который я собираюсь показать, хотя это немного сложно. Вам нужно три шага для этого:

  1. Первый шаг

создайте новую пустую папку на своем компьютере и клонируйте зеркальную копию папки .git из репозитория:

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

Локальный репозиторий внутри папки my_repo_folder по-прежнему пуст, теперь есть только скрытая папка .git, которую вы можете увидеть с помощью команды «ls -alt» из терминала.

  1. Второй шаг

переключите этот репозиторий из пустого (пустого) репозитория в обычный репозиторий, переключив логическое значение «bare» конфигурации git на false:

$ git config --bool core.bare false
  1. Третий шаг

Возьмите все, что находится внутри текущей папки, и создайте все ветви на локальном компьютере, поэтому сделайте это обычным репо.

$ git reset --hard

Теперь вы можете просто набрать команду «git branch» и увидеть, что все ветви загружены.

Это быстрый способ, которым вы можете клонировать git-репозиторий со всеми ветками одновременно, но это не то, что вы хотите сделать для каждого отдельного проекта таким образом.


Мне не нравится, когда вы используете слово «скачать» в ... «скачивать» их вручную по одному . Фактически, вся информация уже загружена после клонирования репо. Единственное, что нужно сделать, - это создать локальные ветви отслеживания (что также возможно в автономном режиме, что доказывает, что вся информация находится в репо).
bvgheluwe

@bvgheluwe, поэтому в кавычках.
Федерико

15

Клонирование из локального репозитория не будет работать с git clone и git fetch: многие ветви / теги останутся незатронутыми.

Получить клон со всеми ветками и тегами.

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

Чтобы получить клон со всеми ветками и тегами, а также с рабочей копией:

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

Хорошо, когда вы клонируете репо, у вас там есть все филиалы ...

Если вы просто делаете git branch, они как бы скрыты ...

Так что, если вы хотите увидеть название всех веток, просто добавьте --allфлаг следующим образом:

git branch --all или git branch -a

Если вы просто оформите заказ в филиале, вы получите все, что вам нужно.

Но как быть, если ветка, созданная кем-то другим после вас, клонируется?

В этом случае просто сделайте:

git fetch

и проверьте все ветви снова ...

Если вы хотите получить и оформить заказ одновременно, вы можете сделать:

git fetch && git checkout your_branch_name

Также создал изображение ниже для вас, чтобы упростить то, что я сказал:

git branch - все ветки получить


3
Есть разница между «у вас есть» и «вы видите это». git branch -all НЕ будет перечислять удаленные ветви больше, когда вы удаляете удаленный репозиторий.
Гюстав

12

Глядя на один из ответов на вопрос, я заметил, что его можно сократить:

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

Но будьте осторожны, если одна из удаленных веток называется, например, admin_master, она не будет загружена!

Спасибо Bigfish за оригинальную идею


Вы можете улучшить регулярное выражение или использовать вместо него Awk grep, чтобы улучшить фильтр, чтобы избежать ложных срабатываний.
tripleee

все ветки являются «origin \ my_branch_name», что не совсем то, что я хочу.
Sнаđошƒаӽ

Я раньше не видел конструкцию $ {branch ## * /} - выглядит действительно полезной - есть идеи, где я могу узнать больше об этом? кажется, нигде не найти под Bash. Спасибо.
SaminOz


10

Для копирования-вставки в командную строку:

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

Для большей читаемости:

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


Это будет:

  1. проверьте мастер (чтобы мы могли удалить ветку, в которой мы находимся)
  2. выберите пульт, чтобы оформить заказ (замените его на тот, который у вас есть)
  3. цикл по всем веткам пульта, кроме master и HEAD
    1. удалить локальную ветку (чтобы мы могли проверить принудительно обновленные ветки)
    2. проверить ветку с пульта
  4. проверить мастер (ради этого)

На основании ответа на VonC .


10

Я написал эти небольшие функции Powershell, чтобы иметь возможность извлекать все мои ветки git, которые находятся на удаленном сервере.

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>' #>
}

Больше функций git можно найти в моем репозитории git settings


9

Вот ответ, который использует awk. Этого метода должно быть достаточно, если он используется в новом репо.

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

Существующие ветки будут просто извлечены или объявлены как уже в нем, но фильтры могут быть добавлены, чтобы избежать конфликтов.

Он также может быть изменен, поэтому он вызывает явное git checkout -b <branch> -t <remote>/<branch> команду.

Этот ответ следует Никос C. «s идея .


В качестве альтернативы мы можем указать удаленную ветку. Это основано на murphytalk «s ответ .

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

Он генерирует фатальные сообщения об ошибках при конфликтах, но я вижу их безвредными.


Обе команды могут быть псевдонимами.

Используя чей -либо ответ в качестве ссылки, мы можем использовать следующие команды для создания псевдонимов:

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) }"'

Лично я бы использовал track-allили track-all-branches.


Просто хотел поблагодарить вас. Это сработало отлично, и оно не страдает от различных проблем, связанных с клонированием голого репо, таких как изменение поведения при подтягивании и т. Д.
mahonya

8

Мне нужно было сделать то же самое. Вот мой скрипт на 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]

Смотрите ответ, который я разместил ниже, чтобы вообще не запускать этот скрипт.
lacostenycoder

8

Ни один из этих ответов не урезал его, кроме того, что никто не находится на правильном пути.

У меня были проблемы с перемещением репо с одного сервера / системы на другой. Когда я клонировал репозиторий, он только создавал локальную ветвь для мастера, поэтому, когда я отправлялся на новый удаленный сервер, была перемещена только основная ветвь.

Таким образом, я нашел эти два метода очень полезными. Надеюсь, они помогут кому-то еще.

Способ 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

Способ 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 на оригинальном репо хорошо для этого работает.

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

7

Git обычно (если не указан) извлекает все ветви и / или теги (ссылки, см .:) git ls-refsиз одного или нескольких других хранилищ вместе с объектами, необходимыми для завершения их истории. Другими словами, он выбирает объекты, которые доступны объектам, которые уже загружены. Смотрите: что на git fetchсамом деле делает?

Иногда у вас могут быть ветки / теги, которые не связаны напрямую с текущим, поэтому git pull --all/ git fetch --allне помогут в этом случае, но вы можете перечислить их следующим образом:

git ls-remote -h -t origin

и получить их вручную, зная имена ссылок.

Итак, чтобы получить их все , попробуйте:

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

--depth=10000Параметр может помочь , если вы обмелевшее хранилищу.

Затем проверьте все свои ветви снова:

git branch -avv

Если вышеприведенное не поможет, вам нужно вручную добавить недостающие ветви в отслеживаемый список (так как они как-то потерялись):

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

по git remote set-branchesкак:

git remote set-branches --add origin missing_branch

поэтому он может появиться remotes/originпосле выборки:

$ 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

Поиск проблемы

Если вы все еще не можете получить ничего, кроме основной ветки, проверьте следующее:

  • Дважды проверьте ваши пульты ( git remote -v), например
    • Проверка , что git config branch.master.remoteесть origin.
    • Проверьте, если originуказывает на правильный URL через: git remote show origin(см. Этот пост ).

7

По состоянию на начало 2017 года ответ в этом комментарии работает:

git fetch <origin-name> <branch-name>приносит ветку для вас. Хотя это не вытягивает все ветви одновременно, вы можете выполнить эту ветку отдельно.


Это требует, чтобы вы выбирали каждую ветку по одному. Не очень хорошо, если у вас много филиалов.
lacostenycoder

6

Вот еще одна короткая однострочная команда, которая создает локальные ветви для всех удаленных ветвей:

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

Это работает также правильно, если отслеживание локальных филиалов уже создано. Вы можете позвонить после первого git cloneили в любое время позже.

Если вам не нужно masterпроверять ветку после клонирования, используйте

git branch -r | sed -n '/->/!s#^  origin/##p'| xargs -L1 git checkout
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.