Git натиска клон от едно дистанционно на друго?

Имам настроени следните дистанционни:

$ 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)


Бърз тест, който прави някои временни хранилища, показва, че можете да създадете рефспец, който може да направи това:

$ 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

И така origin/BRANCHNAME:refs/heads/BRANCHNAME

Проверявам дистанционното си 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 препратки:

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, защото тези заместващи символи за push подпис и препратки са често срещани - 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
ths, и аз го давам за пример - person radistao; 27.04.2017
comment
Този подход дава всичко актуално в Windows, но ако изпълните от bash (дори в Windows), работи според очакванията. - person Alpha; 06.02.2019
comment
Ако изпълнявате тези команди от командния ред на Windows (за разлика от Git Bash или нещо подобно), трябва да използвате двойни кавички вместо единични кавички. - person Pathogen David; 27.03.2019

За да допълним отговора на patthoyt, ето кратък шел скрипт, който премества всички клонове от едно дистанционно към друго:

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
@Patrick пропускаш контекста - и то много важен, IMO - че отговорът, който ти споменаваш, наистина е написан през 2014 г., но му липсват единичните кавички до редакция около 1 година преди твоя коментар . Така че по времето, когато този отговор беше написан, той всъщност беше различен по доста подходящ начин. - person 0xC0000022L; 15.09.2020
comment
@0xC0000022L благодаря, че ми обърнахте внимание. Виждам как разширяването на параметъра може неволно да повлияе на резултата. По мое мнение обаче, ако този отговор трябваше да подчертае липсващия единичен цитат, би било по-добре да го извика изрично, вместо да се остави на читателите да свършат детективската работа... във всеки случай смятам, че е справедливо да се възстанови гласувайте против, тъй като това наистина е по-добър отговор през '17. - person Patrick; 15.09.2020
comment
@Patrick много вярно, можеше да се посочи ... или по-скоро трябваше да бъде. - 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“.

Може да има по-добър начин, който не прави няколко натискания.

Ако използвате моя код, вероятно искате да използвате кеширане на идентификационни данни, в противен случай трябва да въведете вашите идентификационни данни няколко пъти.

За Windows:

Забележка: Този скрипт е за 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" ще настрои всички възходящи потоци да проследяват отдалечено "remotename"

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