Apa perbedaan antara git clone --mirror dan git clone --bare

486

Halaman bantuan git clone mengatakan ini tentang --mirror:

Siapkan cermin repositori jarak jauh. Ini menyiratkan --bare.

Tetapi jangan merinci tentang bagaimana --mirrorklon berbeda dari --bareklon.

Sam
sumber
3
membantu, tetapi jika Anda juga ingin mendorong mirror ini ke repo jarak jauh seperti github, saya menemukan tautan ini berguna.
Makan di Joes

Jawaban:

569

Perbedaannya adalah bahwa ketika menggunakan --mirror, semua referensi disalin apa adanya . Ini berarti segalanya: cabang pelacakan jarak jauh, catatan, referensi / asli / * (cadangan dari cabang-filter). Repo hasil kloning memiliki semuanya. Ini juga diatur sehingga pembaruan jarak jauh akan mengambil kembali semuanya dari asalnya (menimpa referensi yang disalin). Idenya benar-benar untuk mencerminkan repositori, untuk memiliki salinan total, sehingga Anda dapat misalnya meng-host repo pusat Anda di beberapa tempat, atau mendukungnya. Pikirkan hanya menyalin salinan secara langsung, kecuali dengan cara git yang jauh lebih elegan.

Dokumentasi baru cukup banyak mengatakan semua ini:

--mirror

Siapkan cermin repositori sumber. Ini menyiratkan --bare. Dibandingkan dengan --bare, --mirrortidak hanya memetakan cabang lokal dari sumber ke cabang lokal dari target, ia memetakan semua referensi (termasuk cabang jarak jauh, catatan, dll.) Dan membuat konfigurasi refspec sehingga semua referensi ini ditimpa oleh git remote updatedalam repositori target .

Jawaban asli saya juga mencatat perbedaan antara klon telanjang dan klon normal (non-telanjang) - klon non-telanjang membuat cabang pelacakan jarak jauh, hanya membuat cabang lokal untuk HEAD, sedangkan klon telanjang menyalin cabang-cabang secara langsung.

Asal Misalkan memiliki beberapa cabang ( master (HEAD), next, pu, dan maint), beberapa tag ( v1, v2, v3), beberapa cabang terpencil ( devA/master, devB/master), dan beberapa ref lainnya ( refs/foo/bar, refs/foo/baz, yang mungkin catatan, stashes, ruang nama devs lain, siapa tahu).

  • git clone origin-url(non-telanjang): Anda akan mendapatkan semua tag disalin, cabang lokal master (HEAD)melacak cabang terpencil origin/master, dan cabang terpencil origin/next, origin/pudan origin/maint. Cabang pelacakan diatur sehingga jika Anda melakukan sesuatu seperti git fetch origin, mereka akan diambil seperti yang Anda harapkan. Setiap cabang jarak jauh (di remote yang dikloning) dan referensi lainnya diabaikan sama sekali.

  • git clone --bare origin-url: Anda akan mendapatkan semua tag disalin, cabang lokal master (HEAD), next, pu, dan maintcabang pelacakan, tidak ada remote. Artinya, semua cabang disalin sebagaimana adanya, dan itu diatur sepenuhnya independen, tanpa harapan mengambil lagi. Setiap cabang jarak jauh (di remote yang dikloning) dan referensi lainnya diabaikan sama sekali.

  • git clone --mirror origin-url: Setiap salah satu dari referensi tersebut akan disalin apa adanya. Anda akan mendapatkan semua tag, cabang lokal master (HEAD), next, pu, dan maint, cabang terpencil devA/masterdan devB/master, ref lainnya refs/foo/bardan refs/foo/baz. Semuanya persis seperti yang ada di remote yang dikloning. Pelacakan jarak jauh diatur sehingga jika Anda menjalankan git remote updatesemua referensi akan ditimpa dari asal, seolah-olah Anda baru saja menghapus cermin dan mengkloning ulang itu. Seperti yang awalnya dikatakan oleh para dokter, itu adalah sebuah cermin. Ini seharusnya merupakan salinan yang identik secara fungsional, dapat dipertukarkan dengan yang asli.

Cascabel
sumber
Apakah "klon normal" mengacu pada klon tanpa bendera --bare atau --mirror?
Sam
1
Ya, benar. Dengan klon kosong, seperti yang tertulis di halaman manual, cabang disalin secara langsung juga (tidak ada referensi / remote / asal, tidak ada pelacakan). Diedit dalam.
Cascabel
Bisakah Anda menambahkan beberapa contoh penggunaan tentang perbedaan, bukan hanya perbedaan git-internal?
cmcginty
@ Casey apakah itu yang Anda cari? Saya tidak berpikir apa yang awalnya saya tulis adalah "internal" - tag dan cabang adalah fitur porselen yang sangat banyak.
Cascabel
Apakah "cabang disalin sebagaimana adanya" berarti bahwa cabang disalin ke jalur relatif yang sama pada klon? Atau apakah itu menyiratkan bahwa cabang ditransformasikan dengan cara tertentu?
Sam
56
$ git clone --mirror $URL

adalah kependekan dari

$ git clone --bare $URL
$ (cd $(basename $URL) && git remote add --mirror=fetch origin $URL)

(Disalin langsung dari sini )

Bagaimana halaman buku panduan saat ini meletakkannya:

Dibandingkan dengan --bare, --mirrortidak hanya memetakan cabang lokal dari sumber ke cabang lokal dari target, ia memetakan semua referensi (termasuk cabang jarak jauh, catatan, dll.) Dan membuat konfigurasi refspec sehingga semua referensi ini ditimpa oleh git remote updatedalam repositori target .

hfs
sumber
4
Saya yakin Anda harus mengikuti git fetchitu agar benar-benar identik. Bagaimanapun, ini adalah semacam non-jawaban - titik pertanyaannya adalah "bagaimana remote mirror / clone berbeda dari yang normal?"
Cascabel
6
Saya sebenarnya suka cara menunjukkan perbedaan ini. Semoga ini akurat! Saya harap hfs menambahkan perintah ambil.
joeytwiddle
tidak benar-benar jelas, mis. apa yang diterjemahkan menjadi $ (basename $ URL), dll.
Kzqai
5
basenameadalah utilitas unix normal yang menghapus bagian direktori dari lintasan, dan $()hanyalah substitusi perintah bash.
Victor Zamanian
6
Ini masih ada --mirrordi dalamnya. Ini hanya akan menjadi jawaban yang dapat diterima jika menjelaskan apa yang git remote add --mirrorterjadi.
Zenexer
24

Tes saya dengan git-2.0.0 hari ini menunjukkan bahwa opsi --mirror tidak menyalin kait, file konfigurasi, file deskripsi, file info / kecualikan, dan setidaknya dalam kasus pengujian saya beberapa referensi (yang saya tidak punya ' t mengerti.) Saya tidak akan menyebutnya sebagai "salinan fungsional identik, dipertukarkan dengan aslinya."

-bash-3.2$ git --version
git version 2.0.0
-bash-3.2$ git clone --mirror /git/hooks
Cloning into bare repository 'hooks.git'...
done.

-bash-3.2$ diff --brief -r /git/hooks.git hooks.git
Files /git/hooks.git/config and hooks.git/config differ
Files /git/hooks.git/description and hooks.git/description differ
...
Only in hooks.git/hooks: applypatch-msg.sample
...
Only in /git/hooks.git/hooks: post-receive
...
Files /git/hooks.git/info/exclude and hooks.git/info/exclude differ
...
Files /git/hooks.git/packed-refs and hooks.git/packed-refs differ
Only in /git/hooks.git/refs/heads: fake_branch
Only in /git/hooks.git/refs/heads: master
Only in /git/hooks.git/refs: meta
Mark E. Hamilton
sumber
14

Penjelasan bernuansa dari dokumentasi GitHub tentang Duplikasi Repositori :

Seperti halnya klon kosong, klon cermin mencakup semua cabang dan tag jarak jauh, tetapi semua referensi lokal akan ditimpa setiap kali Anda mengambilnya, jadi itu akan selalu sama dengan repositori asli.

Lebih tepatnya
sumber
1
Terima kasih; ini menjelaskan bagi saya bahwa tag lokal akan ditimpa serta cabang dengan menggunakan klon cermin. Sangat membantu.
Wildcard
2
Anda mungkin juga ingin menggunakan --prunesaat menjalankan git fetch untuk menghapus referensi lokal yang tidak lagi ada di remote.
nishanths
13

Klon menyalin referensi dari jarak jauh dan memasukkan mereka ke dalam subdirektori bernama 'ini adalah referensi yang dimiliki oleh remote'.

Sebuah mirror menyalin referensi dari jarak jauh dan menempatkan mereka ke level teratasnya sendiri - itu menggantikan referensi sendiri dengan yang ada di jarak jauh.

Ini berarti bahwa ketika seseorang menarik dari cermin Anda dan memasukkan referensi cermin ke subdirektori mereka, mereka akan mendapatkan referensi yang sama seperti pada aslinya. Hasil pengambilan dari mirror terbaru sama dengan mengambil langsung dari repo awal.

PaulMurrayCbr
sumber
12

Saya menambahkan gambar, menunjukkan configperbedaan antara cermin dan telanjang. masukkan deskripsi gambar di sini Kiri kosong, kanan cermin. Anda dapat menghapus, file konfigurasi mirror memiliki fetchkunci, yang berarti Anda dapat memperbaruinya, dengan git remote updateataugit fetch --all

yanzi1225627
sumber
3
$ git clone --bare https://github.com/example

Perintah ini akan menjadikan yang baru sebagai $ GIT_DIR. Juga kepala cabang di remote disalin langsung ke kepala cabang lokal yang sesuai, tanpa pemetaan. Saat opsi ini digunakan, cabang pelacakan jarak jauh maupun variabel konfigurasi terkait tidak dibuat.

$ git clone --mirror https://github.com/example

Seperti halnya klon kosong, klon cermin mencakup semua cabang dan tag jarak jauh, tetapi semua referensi lokal (termasuk cabang pelacakan jarak jauh, catatan, dll.) Akan ditimpa setiap kali Anda mengambil, sehingga akan selalu sama dengan repositori asli .

Shantanu Singh
sumber