Git push ветку с одного пульта на другой?

У меня настроены следующие пульты:

$ git remote 
korg
rorg

И следующие ветки:

$ git branch -a
* (no branch)
  remotes/korg/gingerbread
  remotes/korg/gingerbread-release
  remotes/korg/honeycomb
  remotes/korg/honeycomb-mr1-release
  remotes/korg/master
  remotes/m/android-2.3.3_r1 -> refs/tags/android-2.3.3_r1a
  remotes/m/gingerbread -> korg/gingerbread

Теперь я хочу перенаправить все удаленные ветки с korg на rorg удаленную. Как мне это сделать?

Желательно без создания локальной ветки для каждого первого, если этого можно избежать.


person Bjarke Freund-Hansen    schedule 19.10.2011    source источник
comment
Я предполагаю, что ответ на этот вопрос сравним с ответом на этот: stackoverflow.com/questions/6922700/.   -  person Legolas    schedule 19.10.2011


Ответы (6)


Быстрый тест, создающий несколько временных репозиториев, показывает, что вы можете создать refspec, который может это сделать:

$ git push rorg origin/one:refs/heads/one
Counting objects: 5, done.
Writing objects: 100% (3/3), 240 bytes, done.
Total 3 (delta 0), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
To /tmp/rorg
 * [new branch]      origin/one -> one

Итак, происхождение/ИМЯ ОТДЕЛЕНИЯ:refs/heads/ИМЯ ОТДЕЛЕНИЯ

Проверяю свой rorg пульт:

pat@host /tmp/rorg (BARE:master)
$ git graph --all
* 5750bca (HEAD, master) c
| * 13fd55a (one) b
|/
* 822e0de a
person patthoyts    schedule 19.10.2011
comment
Почему бы не git push rorg origin/one:one (без refs/heads/) вместо этого? - person Ali; 14.05.2013
comment
@exalted, потому что с префиксом refs/heads/ вы отправляете удаленные разветвления, которые не нужно проверять, в one - person ДМИТРИЙ МАЛИКОВ; 18.06.2014
comment
@patthoyts Я попробовал упомянутую команду, она говорит все в актуальном состоянии, но у меня есть 10 ветвей в удаленном A и 6 веток в удаленном B, поэтому не могли бы вы сказать мне, как я могу переместить оставшиеся ветки? - person Keshav1234; 03.01.2018

Я нашел это:

git push rorg 'refs/remotes/korg/*:refs/heads/*'

И он переместил все мои удаленные ветки с korg на rorg (даже без локальных копий веток). См. вывод ниже:

Counting objects: 293, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (67/67), done.
Writing objects: 100% (176/176), 48.32 KiB, done.
Total 176 (delta 105), reused 168 (delta 97)
remote: Resolving deltas:  11% (12/105)
To <<MY_REPOSITORY_URL>>
 * [new branch]      korg/gingerbread-> gingerbread
 * [new branch]      korg/gingerbread-release -> gingerbread-release
 * [new branch]      korg/honeycomb-> honeycomb
 * [new branch]      korg/HEAD -> HEAD
 * [new branch]      korg/honeycomb-mr1-release-> honeycomb-mr1-release
 * [new branch]      korg/master -> master

И затем вы можете сделать то же самое для tags refs:

git push rorg 'refs/tags/*:refs/tags/*'
person radistao    schedule 15.01.2014
comment
В достаточно новой (какой версии?) git это должен быть принятый ответ. @bjarke-freund-hansen, хотели бы вы изменить принятый ответ, если согласны, в интересах будущих искателей? - person Jonah Graham; 22.10.2015
comment
В достаточно новой (какой версии?) git это должен быть принятый ответ, как я знаю, это должно работать для каждой общедоступной версии git, потому что эти подстановочные знаки подписи и ссылок являются общими - person radistao; 16.11.2015
comment
Дает мне Everything up-to-date на git 2.10.0, при этом ничего не происходит, в то время как то же самое в отдельных ветках работает. - person user239558; 24.04.2017
comment
вы пробовали с отдельной ветвью в таком синтаксисе: git push rorg refs/remotes/korg/branch_name:refs/heads/branch_name - person radistao; 24.04.2017
comment
Просто подумал, что я должен назвать это: этот метод, похоже, создает фактическую ветку на удаленном компьютере с именем HEAD. Но это можно удалить. git push rorg :HEAD - person Mark Stickley; 27.04.2017
comment
Всем, кто не знаком со структурой refs и интересуется, как протолкнуть теги, нужна эта команда: git push rorg refs/tags/*:refs/tags/*. Это то же самое, что и git push rorg --tags, но полезно понимать, что эти штуки делают :) - person Mark Stickley; 27.04.2017
comment
спс, я тоже привел в пример - person radistao; 27.04.2017
comment
Этот подход обновляет все в Windows, но если вы выполняете из bash (даже в Windows), он работает так, как ожидалось. - person Alpha; 06.02.2019
comment
Если вы запускаете эти команды из командной строки Windows (в отличие от Git Bash или чего-то подобного), вам нужно использовать двойные кавычки вместо одинарных. - person Pathogen David; 27.03.2019

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

SRC_REMOTE=korg
DST_REMOTE=rorg
for a in $(git branch --list --remote "$SRC_REMOTE/*" | grep -v --regexp='->')
  do git push "$DST_REMOTE" "$a:refs/heads/${a//$SRC_REMOTE\/}"
done

Подводя итог, для каждой удаленной ветки на исходном удаленном (за исключением «указательных» ветвей, таких как HEAD), нажмите эту ссылку на удаленный пункт назначения. (Бит ${a//$SRC_REMOTE\/} отделяет удаленное имя источника от имени ветви, т. е. origin/master становится master.)

person blahdiblah    schedule 19.04.2013
comment
для тех из нас, кому нужно сделать это одним нажатием: git push -u $DST_REMOTE $(for a in $(git branch --list --remote "$SRC_REMOTE/*" | grep -v --regexp='->'); do echo "$a:refs/heads/${a//$SRC_REMOTE\/}"; done) - person Jayen; 31.12.2013

Это работает в Zsh

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

git push rorg 'refs/remotes/korg/*:refs/heads/*'
person zhudongfang    schedule 04.08.2017
comment
Извините, я понизил его, но ваш ответ идентичен приведенному выше radistao (stackoverflow.com/a/21133502/235878), который был опубликован в 14 году. - person Patrick; 28.04.2020
comment
@ Патрик, вам не хватает контекста - и очень важного, ИМО - что ответ, который вы упоминаете, действительно был написан в 2014 году, но в нем не было одинарных кавычек до редактирования примерно за 1 год до вашего комментария. . Таким образом, в то время, когда этот ответ был написан, он действительно отличался довольно важным образом. - person 0xC0000022L; 15.09.2020
comment
@ 0xC0000022L спасибо, что обратили мое внимание на это. Я вижу, как расширение параметра может непреднамеренно повлиять на результат. Однако, на мой взгляд, если бы этот ответ должен был выделить отсутствующую одинарную кавычку, было бы лучше указать это явно, а не оставлять читателям выполнять детективную работу... в любом случае, я думаю, что справедливо восстановить голосование против, так как это действительно лучший ответ в 17-м. - person Patrick; 15.09.2020
comment
@ Патрик, очень верно, можно было указать ... или, скорее, следовало бы. - person 0xC0000022L; 15.09.2020

Для любого скрипта, который я предлагаю вам запустить, было бы разумно спрятать или зафиксировать все ваши изменения.

Мне нужно было протолкнуть несколько веток с одного пульта на другой. Эти ответы требовали, чтобы локальные ветки существовали ранее

SRC_R=origin1
DEST_R=origin2
for cbranch in $(git branch -r | grep $SRC_R | cut -d '/' -f2,3,4,5 | cut -d ' ' -f1)
do
    git checkout $cbranch
    git push $DEST_R $cbranch
done

Просто измените origin1 на исходный удаленный, а origin2 на целевой удаленный. Скопируйте это в «remoteBranchCloner.sh» и вызовите его, используя «sh callBranchCloner.sh».

Может быть лучший способ, который не делает несколько нажатий.

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

Для окон:

Примечание. Этот скрипт предназначен для Linux. Если вы запустите его в "git bash", скрипт будет работать, но вы не сможете запустить его из родной консоли, не установив что-то специальное.

git config [--global] credential.helper wincred

Для Linux

git config [--global] credential.helper cache

Где [--global] означает необязательное добавление --global

Если вы хотите установить удаленное отслеживание для всех филиалов на новый удаленный:

DEST_R=remotename
for cbranch in `git branch`
do
    git checkout $cbranch
    git branch -u guru/$cbranch
done

Сохраненный как файл .sh и запущенный с «sh filename.sh», все восходящие потоки будут настроены на отслеживание удаленного «удаленного имени»

person csga5000    schedule 22.07.2015

Из-за создания дополнительной ветки HEAD в предыдущем ответе , самый чистый способ, который я нашел для этого, — клонировать в голый репозиторий, а затем отправить все ветки на удаленный компьютер следующим образом:

git clone --bare <from-repository>
cd <from-repo-dir>
git push --set-upstream <to-repository> --all
git push --set-upstream <to-repository> --tags
person Kurt Vangraefschepe    schedule 09.05.2019