Отслеживайте все удаленные Git-ветки как локальные
Отслеживание одной удаленной ветви как локальной ветви достаточно просто.
$ git checkout --track -b ${branch_name} origin/${branch_name}
Перетаскивание всех локальных ветвей до удаленного, создание новых удаленных ветвей по мере необходимости также легко.
$ git push --all origin
Я хочу сделать наоборот. Если у меня есть X количество удаленных веток в одном источнике:
$ git branch -r
branch1
branch2
branch3
.
.
.
Могу ли я создать локальные ветви отслеживания для всех этих удаленных веток без необходимости их создания вручную? Скажите что-то вроде:
$ git checkout --track -b --all origin
Я гуглил и RTM, но дошел до настоящего времени.
16 ответов
Используя bash:
после мерзавца 1.9.1for i in `git branch -a | grep remote | grep -v HEAD | grep -v master`; do git branch --track ${i#remotes/origin/} $i; done
перед мерзавцем 1.9.1Авторы: Вэл Блант, Элиас и Хьюго.
Примечание: следующий код, если он используется в более поздних версиях git (>v1.9.1), вызывает
- (ошибка) Все созданные ветки для отслеживания мастера
- (раздражение) Все созданные имена локальных веток должны иметь префикс
origin/
for remote in `git branch -r `; do git branch --track $remote; done
Обновите ветки, если в ваших локальных ветках отслеживания нет изменений:
for remote in `git branch -r `; do git checkout $remote ; git pull; done
Игнорируйте неоднозначные предупреждения refname, git, похоже, предпочитает локальную ветку, как и должно.
Ответ, данный Отто, хорош, но все созданные ветви будут иметь "происхождение /" в качестве начала имени. Если вы просто хотите, чтобы последняя часть (после last /) была вашими именами ветвей, используйте это:
for remote in `git branch -r | grep -v /HEAD`; do git checkout --track $remote ; done
Он также имеет то преимущество, что не дает вам никаких предупреждений о неоднозначных ссылках.
Большинство ответов здесь слишком усложняют анализ выходных данных git branch -r
, Вы можете использовать следующее for
Цикл для создания отслеживания ветвей против всех веток на пульте, вот так.
пример
Скажем, у меня есть эти удаленные ветви.
$ git branch -r
origin/HEAD -> origin/master
origin/development
origin/integration
origin/master
origin/production
origin/staging
Убедитесь, что мы не отслеживаем ничего, кроме мастера, локально:
$ git branch -l # or using just git branch
* master
Вы можете использовать этот вкладыш для создания веток отслеживания:
$ for i in $(git branch -r | grep -vE "HEAD|master"); do
git branch --track ${i#*/} $i; done
Branch development set up to track remote branch development from origin.
Branch integration set up to track remote branch integration from origin.
Branch production set up to track remote branch production from origin.
Branch staging set up to track remote branch staging from origin.
Теперь подтвердите:
$ git branch
development
integration
* master
production
staging
Чтобы удалить их:
$ git br -D production development integration staging
Deleted branch production (was xxxxx).
Deleted branch development (was xxxxx).
Deleted branch integration (was xxxxx).
Deleted branch staging (was xxxxx).
Если вы используете -vv
переключиться на git branch
Вы можете подтвердить:
$ git br -vv
development xxxxx [origin/development] commit log msg ....
integration xxxxx [origin/integration] commit log msg ....
* master xxxxx [origin/master] commit log msg ....
production xxxxx [origin/production] commit log msg ....
staging xxxxx [origin/staging] commit log msg ....
Разбивка цикла
Цикл в основном вызывает команду git branch -r
, отфильтровывая любые заголовки или главные ветви в выводе, используя grep -vE "HEAD|master"
, Чтобы получить имена только ветвей минус origin/
подстрока мы используем строковые манипуляции Баша ${var#stringtoremove}
, Это удалит строку "stringtoremove" из переменной $var
, В нашем случае мы удаляем строку origin/
из переменной $i
,
ПРИМЕЧАНИЕ: в качестве альтернативы вы можете использовать git checkout --track ...
чтобы сделать это также:
$ for i in $(git branch -r | grep -vE "HEAD|master" | sed 's/^[ ]\+//'); do
git checkout --track $i; done
Но мне не особенно важен этот метод, так как он переключает вас между ветвями, когда он выполняет проверку. Когда это будет сделано, вы останетесь на последней ветви, которую создали.
Рекомендации
Вот мой однострочный текст, который я использую (в оболочке bash, протестирован с msysgit1.7.4):
Для копирования-вставки:
remote=origin ; for brname in `git branch -r | grep $remote | grep -v master | grep -v HEAD | awk '{gsub(/^[^\/]+\//,"",$1); print $1}'`; do git branch --set-upstream-to $remote/$brname $brname; done
Для большей читаемости:
remote=origin ; // put here the name of the remote you want
for brname in `
git branch -r | grep $remote | grep -v master | grep -v HEAD
| awk '{gsub(/^[^\/]+\//,"",$1); print $1}'
`; do
git branch --set-upstream-to $remote/$brname $brname;
done
- он будет только выбирать восходящие ветви от удаленного, который вы указали в
remote
переменная (это может быть 'origin
'или любое другое имя, которое вы указали для одного из пультов вашего текущего репозитория Git). - он извлечет название ветви:
origin/a/Branch/Name => a/Branch/Name
сквозьawk
выражение. это установит ветку вверх по течению через
--set-upstream-to
(или же-u
) не--track
:
Преимущество состоит в том, что, если ветвь уже существует, она не выйдет из строя и не изменит источник этой ветки, она только настроитbranch.xxx.(remote|merge)
установка.branch.aBranchName.remote=origin branch.aBranchName.merge=refs/heads/a/Branch/Name
Эта команда создаст локальные ветви для всех удаленных вышестоящих ветвей и установит их удаленные ветви и настройки слияния для этой удаленной ветви.
Без каких-либо сценариев (в пустой директории):
$ git clone --bare repo_url .git
$ git config core.bare false
$ git checkout
после этого все удаленные ветви будут рассматриваться как локальные.
Вы могли бы написать это достаточно легко, но я не знаю, когда это будет ценно. Эти ветви довольно быстро отстанут, и вам придется постоянно обновлять их.
Удаленные ветви будут автоматически обновляться, поэтому проще всего создать локальную ветку в точке, где вы действительно хотите работать с ней.
for i in `git branch -a | grep remote`; do git branch --track ${i#remotes/origin/} $i; done
Если вы хотите использовать powershell, а ваш пульт называется origin. Тогда это работает.
git fetch
git branch -r | %{$_ -replace " origin/"} | %{git branch --track $_ "origin/$_"}
for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master`; do git branch --track ${branch##*/} $branch; done
Используйте это, и у вас не будет такого предупреждения, как: refname 'origin/dev' является неоднозначным
Вот мое решение команды BASH, ссылающейся на @tjmcewan:
for remote in `git branch -r | grep -v /HEAD `; do git branch --track ${remote/"origin/"/""}; done
Моя цель состоит в том, чтобы решить проблему, заключающуюся в том, что все созданные ветки будут иметь "origin/" в качестве начала имени, потому что я проверял, что переменные $remote по-прежнему включают "origin/":
for remote in `git branch -r | grep -v /HEAD`; do echo $remote ; done
Начиная с git 2.23:
for branch in `git branch -r | grep origin/`; do git switch -t -C ${branch#origin/} $branch; git pull; done
В -C
флаг для git switch
создает или сбрасывает, если он уже существует.
Чтобы сделать то же самое, что и ответ tjmcewan, но в Windows, вызовите это из командного файла:
for /f "delims=" %%r in ('git branch -r ^| grep -v master') do git checkout --track %%r
Или это из командной строки:
for /f "delims=" %r in ('git branch -r ^| grep -v master') do git checkout --track %r
Решение VonC можно еще больше упростить, изменив sed (мне не хватает очков репутации, чтобы прокомментировать его сообщение):
for branch in $(git branch -r | sed 's,[^/]*/,,g'); do git switch $branch; done
Заменяя все, что не является косой чертой, до последней косой черты, оставшееся имя ветки подходит для локального использования; многократное переключение на одну и ту же ветку не является ошибкой (это может быть неэффективно, но может быть более эффективным, чем использование grep в конвейере :->).
Команда switch достаточно умна, чтобы отслеживать каждую удаленную ветвь по мере необходимости.
Используя bash, если вы хотите оформить заказ во всех филиалах:
for remote in `git branch -r`; do git checkout $(echo $remote | cut -d'/' -f 2); done
Важно отметить, что когда вы делаете выборку, которая выводит из строя новые ветви удаленного отслеживания, у вас автоматически не появляется локальных, редактируемых их копий.
for rembranch in `git remote update 2>&1 > /dev/null ; git branch -r|egrep -wv "HEAD|master"`
do
git checkout --track -b `echo $rembranch|awk -F\/ '{print $2}'` $rembranch;
done
Объяснение:
строка 1: "git branch -r" (за которой следует "git remote update" для обновления информации об изменениях в remote), перечисляются все удаленные ветви; 'egrep -vw' используется, чтобы выбить записи, имеющие HEAD и master в результате.
строка 3: отслеживание названной удаленной ветви при локальной проверке. Простой awk используется, чтобы избежать "origin/" как суффикса для локальных веток.
В случае, если у вас уже есть некоторые проверенные ветки и вы хотите
- проверить все оставшиеся ветви с пульта
- убедитесь, что все локальные ветви отслеживают удаленные ветви
Вы можете использовать следующий bash- и zsh-совместимый скрипт:
git branch -r | while read b; do if git branch | grep -q " ${b##*/}$"; then git branch --set-upstream ${b##*/} $b; else git branch --track ${b##*/} $b; fi; done