Apa perbedaan -praktik- antara repositori Bare dan non-Bare?

213

Saya sudah membaca tentang repositori telanjang dan non-telanjang / default di Git. Saya belum dapat memahami dengan baik (secara teoritis) tentang perbedaan di antara mereka, dan mengapa saya harus "mendorong" ke repositori kosong. Ini kesepakatannya:

Saat ini, saya satu-satunya yang mengerjakan proyek pada 3 komputer yang berbeda, tetapi akan ada lebih banyak orang yang terlibat di dalamnya nanti, jadi saya menggunakan Git untuk kontrol versi. Saya mengkloning repo telanjang di semua komputer, dan ketika saya menyelesaikan modifikasi saya di salah satu dari mereka, saya komit dan mendorong perubahan ke repo telanjang. Dari apa yang saya baca, repositori telanjang TIDAK memiliki "pohon kerja", jadi jika saya mengkloning repo telanjang, saya tidak akan memiliki "pohon kerja".

Saya menduga bahwa pohon yang bekerja menyimpan informasi komit, cabang, dll dari proyek. Itu tidak akan muncul di repo telanjang. Jadi sepertinya lebih baik bagi saya untuk "mendorong" komitmen ke repo dengan pohon yang berfungsi.

Lalu, mengapa saya harus menggunakan repositori telanjang dan mengapa tidak? Apa perbedaan praktisnya? Itu tidak akan bermanfaat bagi lebih banyak orang yang mengerjakan suatu proyek, saya kira.

Apa metode Anda untuk jenis pekerjaan ini? Saran?

AeroCross
sumber
4
AeroCross, Anda dapat mengkloning repositori telanjang untuk membuat repositori non-telanjang (yaitu, yang memiliki ruang kerja). Jadi, menggunakan git cloneAnda dapat dengan bebas mengkonversi antara repositori kosong dan tidak kosong.
Derek Mahar
13
@ AeroCross: Ini bukan tentang konversi; tidak masalah apa yang ada di ujung sana. Jika Anda menjalankan git clone --bareAnda akan mendapatkan repo telanjang, dan jika Anda menjalankan git clone, Anda akan mendapatkan yang tidak telanjang. Setiap proyek publik yang pernah Anda kloning (dihosting di github, misalnya) adalah repositori kosong di ujung yang lain.
Cascabel
1
Jefromi, saya mengoreksi poin AeroCross, "jadi jika saya mengkloning repo telanjang, saya tidak akan memiliki" pohon kerja "", jadi itu adalah semacam konversi. Dan tidak setiap proyek publik harus merupakan repositori kosong. Ini hanya pilihan umum karena repositori kosong lebih efisien ruang karena tidak memiliki pohon yang berfungsi (ini sama efisiennya dengan repositori mana pun yang tidak memiliki pohon kerja).
Derek Mahar
2
@ Serek: Tapi intinya adalah, begitu menemukan direktori .git, mengambil sepenuhnya tidak menyadari apakah remote itu telanjang atau tidak. Itu tidak mengkonversi. Itu hanya mengambil apa yang dibutuhkan dari jarak jauh, dan meletakkannya di tempat yang seharusnya. Tidak ada yang perlu dikonversi. Itulah yang saya coba tekankan ke OP. Dan saya sangat sadar bahwa proyek publik tidak harus telanjang, tetapi karena orang tidak bodoh, mereka pada dasarnya semua. Saya pikir saya membuat generalisasi yang dapat diterima.
Cascabel
2
Lihat Push to non-bare repository yang memberikan penjelasan luar biasa lain tentang penggunaan repositori telanjang.
Craig McQueen

Jawaban:

95

Perbedaan lain antara repositori telanjang dan non-telanjang adalah bahwa repositori telanjang tidak memiliki repositori asal asli remote :

~/Projects$ git clone --bare test bare
Initialized empty Git repository in /home/derek/Projects/bare/
~/Projects$ cd bare
~/Projects/bare$ git branch -a
* master
~/Projects/bare$ cd ..
~/Projects$ git clone test non-bare
Initialized empty Git repository in /home/derek/Projects/non-bare/.git/
~/Projects$ cd non-bare
~/Projects/non-bare$ git branch -a
* master
  remotes/origin/HEAD -> origin/master
  remotes/origin/master

Dari halaman manual untuk git clone --bare:

Juga kepala cabang di remote disalin langsung ke kepala cabang lokal yang sesuai, tanpa memetakannya ke ref / remote / asal /. Saat opsi ini digunakan, cabang pelacakan jarak jauh maupun variabel konfigurasi terkait tidak dibuat.

Agaknya, ketika itu membuat repositori telanjang, Git mengasumsikan bahwa repositori telanjang akan berfungsi sebagai repositori asal untuk beberapa pengguna jarak jauh, sehingga tidak membuat asal-usul jauh default. Apa artinya ini adalah bahwa dasar git pulldan git pushoperasi tidak akan berfungsi karena Git mengasumsikan bahwa tanpa ruang kerja, Anda tidak bermaksud melakukan perubahan apa pun pada repositori kosong:

~/Projects/bare$ git push
fatal: No destination configured to push to.
~/Projects/bare$ git pull
fatal: /usr/lib/git-core/git-pull cannot be used without a working tree.
~/Projects/bare$ 
Derek Mahar
sumber
1
Ya, saya setuju bahwa ini adalah perbedaan yang paling signifikan antara repositori telanjang dan non-telanjang. Fakta bahwa repositori non-telanjang memiliki ruang kerja, tetapi repositori kosong tidak merupakan perbedaan penting, tetapi git clone --no-checkoutdapat membuat repositori non-telanjang tanpa file ruang kerja juga.
Derek Mahar
10
Repositori non-telanjang juga tidak harus memiliki "asal" remote default.
mipadi
2
Anda dapat membuat repositori Git hanya dengan git init, yang akan membuat repo non-telanjang tanpa ditentukan jarak jauh.
mipadi
1
mipadi, ini benar, tetapi juga bukan tiruan.
Derek Mahar
1
Ini salah. Repositori akan memiliki asal default jika sudah clonediedit. Jika sudah initdiedit secara lokal, itu tidak akan memiliki asal seperti itu. Ini tidak ada hubungannya dengan apakah itu telanjang atau tidak.
Noufal Ibrahim
62

Perbedaan antara repositori telanjang dan non-telanjang adalah buatan dan menyesatkan karena ruang kerja bukan bagian dari repositori dan repositori tidak memerlukan ruang kerja. Sebenarnya, repositori Git mencakup objek-objek yang menggambarkan status repositori. Objek-objek ini mungkin ada di direktori mana pun, tetapi biasanya ada di .gitdirektori di direktori tingkat atas ruang kerja. Ruang kerja adalah pohon direktori yang mewakili komit tertentu di repositori, tetapi mungkin ada di direktori mana pun atau tidak sama sekali. Variabel lingkungan$GIT_DIR menautkan ruang kerja ke repositori tempat asalnya.

Perintah Git git clonedan git initkeduanya memiliki opsi --bareyang membuat repositori tanpa ruang kerja awal. Sangat disayangkan bahwa Git mengonfigurasi dua terpisah, tetapi konsep terkait ruang kerja dan repositori dan kemudian menggunakan istilah membingungkan telanjang untuk memisahkan dua ide.

Derek Mahar
sumber
61

Repositori kosong hanyalah folder .git itu sendiri yaitu isi repositori kosong sama dengan isi folder .git di dalam repositori kerja lokal Anda.

  • Gunakan repositori kosong pada server jarak jauh untuk memungkinkan banyak kontributor mendorong pekerjaan mereka.
  • Non-bare - Yang memiliki pohon kerja masuk akal pada mesin lokal dari setiap kontributor proyek Anda.
Deepak Sharma
sumber
60

5 tahun terlambat, saya tahu, tetapi tidak ada yang benar-benar menjawab pertanyaan:

Lalu, mengapa saya harus menggunakan repositori telanjang dan mengapa tidak? Apa perbedaan praktisnya? Itu tidak akan bermanfaat bagi lebih banyak orang yang mengerjakan suatu proyek, saya kira.

Apa metode Anda untuk jenis pekerjaan ini? Saran?

Mengutip langsung dari buku Loeliger / MCullough (978-1-449-31638-9, p196 / 7):

Sebuah repositori telanjang mungkin tampaknya tidak banyak berguna, tetapi perannya sangat penting: untuk berfungsi sebagai titik fokus otoritatif untuk pengembangan kolaboratif. Pengembang lain clonedan fetchdari repositori kosong dan pushpembaruannya ... jika Anda menyiapkan repositori tempat pengembang pushberubah, itu seharusnya kosong. Akibatnya, ini adalah kasus khusus dari praktik terbaik yang lebih umum bahwa repositori yang diterbitkan harus kosong.

EML
sumber
19

Repositori non-telanjang hanya memiliki pohon kerja check-out. Pohon kerja tidak menyimpan informasi apa pun tentang keadaan repositori (cabang, tag, dll.); alih-alih, pohon yang berfungsi hanyalah representasi dari file aktual dalam repo, yang memungkinkan Anda untuk mengerjakan (mengedit, dll.) file.

mipadi
sumber
Jadi itu artinya saya bisa menambahkan cabang, tag, dll ke repositori telanjang lalu menarik dari telanjang ke repositori non-telanjang / produksi?
AeroCross
2
mipadi, repositori non-telanjang mungkin tidak memiliki pohon check-out. Ini terjadi jika Anda membuat repositori non-telanjang git clone --no-checkout. Dalam hal ini, repositori non-telanjang memiliki lokasi untuk ruang kerja, tetapi Git tidak memeriksa file apa pun ke dalam ruang kerja tersebut.
Derek Mahar
17

Repositori kosong memiliki manfaat di

  • mengurangi penggunaan disk
  • lebih sedikit masalah yang terkait dengan push jarak jauh (karena tidak ada pohon yang berfungsi untuk keluar dari sinkronisasi atau memiliki perubahan yang bertentangan)
lihat
sumber
3
Jadi repositori kosong adalah cara terbaik / direkomendasikan untuk bekerja dengan beberapa orang tanpa akses ke repositori MEREKA? (Agak suka SVN?)
AeroCross
2
AeroCross, saya akan mengatakan repositori kosong adalah pilihan yang baik untuk skenario itu.
Derek Mahar
12

Repositori non telanjang memungkinkan Anda untuk (ke dalam pohon kerja Anda) menangkap perubahan dengan membuat komit baru.

Repositori kosong hanya diubah dengan mentransportasikan perubahan dari repositori lain.

Nitin
sumber
10

Saya tentu saja bukan "pakar" Git. Saya telah menggunakan TortoiseGit untuk sementara waktu, dan bertanya-tanya apa yang dibicarakan ketika bertanya apakah saya ingin membuat repo "telanjang" setiap kali saya membuatnya. Saya membaca tutorial ini: https://www.atlassian.com/git/tutorials/setting-up-a-repository/git-init dan membahas masalah ini, tetapi saya masih belum cukup memahami konsepnya. Yang ini banyak membantu: http://bitflop.com/tutorials/git-bare-vs-non-bare-repositories.html . Sekarang, yang pertama juga masuk akal!

Menurut sumber-sumber ini, singkatnya repo "telanjang" digunakan pada server tempat Anda ingin mengatur titik distribusi. Itu tidak dimaksudkan untuk digunakan pada mesin lokal Anda. Anda biasanya mendorong komit dari mesin lokal Anda ke repo telanjang di server jarak jauh, dan Anda dan / atau orang lain menarik dari repo telanjang itu ke mesin lokal Anda. Jadi GitHub, Assembla, dll. Repo penyimpanan / distribusi jarak jauh Anda adalah contoh di mana repo "telanjang" dibuat. Anda akan membuatnya sendiri jika sedang menyiapkan "pusat berbagi" analog Anda sendiri.

Terima kasih
sumber
ooooh sekarang saya mengerti
Fuseteam
9

Repo Git default / non-telanjang berisi dua bagian negara:

  1. Sebuah snapshot dari semua file dalam repositori (ini adalah apa yang "pohon kerja" berarti di Git jargon)
  2. Sebuah sejarah dari semua perubahan yang dibuat untuk semua file yang sudah pernah di repositori (ada tampaknya tidak menjadi bagian singkat dari Git jargon yang mencakup semua ini)

The snapshot adalah apa yang mungkin Anda anggap sebagai proyek Anda: file Anda kode, membangun file, script helper, dan apa pun versi Anda dengan Git.

The sejarah adalah negara yang memungkinkan Anda untuk memeriksa berbeda komit dan mendapatkan gambaran lengkap dari apa file dalam repositori Anda tampak seperti ketika yang komit ditambahkan. Ini terdiri dari sekelompok struktur data yang internal untuk Git yang mungkin belum pernah Anda berinteraksi secara langsung. Yang penting, sejarah tidak hanya menyimpan metadata (mis. "Pengguna U menambahkan banyak baris ini ke File F pada Waktu T sebagai bagian dari Komit C"), tetapi juga menyimpan data (mis. "Pengguna U menambahkan baris yang tepat ini ke File F" ).

Gagasan kunci dari repositori kosong adalah bahwa Anda sebenarnya tidak perlu memiliki snapshot. Git membuat snapshot tetap ada karena nyaman bagi manusia dan proses non-Git lainnya yang ingin berinteraksi dengan kode Anda, tetapi snapshot itu hanya menduplikasi keadaan yang sudah ada dalam sejarah.

Sebuah repositori telanjang adalah repositori Git yang tidak memiliki snapshot. Itu hanya menyimpan sejarah.

Mengapa Anda menginginkan ini? Nah, jika Anda hanya akan berinteraksi dengan file Anda menggunakan Git (yaitu, Anda tidak akan mengedit file Anda secara langsung atau menggunakannya untuk membangun yang dapat dieksekusi), Anda dapat menghemat ruang dengan tidak menyimpan snapshot. Khususnya, jika Anda mempertahankan versi repo terpusat pada server di suatu tempat (yaitu Anda pada dasarnya hosting GitHub Anda sendiri), server itu mungkin harus memiliki repo telanjang (Anda masih akan menggunakan repo non-telanjang pada Anda mesin lokal, karena Anda mungkin ingin mengedit snapshot Anda).

Jika Anda menginginkan penjelasan yang lebih mendalam tentang repo telanjang dan contoh penggunaan lainnya, saya menulis posting blog di sini: https://stegosaurusdormant.com/bare-git-repo/

Greg Owen
sumber
4

Ini bukan jawaban baru, tetapi itu membantu saya untuk memahami berbagai aspek dari jawaban di atas (dan itu terlalu banyak untuk dikomentari).

Menggunakan Git Bash coba saja:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init
Initialized empty Git repository in C:/Test/.git/

me@pc MINGW64 /c/Test (master)
$ ls -al
total 20
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:35 .git/

me@pc MINGW64 /c/Test (master)
$ cd .git

me@pc MINGW64 /c/Test/.git (GIT_DIR!)
$ ls -al
total 15
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 ../
-rw-r--r-- 1 myid 1049089 130 Apr  1 11:35 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:35 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:35 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 objects/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:35 refs/

Sama dengan git --bare:

me@pc MINGW64 /c/Test
$ ls -al
total 16
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089 0 Apr  1 11:11 ../

me@pc MINGW64 /c/Test
$ git init --bare
Initialized empty Git repository in C:/Test/

me@pc MINGW64 /c/Test (BARE:master)
$ ls -al
total 23
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 ./
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:11 ../
-rw-r--r-- 1 myid 1049089 104 Apr  1 11:36 config
-rw-r--r-- 1 myid 1049089  73 Apr  1 11:36 description
-rw-r--r-- 1 myid 1049089  23 Apr  1 11:36 HEAD
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 hooks/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 info/
drwxr-xr-x 1 myid 1049089   0 Apr  1 11:36 objects/
Christoph
sumber
2

$ git help repository-layout

Repositori Git hadir dalam dua rasa berbeda:

  • direktori .git di akar pohon yang bekerja;
  • direktori .git yang merupakan repositori kosong (yaitu tanpa pohon yang berfungsi sendiri), yang biasanya digunakan untuk bertukar sejarah dengan orang lain dengan mendorongnya dan mengambilnya.
Sial
sumber