Dorong repo Git lokal ke remote baru termasuk semua cabang dan tag

551

Saya memiliki repo Git lokal yang ingin saya dorong ke repo jarak jauh baru (repo baru yang dibuat di Beanstalk, jika itu penting).
Repo lokal saya memiliki beberapa cabang dan tag, dan saya ingin menyimpan semua sejarah saya.

Sepertinya pada dasarnya saya hanya perlu melakukan git push, tetapi itu hanya mengunggah mastercabang.

Bagaimana cara mendorong semuanya sehingga saya mendapatkan replika lengkap repo lokal saya di remote?

Cory Imdieke
sumber
Jawaban terpendek dan termudah - stackoverflow.com/a/39992258/6648326 .
MasterJoe2

Jawaban:

898

Untuk mendorong semua cabang Anda , gunakan salah satu (ganti REMOTE dengan nama remote, misalnya "asal"):

git push REMOTE '*:*'
git push REMOTE --all

Untuk mendorong semua tag Anda :

git push REMOTE --tags

Akhirnya, saya pikir Anda bisa melakukan ini semua dalam satu perintah dengan:

git push REMOTE --mirror

Namun, di samping itu --mirror, juga akan mendorong remote Anda, jadi ini mungkin bukan yang Anda inginkan.

cmcginty
sumber
53
--allbukannya *:*tampak lebih ramah
Idan K
56
Ya tuhan ............. aku merobek seluruh internet dan aku menemukan saklar `--all` adalah AAAAALLLLLLLLLLLLLL yang kubutuhkan!
Rakib
21
Hanya mencatat bahwa git push REMOTE --allkembali No refs in common and none specified;tidak melakukan apa-apa, sementara git push REMOTE "*:*sebenarnya mendorong semua cabang ke jarak jauh.
Im0rtality
10
Gunakan --dry-run untuk memeriksa apa yang akan terjadi, jika Anda memiliki cabang "tmp" atau "fitur" secara lokal yang tidak ingin Anda perbarui di REMOTE
Jonno
55
Jika remote asli masih tersedia, itu ide bagus untuk dilakukan git clone --mirror old-remote-url; cd repo.git; git push --mirror new-remote-url.
Suzanne Dupéron
157

Dalam kasus seperti saya bahwa Anda memperoleh repo dan sekarang mengalihkan asal remote ke repo yang berbeda, yang baru kosong ...

Jadi Anda memiliki repo dan semua cabang di dalamnya, tetapi Anda masih perlu memeriksa cabang-cabang itu untuk git push --allperintah untuk benar-benar mendorongnya juga.

Anda harus melakukan ini sebelum menekan:

for remote in `git branch -r | grep -v master `; do git checkout --track $remote ; done

Diikuti oleh

git push --all
Daniel
sumber
4
Ini juga sangat membantu, karena saya harus checkout semua cabang secara manual. Ini akan bagus untuk waktu berikutnya.
Cory Imdieke
10
Anehnya, git push '*:*'mendorong semua cabang. git push -allbaru saja mendorong tuannya. Saya memindahkan repo dari github ke bitbucket.
jerrymouse
3
Alih-alih memeriksa setiap cabang, Anda hanya perlu melakukan "git branch --track $ remote". Dalam repo besar memeriksa cabang tua membutuhkan waktu
Moataz Elmasry
2
Saya harus membuat perubahan kecil agar ini berhasil: --track remotes/$remotealih-alih --track $remote. Inilah baris perintah lengkap:for remote in `git branch -r | grep -v master `; do git checkout --track remotes/$remote ; done
Adrian T
Terima kasih, ini bekerja untuk saya, jawaban di atas tidak berfungsi juga.
Benyamin Jafari
90

Berikut ini adalah pandangan lain tentang hal yang sama yang bekerja lebih baik untuk situasi yang saya alami. Ini memecahkan masalah di mana Anda memiliki lebih dari satu remote, ingin mengkloning semua cabang di remote sourceke remote destinationtetapi tanpa harus memeriksa semuanya terlebih dahulu.

(Masalah yang saya miliki dengan solusi Daniel adalah bahwa ia akan menolak untuk checkout cabang pelacakan dari sourcejarak jauh jika saya sudah memeriksanya sebelumnya, yaitu, itu tidak akan memperbarui cabang lokal saya sebelum push)

git push destination +refs/remotes/source/*:refs/heads/*

Catatan: Jika Anda tidak menggunakan CLI langsung, Anda harus menghindar dari tanda bintang:

git push destination +refs/remotes/source/\*:refs/heads/\*

ini akan mendorong semua cabang dalam jarak jauh sourceke cabang kepala destination, mungkin melakukan dorongan non-maju cepat. Anda masih harus mendorong tag secara terpisah.

Pieter Breed
sumber
8
+1 Ini berfungsi untuk saya, mengkloning satu remotesama lain. Terima kasih!
Laurence
4
Saya harus melarikan diri dari asterisk:git push destination +refs/remotes/source/\*:refs/heads/\*
mattalxndr
2
Bagi saya, ini akhirnya mendorong cabang yang disebut HEAD, yang saya pikir tidak disengaja dalam skenario ini.
Maxwellb
1
Jawaban ini sangat berguna bagi saya. Satu-satunya penyebutan dalam halaman manual git-push (1) tentang penggunaan tanda bintang ini adalah dalam contoh kecil untuk --pruneopsi.
laindir
4
Jawaban luar biasa, jauh berbeda dari --mirrorparameter biasa yang direkomendasikan semua orang. Berfungsi sempurna untuk skenario di mana Anda hanya ingin tetap menyinkronkan dua remote untuk tujuan otomatisasi atau audit.
Vinicius Xavier
15

Ini adalah cara paling ringkas yang saya temukan, asalkan tujuannya kosong. Beralih ke folder kosong dan kemudian:

# Note the period for cwd >>>>>>>>>>>>>>>>>>>>>>>> v
git clone --bare https://your-source-repo/repo.git .
git push --mirror https://your-destination-repo/repo.git

Ganti https://...untuk file:///your/repodll yang sesuai.

ta.speot.is
sumber
13

Halaman manual git-pushini layak dibaca. Digabungkan dengan situs web ini, saya menulis yang berikut ini di .git/config:

[remote "origin"]
    url = …
    fetch = …
    push = :
    push = refs/tags/*

The push = :berarti "mendorong setiap 'pencocokan' cabang (yaitu cabang yang sudah ada di repositori remote dan memiliki mitra lokal)", sedangkan push = refs/tags/*berarti "mendorong semua tag".

Jadi sekarang saya hanya perlu menjalankan git pushuntuk mendorong semua cabang yang cocok dan semua tag.

Ya, ini tidak seperti yang diinginkan OP (semua cabang untuk mendorong harus sudah ada di sisi yang jauh), tetapi mungkin bermanfaat bagi mereka yang menemukan pertanyaan ini sambil mencari "bagaimana cara mendorong cabang dan tag pada saat yang sama waktu".

scy
sumber
13

Dalam kasus saya apa yang berhasil adalah.

git push origin --all
nomulex
sumber
4
Sederhana dan mudah. Berhasil! originalias untuk repositori URL Git jarak jauh.
Do Nhu Vy
8

Mencerminkan repositori

Buat tiruan kosong dari repositori.

git clone --bare https://github.com/exampleuser/old-repository.git

Dorong cermin ke repositori baru.

cd old-repository.git
git push --mirror https://github.com/exampleuser/new-repository.git

Hapus repositori lokal sementara yang Anda buat pada langkah 1.

cd ..
rm -rf old-repository.git

Mencerminkan repositori yang berisi objek Penyimpanan File Besar Git

Buat tiruan kosong dari repositori. Ganti nama pengguna contoh dengan nama orang atau organisasi yang memiliki repositori, dan ganti nama repositori contoh dengan nama repositori yang ingin Anda gandakan.

git clone --bare https://github.com/exampleuser/old-repository.git

Arahkan ke repositori yang baru saja Anda kloning.

cd old-repository.git

Tarik objek Git Large File Storage di repositori.

git lfs fetch --all

Dorong cermin ke repositori baru.

git push --mirror https://github.com/exampleuser/new-repository.git

Dorong objek Git Large File Storage repositori ke mirror Anda.

git lfs push --all https://github.com/exampleuser/new-repository.git

Hapus repositori lokal sementara yang Anda buat pada langkah 1.

cd ..
rm -rf old-repository.git

Instruksi di atas berasal dari Bantuan Github: https://help.github.com/articles/duplicating-a-repository/

Michał Zalewski
sumber
1
Sementara ini secara teoritis dapat menjawab pertanyaan, akan lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini, dan menyediakan tautan untuk referensi. Lihat di sini untuk petunjuk cara menulis jawaban "berbasis tautan" yang lebih baik . Terima kasih!
GhostCat
5

Saya menemukan jawaban di atas masih memiliki beberapa hal yang tidak jelas, yang akan menyesatkan pengguna. Pertama, yakin git push new_origin --alldan git push new_origin --mirrortidak bisa menduplikasi semua cabang asal, itu hanya menduplikasi cabang lokal yang ada ke new_origin Anda.

Di bawah ini adalah dua metode berguna yang telah saya uji:

1, duplikat dengan clone bare repo. git clone --bare origin_url, lalu masukkan folder, dan git push new_origin_url --mirror. Dengan cara ini, Anda juga dapat menggunakan git clone --mirror origin_url, keduanya --baredan --mirrorakan mengunduh repo kosong, tidak termasuk ruang kerja. silakan lihat ini

2, Jika Anda memiliki repo git dengan menggunakan git clone, yang berarti Anda memiliki repo dan ruang kerja git, Anda dapat menggunakan git remote add new_origin new_origin_url, lalu git push new_origin +refs/remotes/origin/\*:refs/heads/\*, lalugit push new_origin --tags

Dengan cara ini, Anda akan mendapatkan cabang tambahan, yang tidak masuk akal.

yanzi1225627
sumber
2

Untuk mendorong cabang dan tag (tetapi tidak jauh):

git push origin 'refs/tags/*' 'refs/heads/*'

Ini sama dengan menggabungkan opsi --tagsdan --alluntuk git push, yang tampaknya tidak diizinkan oleh git.

CEL
sumber
Apakah ada opsi tambahan untuk mendorong dari remote lain? Misalnya dengan+refs/remotes/source/*
Yves Martin
2

Berbasis di @aniel jawaban yang saya lakukan:

for remote in \`git branch | grep -v master\`
do 
    git push -u origin $remote
done
Arthur Julião
sumber
2
Bahkan lebih baik, | grep -v masterdapat diganti dengan | sed 's/\*//'(saya berasumsi Anda dikecualikan masteruntuk menghindari sedikit jahat *yang ditambahkan ke cabang yang saat ini dipilih) yang memungkinkan Anda untuk memasukkan masterdan menghindari masalah ketika masterbukan cabang yang Anda pilih saat ini. Juga maaf untuk necroposting, hanya saja jawaban ini membantu saya hari ini dan saya ingin membagikan modifikasi saya jika dapat membantu orang lain di posisi saya ...
ToVine
1

Saya menemukan bahwa semua ini tampaknya tidak berfungsi dengan baik untuk saya. Merasa bebas untuk menyalakan ini sampai mati tetapi karena alasan tertentu tidak bisa mendapatkan opsi lain untuk berfungsi dengan baik.

Hasil yang diharapkan adalah repo "kloning" ke jarak jauh lain (yaitu dari Github ke penyedia lain):

  • Semua cabang dibuat pada remote baru
  • Semua riwayat cabang dibuat pada remote baru
    • (ini terlewatkan pada setiap solusi yang saya coba)
  • Semua tag dibuat pada remote baru
  • Sumber berpindah (diberikan)
  • Non-destruktif (memberikan jeda pada opsi --mirror)

Masalah utama yang saya lihat adalah apakah semua cabang jarak jauh tidak dibuat ulang di remote baru. Jika suatu perintah melakukan, remote baru tidak memiliki sejarah cabang (yaitu melakukan git checkout branch; git logtidak akan menunjukkan komitmen cabang yang diharapkan).

Saya perhatikan git checkout -b branchnameTIDAK sama dengan git checkout branchname(yang terakhir adalah yang saya butuhkan). Saya perhatikan git checkout --track branchnamesepertinya tidak menarik sejarah cabang.

Solusi Saya (berbasis PowerShell):

Function Git-FetchRemoteBranches {
$originalbranch = (git symbolic-ref HEAD).split("/")[-1]

Foreach ($entry in (git branch -r)) {

If ($entry -like "*->*") {
  $branch = $entry.split("->")[2].split("/")[1]
}
  else {$branch = $entry.split("/")[1]}

Write-Host "--Trying git checkout " -NoNewline
Write-Host "$branch" -Foreground Yellow

git checkout $branch

Remove-Variable branch -Force

""}

#Switch back to original branch, if needed
If ( ((git symbolic-ref HEAD).split("/")[-1]) -ne $originalbranch) {
"Switching back to original branch"
git checkout $originalbranch
Remove-Variable originalbranch -Force
}
}

git clone http://remoterepo
cd remoterepo
Git-FetchRemoteBranches
git remote add newremote
git push newremote --all
git push newremote --tags #Not sure if neeeded, but added for good measure
Petani kentang
sumber
1

Perintah di bawah ini akan mendorong semua cabang ( termasuk yang Anda belum pernah check-out tetapi ada di git repo Anda, Anda dapat melihatnya dengangit branch -a )

git push origin '*:*'

CATATAN: Perintah ini berguna ketika Anda memigrasi layanan kontrol versi ( mis. Bermigrasi dari Gitlab ke GitHub )

Pratik Patel
sumber
1
Bermigrasi di antara layanan kontrol versi dan inilah yang saya cari, tepuk tangan!
Luka Špoljarić
1

Saya sedang dalam proses beralih dari satu layanan kontrol versi ke yang lain dan perlu mengkloning semua repositori termasuk semua cabang, tag dan riwayat.

Untuk mencapai di atas saya lakukan selanjutnya:

  • secara manual checkout semua cabang ke repositori lokal (skrip untuk checkout semua yang ditunjukkan di bawah),
  • git push origin '*:*'

Script .sh yang digunakan untuk checkout semua cabang ke repositori lokal:

for branch in `git branch -a | grep remotes | grep -v HEAD | grep -v master `; do
   git branch --track ${branch#remotes/origin/} $branch
done
Luka Špoljarić
sumber