Як клонувати всі віддалені гілки в Git?


4129

У мене є 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
Мене завжди хизує, чому "клон" не є в значенні точної копії. Якщо це точний клон, чи не повинні всі гілки бути частиною локального сховища? Я маю на увазі, чи не це одна з точок розповсюдження? Тож, коли щось сховане, у вас все ще є повна копія всього. Або це так звані "віддалені" насправді вже є частиною локального сховища?
huggie

21
Побачивши всі відгуки, відповіді, коментарі до відповідей та привабливу кількість поглядів, я думаю, що настав час git додати команду для цього. І правильно ти @huggie, мої думки точно.
Snađошƒаӽ

Відповіді:


4557

Спочатку клонуйте віддалений сховище Git і введіть його в CD :

$ 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

Якщо ви просто хочете зазирнути у верхню гілку, ви можете перевірити це безпосередньо:

$ 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> <name_name>" приводить гілку локально для вас.

137
Гарна відповідь, але начебто не вистачає питання. Я шукав однолінійку, щоб перевірити всі віддалені гілки.
cmcginty

32
Питання стосувалося клонування всіх віддалених гілок, а не перевірки їх. І, як я вже зазначав вище, ви дійсно не хочете робити більше локальних гілок відстеження, ніж потрібно, тому що, коли вони дійсно застаріли, вони можуть викликати головні болі.
emk

822

Якщо у вас є багато віддалених гілок, які ви хочете отримати одразу, зробіть:

$ git pull --all

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


12
Якщо я роблю git clone, я маю головну гілку локально і 10 гілок "віддалені". Тож ця відповідь Габе була дуже корисною та відповідає на питання.
basZero

38
це лише отримання віддалених гілок, які локально додали не будь-яку віддалену гілку
липня 12

33
Перша команда є зайвою. Просто git pull --allзробимо те саме - він просто не вийде двічі. І infosec812 має рацію, що це ніяк не відповідає на питання. Цікаво, як це отримало так багато відгуків.
Свен Марнах

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

38
Це зовсім не корисно, не тягне за собою будь-які віддалені гілки, крім існуючих.
Avinash R

446

Цей сценарій Баша мені допоміг:

#!/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 всесвіту, як ми це знаємо

Кредити для однолінійки переходять на користувальницький файл 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 травня
1313

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
kgadek

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 repo при переході від github.com до встановлення підприємства github. Дякую!
Яків Фіке

3
@Dave: Додайте остаточну git checkoutкоманду як останню команду, щоб остаточно перевірити голову поточної гілки на клонованому репо. Це чудова відповідь, безумовно, найкраща. Будьте сміливі, врешті-решт ми
підведемо

3
@Dave: Гм. У мене є другі думки: - помилка робить більше, ніж просто налаштовувати всі гілки як відстежені. Він копіює всі посилання з походження, і наступні 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прямо.
сумнівним

3
@dubiousjim: Насправді це є в посібнику. git-checkout (1) говорить: "Якщо <branch> не знайдено, але існує гілка відстеження точно в одному віддаленому (назвіть його <remote>) із відповідним ім'ям, вважайте це еквівалентом" git checkout -b <branch > - трек <remote> / <branch> '"(Git V.1.8.1.1).
sleske

Нам потрібно $ git pull * <remote> / * - де "*" - це майна, тому вона витягує всі гілки, включаючи ще не локальну систему. Як це зробити? Ми дійсно повинні перевірити / витягнути кожну гілку лише для того, щоб код перейшов до нашої локальної системи?
ДжозефК

98

Щодо,

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

використовуючи

$ git checkout -t origin/experimental

або більш багатослівне, але простіше запам’ятати

$ git checkout --track origin/experimental

може бути краще, що стосується відстеження віддаленого сховища.


Отже, ви маєте на увазі, що другу форму запам'ятовувати лише простіше, і різниці немає?
aderchox

79

Вибір, який ви робите, має отримати всі віддалені гілки, але це не створить для них локальні гілки. Якщо ви використовуєте gitk, ви повинні побачити віддалені гілки, описані як "видалення / походження / dev" або щось подібне.

Щоб створити локальну гілку на основі віддаленої гілки, зробіть щось на кшталт:

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

Що має повернути щось на кшталт:

Розробник відділення налаштовано для відстеження віддалених відхилень відділення / віддалених / походження / dev
Переключився на нову гілку "dev"

Тепер, коли ви перебуваєте на гілці розробників, "git pull" оновить ваш локальний розробник до тієї ж точки, що й віддалена гілка розробників. Зауважте, що вона отримає всі гілки, але лише тягніть ту, на якій ви знаходитесь, на верхівку дерева.


14
Тут вам не потрібні відповідні / віддалені послуги. git checkout -b dev origin / dev буде добре працювати.
emk

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.
сумнівним

Що відбувається, коли пульта більше не існує, але Git занадто дурний, щоб визнати його видаленим? Це передбачає, що ви оновили та git branch -aпродовжуєте перелічувати його як віддалену гілку.
jww

І ми це робимо для десятків філій?
ДжозефК

59

Коли ви робите "git clone git: // location", всі гілки та теги отримуються.

Щоб працювати над певною віддаленою гілкою, припускаючи, що це віддалене походження:

git checkout -b branch origin/branchname

2
Дякую Вашій записці "всі гілки та теги отримані". Я збирався прокоментувати вашу неправильну відповідь, але потім я перевірив її і виявив, що ви абсолютно праві. Отже, ви певним чином надали найкоротшу відповідь - якщо ви клонувались, у вас її вже є. Приємно. Можна спробувати додати: спробуйте $ git branch -aдізнатися, які віддалені гілки вже доступні.
Ян Вльчинський

Подивіться також на відповідь, яку я опублікував. Це може бути корисним, якщо ви знаєте, що хочете працювати локально на багатьох віддалених гілках і не потрібно перевіряти їх по черзі.
лакостенікодер

Чи можете ви пояснити мені, в чому різниця між git checkout -b master origin/masterі git checkout --track origin/masterбудь ласка?
aderchox

1
@aderchox Сьогодні я думаю, що ніхто.
elmarco

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відображаються лише локальні гілки, тому ви бачите лише "майстер".

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 fetch all branch to local". Для цього повинен бути спосіб окрім bash-скриптів.
ДжозефК

1
Одразу після того, як ви виконаєте "git fetch origin", він покаже такий висновок у вашому терміналі - "* [нова гілка] гілка_назви -> походження / ім'я гілки", але коли ви запустите "гіт гілки", вона покаже лише ваш локальний гілки, натомість, щоб побачити всі гілки, ви можете зробити "git branch -a", а потім для переходу до віддаленої гілки вам потрібно запустити "git checkout - трек походження / <гілка, яку ви хочете оформити>". Сподіваюсь, це допомагає. :-)
Сем

4
Suraj, адже питання полягало в тому, як "клонувати всі віддалені гілки" - а не як вручну оновлювати одну за одною. Здається, немає відповіді на власне запитання - лише способи зробити цілу масу набору тексту, якщо у вас багато гілок.
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. Відповідь Дейва працює краще.
олібре

Це git config --unset core.bareнасправді ... Мені це здається найчистішим рішенням усіх представлених тут відповідей. Шкода, що в ньому так мало відгуків ...
Дірк Хіллбрехт

1
Дякую @ChrisSim Я згоден git config --bool core.bare false. Ось чому я рекомендую натомість відповідь Дейва . Що ви думаєте про відповідь Дейва ? Ура
олібре

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

Я хотів би другий ваш вислів "може бути запущений успішно, коли ви закриєте свій wifi". "клон git" дійсно призводить до репо, що містить усі гілки.
bvgheluwe

Чудова чітка відверта відповідь.
Amr

24

A git cloneповинен скопіювати весь сховище. Спробуйте його клонувати, а потім запустіть git branch -a. У ньому повинні бути перелічені всі гілки. Якщо тоді ви хочете перейти до гілки "foo" замість "master", використовуйте git checkout foo.


1
Ви можете запускати команди git із дефісом або без нього. Працюватимуть і "git-гілка", і "гіт-гілка".
Пітер Бауфтон

21
Можливо, цю відповідь було дано давно, коли git працював по-іншому, але я думаю, це сьогодні вводить в оману. git cloneзавантажує всі віддалені гілки, але це робить лише локальна гілка майстра. Оскільки git branchвідображаються лише локальні гілки, вам потрібно git branch -aбачити і віддалені гілки.
Серран

Дякую. Це своєрідна поведінка IMO за замовчуванням. Я просто змалюю це до більшої дурості. Якщо він завантажував гілки, навіщо їх ховати при виклику гілки git?
Адам Х'юз

1
@Cerran, спасибі; Я відповідно оновив свою відповідь.
MattoxBeckman

"завантажує всі віддалені гілки, але це лише робить локальну гілку". Мені потрібна допомога в розумінні цього. Здається, клон git НЕ клонує жодних гілок, крім головного, тому що, коли ви робите "git гілка -a", це показує, що гілка "розвивати" є лише на "віддалено / походження / розвиток". Це, мабуть, говорить про те, що ви не маєте цієї гілки в будь-якому місці локально, вона існує лише зараз на праві походження?
Джон Малий

19

Використовуйте мій інструмент git_remote_branch (на вашій машині потрібно встановити Ruby). Він створений спеціально для полегшення маніпуляцій із віддаленими гілками.

Кожен раз, коли він робить операцію від вашого імені, він друкує червоним кольором на консолі. З часом вони нарешті впираються у ваш мозок :-)

Якщо ви не хочете, щоб grb запускав команди від вашого імені, просто скористайтеся функцією "пояснити". Команди будуть надруковані на вашу консоль, а не виконані для вас.

Нарешті, всі команди мають псевдоніми, щоб полегшити запам'ятовування.

Зауважте, що це альфа-програмне забезпечення ;-)

Ось допомога під час запуску довідки з GRB:

git_remote_branch версія 0.2.6

  Використання:

  grb створити ім'я гілки [origin_server] 

  grb опублікувати ім'я гілки [вихідний_сервер] 

  grb перейменувати ім'я гілки [origin_server] 

  grb видалити ім'я гілки [origin_server] 

  grb track track_name [origin_server] 



  Примітки:
  - Якщо origin_server не вказано, передбачається ім'я "origin" 
    (за замовчуванням git)
  - Функція перейменування перейменовує поточну гілку

  Мета-команда пояснення: ви також можете додати будь-яку команду до 
ключове слово 'пояснити'. Замість виконання команди, git_remote_branch
просто виведе список команд, які потрібно виконати для виконання 
та мета.

  Приклад: 
    grb пояснити створення
    grb пояснити створення my_branch github

  Усі команди також мають псевдоніми:
  творити: творити, новий
  delete: видалити, знищити, вбити, видалити, rm
  публікувати: публікувати, віддаляти
  перейменувати: перейменувати, rn, mv, перемістити
  трек: слідкувати, слідкувати, захоплювати, виносити

6
Слово для мудрих: Схоже, цей проект був припинений у той час, коли ця відповідь була розміщена. Я не можу знайти жодних оновлень після 2008 року. Caveat emptor і все це. Якщо я помиляюся, я сподіваюся, що хтось відредагує та надасть поточний вказівник, тому що я хотів би мати такий інструмент, як цей підручний.
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. Другий крок

переключити це сховище з порожнього (голого) сховища в звичайне сховище, перемикаючи булеве значення "голі" конфігурацій git на хибне:

$ git config --bool core.bare false
  1. Третій крок

Візьміть усе, що знаходиться у поточній папці, і створіть усі гілки на локальній машині, тому зробимо це нормальним репо.

$ git reset --hard

Отже, тепер ви можете просто ввести команду "git гілка", і ви можете побачити, що всі гілки завантажені.

Це швидкий спосіб, за допомогою якого ви можете клонувати сховище git з усіма гілками одночасно, але це не те, що ви хочете зробити для кожного окремого проекту таким чином.


Мені не подобається, що ви вживаєте слово "скачати" в ... "завантажуйте" їх вручну по одному . Фактично вся інформація вже завантажена після клонування репо. Єдине, що потрібно зробити - це створити локальні гілки відстеження (що також можливо в режимі офлайн, що доводить, що вся інформація знаходиться в репо-репо).
bvgheluwe

@bvgheluwe тому це в лапках.
FedericoCapaldo

15

Клонування з локального репо не буде працювати з клоном git & 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", що точно не є тим, що я хочу.
Snađошƒаӽ

Я раніше не бачив конструкцію $ {branch ## * /} - виглядає дуже корисною - будь-яка ідея, де я можу дізнатися більше про це? не можу знайти десь під басом. Дякую.
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. пройдіть через усі гілки дистанційного, крім головного та 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


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]

Дивіться відповідь, яку я розмістив далі вниз, щоб уникнути необхідності запускати цей сценарій.
лакостенікодер

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 зазвичай (якщо не вказано) витягує всі гілки та / або теги (refs, див.:) 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>зводить гілку за вас. Хоча це не витягує всі гілки одразу, ви можете синхронно виконати цю гілку.


Це вимагає, щоб ви отримували кожну гілку по одній. Не дуже добре, якщо у вас багато гілок.
лакостенікодер

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.