Git mendorong cabang dari satu remote ke yang lain?

133

Saya memiliki pengaturan remote berikut:

$ git remote 
korg
rorg

Dan cabang-cabang berikut:

$ 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

Sekarang saya ingin mendorong semua cabang jarak jauh dari korgke rorgjarak jauh. Bagaimana aku melakukan itu?

Lebih disukai tanpa membuat cabang lokal untuk setiap cabang terlebih dahulu, jika itu dapat dihindari.

Bjarke Freund-Hansen
sumber
Saya menduga jawaban yang satu ini sebanding dengan jawaban yang satu ini: stackoverflow.com/questions/6922700/… .
Legolas

Jawaban:

52

Tes cepat yang membuat beberapa repositori sementara menunjukkan Anda dapat membuat refspec yang dapat melakukan ini:

$ 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

Jadi asal / BRANCHNAME: ref / kepala / BRANCHNAME

Memeriksa di rorgremote saya :

pat@host /tmp/rorg (BARE:master)
$ git graph --all
* 5750bca (HEAD, master) c
| * 13fd55a (one) b
|/
* 822e0de a
patthoyts
sumber
5
Kenapa tidak git push rorg origin/one:one(tanpa refs/heads/) saja?
Ali
2
@exalted karena dengan refs/heads/awalan Anda mendorong remote branched yang tidak perlu checkout keone
ДМИТРИЙ МАЛИКОВ
@ Patthoyts Saya mencoba perintah yang disebutkan itu mengatakan semuanya up to date, Tapi saya punya 10 cabang di A terpencil dan 6 cabang di B terpencil sehingga Anda bisa tolong katakan padaku bagaimana saya bisa memindahkan cabang yang ditinggalkan?
Keshav1234
219

Saya menemukan ini:

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

Dan itu mendorong semua cabang terpencil saya dari korg ke rorg (bahkan tanpa salinan cabang lokal). Lihat output di bawah ini:

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

Dan kemudian Anda dapat membuat dorongan yang sama untuk tagsref:

git push rorg 'refs/tags/*:refs/tags/*'
radistao
sumber
2
Dalam git yang cukup baru (versi apa?), Ini harus menjadi jawaban yang diterima. @ bjarke-freund-hansen apakah Anda ingin mengubah jawaban yang diterima jika Anda setuju untuk kepentingan pencari masa depan?
Jonah Graham
1
"Dalam git yang cukup baru (versi apa?), Ini harus menjadi jawaban yang diterima" seperti yang saya tahu, ini harus bekerja untuk setiap versi publik git, karena tanda tangan dan referensi wildcard itu umum
radistao
3
Memberi saya Everything up-to-datedi git 2.10.0 tanpa terjadi apa-apa, sambil melakukan hal yang sama pada masing-masing cabang bekerja.
user239558
6
Hanya berpikir saya harus memanggil ini: metode ini tampaknya membuat cabang aktual pada remote yang dipanggil HEAD. Tapi itu bisa dihapus. git push rorg :HEAD
Mark Stickley
1
Siapa pun tidak akrab dengan struktur ref dan bertanya-tanya bagaimana untuk mendorong tag, Anda ingin perintah ini: git push rorg refs/tags/*:refs/tags/*. Yang sama dengan git push rorg --tags, tetapi baik untuk memahami apa yang dilakukan hal-hal ini :)
Mark Stickley
14

Untuk melengkapi jawaban patthoyt , berikut ini skrip shell pendek yang mendorong semua cabang dari satu remote ke yang lain:

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

Untuk meringkas, untuk setiap cabang jarak jauh pada sumber jarak jauh (tidak termasuk cabang "pointer" seperti KEPALA), tekan ref itu ke tujuan jarak jauh. ( ${a//$SRC_REMOTE\/}Bit menghapus nama sumber jauh dari nama cabang, yaitu origin/mastermenjadi master.)

blahdiblah
sumber
3
bagi kita yang perlu melakukannya dalam satu dorongan: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)
Jayen
3

Ini berfungsi di Zsh

git push rorg 'refs/remotes/korg/*:refs/heads/*'
zhudongfang
sumber
Maaf saya downvote tetapi jawaban Anda identik dengan radistao di atas ( stackoverflow.com/a/21133502/235878 ) yang diposting di '14.
Patrick
0

Untuk skrip apa pun yang saya jalankan, sebaiknya simpan atau lakukan semua perubahan Anda.

Saya perlu mendorong beberapa cabang dari satu remote ke yang lain. Jawaban ini mensyaratkan bahwa cabang lokal sebelumnya ada

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

Ubah saja origin1 ke sumber remote, dan origin2 ke tujuan remote. Salin ini ke "remoteBranchCloner.sh" dan menyebutnya dengan "sh callBranchCloner.sh".

Mungkin ada cara yang lebih baik , yang tidak melakukan beberapa dorongan.

Jika Anda menggunakan kode saya, Anda mungkin ingin menggunakan caching kredensial, jika tidak , Anda harus mengetikkan waktu kredensial serveral Anda.

Untuk windows :

Catatan: Skrip ini untuk linux . Jika Anda menjalankannya di "git bash" skrip akan berfungsi, tetapi Anda tidak dapat menjalankannya dari konsol asli tanpa menginstal sesuatu yang istimewa.

git config [--global] credential.helper wincred

Untuk linux

git config [--global] credential.helper cache

Di mana [--global] berarti secara opsional tambahkan --global

Jika Anda ingin mengatur pelacakan jarak jauh untuk semua cabang ke remote baru:

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

Disimpan sebagai file .sh dan dijalankan dengan "sh filename.sh" akan mengatur semua upstreams untuk melacak 'remotename' jarak jauh

csga5000
sumber
0

Karena HEADcabang tambahan yang dibuat dalam jawaban sebelumnya , cara terbersih yang saya temukan untuk melakukan ini adalah mengkloning ke repositori kosong dan kemudian mendorong semua cabang ke remote sebagai berikut:

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