Apa perbedaan antara "git init" dan "git init --bare"?

162

Apa perbedaan antara git initdan git init --bare? Saya menemukan bahwa banyak posting blog yang diperlukan --bareuntuk server Git mereka?

Dari halaman manual , tertulis:

--bare

Buat repositori kosong. Jika lingkungan GIT_DIR tidak disetel, itu ditetapkan ke direktori kerja saat ini

Tapi apa sebenarnya artinya? Apakah harus memiliki --bareuntuk pengaturan server Git?

Kit Ho
sumber

Jawaban:

143

Repo Git Non-Bare

Varian ini membuat repositori dengan direktori yang berfungsi sehingga Anda dapat benar-benar bekerja ( git clone). Setelah membuatnya, Anda akan melihat bahwa direktori tersebut berisi folder .git tempat sejarah dan semua pipa ledeng berjalan. Anda bekerja pada level di mana folder .git berada.

Bare Git Repo

Varian lainnya membuat repositori tanpa direktori kerja ( git clone --bare). Anda tidak mendapatkan direktori tempat Anda dapat bekerja. Segala sesuatu di direktori sekarang adalah apa yang terdapat dalam folder .git dalam kasus di atas.

Mengapa Anda Akan Menggunakan Satu vs. Lainnya

Kebutuhan untuk repositori git tanpa direktori yang berfungsi adalah fakta bahwa Anda dapat mendorong cabang ke sana dan tidak mengelola apa yang sedang dikerjakan seseorang. Anda masih bisa mendorong ke repositori yang tidak kosong, tetapi Anda akan ditolak karena Anda berpotensi memindahkan cabang yang sedang dikerjakan seseorang di direktori kerja tersebut.

Jadi dalam sebuah proyek tanpa folder yang berfungsi, Anda hanya dapat melihat objek ketika git menyimpannya. Mereka dikompresi dan diserialisasi dan disimpan di bawah SHA1 (hash) dari isinya. Untuk mendapatkan objek dalam repositori kosong, Anda perlu git showdan kemudian menentukan sha1 objek yang ingin Anda lihat. Anda tidak akan melihat struktur seperti apa proyek Anda.

Repositori telanjang biasanya adalah repositori sentral tempat setiap orang memindahkan pekerjaannya. Tidak perlu memanipulasi pekerjaan yang sebenarnya. Ini adalah cara untuk menyinkronkan upaya antara banyak orang. Anda tidak akan dapat langsung melihat file proyek Anda.

Anda mungkin tidak memiliki kebutuhan untuk repositori telanjang jika Anda adalah satu-satunya yang mengerjakan proyek atau Anda tidak ingin / memerlukan repositori "secara logis sentral". Yang satu lebih suka git pull dari repositori lain dalam kasus itu. Ini menghindari keberatan yang dimiliki git ketika mendorong repositori yang tidak telanjang.

Semoga ini membantu

Adam Dymitruk
sumber
Jauhkan itu , membuang sebuah dari baris ini - Satu lebih suka git pull dari yang lain ... :-)
Arup Rakshit
10
Saya menemukan jawaban ini sangat tidak jelas & membingungkan. Beberapa alasannya ada di sini: meta.stackoverflow.com/questions/339837/...
Marko Avlijaš
Bare repositories are usually central repositories where everyone moves their work to.Apakah Anda bermaksud mengatakan bahwa repositori telanjang adalah sumber dari mana kolaborator proyek lain dapat mengkloning proyek? Artinya, kolaborator memperlakukan ini sebagai remote?
Minh Tran
112

Jawaban singkat

Repositori kosong adalah repositori git tanpa copy yang berfungsi, oleh karena itu konten .git adalah level teratas untuk direktori itu.

Gunakan repositori non-telanjang untuk bekerja secara lokal dan repositori kosong sebagai server / hub pusat untuk membagikan perubahan Anda dengan orang lain. Misalnya, ketika Anda membuat repositori di github.com, itu dibuat sebagai repositori kosong.

Jadi, di komputer Anda:

git init
touch README
git add README
git commit -m "initial commit"

di server:

cd /srv/git/project
git init --bare

Kemudian pada klien, Anda mendorong:

git push username@server:/srv/git/project master

Anda kemudian dapat menyimpan sendiri pengetikan dengan menambahkannya sebagai remote.

Repositori di sisi server akan mendapatkan komit melalui tarik dan tekan, dan bukan dengan Anda mengedit file dan kemudian melakukannya di mesin server, oleh karena itu repositori kosong.

Detail

Anda dapat mendorong ke repositori yang bukan repositori kosong, dan git akan mengetahui bahwa ada repositori .git di sana, tetapi karena kebanyakan repositori "hub" tidak memerlukan copy pekerjaan, adalah normal menggunakan repositori kosong untuk dan direkomendasikan karena tidak ada gunanya memiliki copy pekerjaan di repositori semacam ini.

Namun, jika Anda mendorong ke repositori non telanjang, Anda membuat copy pekerjaan tidak konsisten, dan git akan memperingatkan Anda:

remote: error: refusing to update checked out branch: refs/heads/master
remote: error: By default, updating the current branch in a non-bare repository
remote: error: is denied, because it will make the index and work tree inconsistent
remote: error: with what you pushed, and will require 'git reset --hard' to match
remote: error: the work tree to HEAD.
remote: error: 
remote: error: You can set 'receive.denyCurrentBranch' configuration variable to
remote: error: 'ignore' or 'warn' in the remote repository to allow pushing into
remote: error: its current branch; however, this is not recommended unless you
remote: error: arranged to update its work tree to match what you pushed in some
remote: error: other way.
remote: error: 
remote: error: To squelch this message and still keep the default behaviour, set
remote: error: 'receive.denyCurrentBranch' configuration variable to 'refuse'.

Anda dapat melewati peringatan ini. Tetapi pengaturan yang disarankan adalah: gunakan repositori non-telanjang untuk bekerja secara lokal dan repositori telanjang sebagai hub atau server pusat untuk mendorong dan menarik dari.

Jika Anda ingin berbagi pekerjaan secara langsung dengan copy pekerjaan pengembang lain, Anda dapat menarik satu sama lain dari repositori alih-alih mendorong.

duncan
sumber
jika saya ingin mengerjakan proyek saya di server git, jadi tidak perlu memiliki opsi --bare, bukan?
Kit Ho
Anda menggunakan telanjang untuk repositori jarak jauh, bukan untuk repositori lokal.
duncan
Memang sebentar, tapi di sini pertanyaan lain. Jika kami memiliki repositori jarak jauh kosong, pengembang mana pun dapat menariknya, repositori adalah "sentral". Tetapi jika kita bekerja tanpa repositori kosong, para pengembang seharusnya hanya menarik satu sama lain, tetapi tidak pernah mendorong. Skenario terakhir hanya baik, jika hanya ada 2 copy pekerjaan repo (alias repo lokal). Apakah ini benar?
Asturio
60

Ketika saya membaca pertanyaan ini beberapa waktu lalu, semuanya membingungkan saya. Saya baru saja mulai menggunakan git dan ada copy pekerjaan ini (yang tidak berarti apa-apa saat itu). Saya akan mencoba menjelaskan ini dari sudut pandang lelaki itu, yang baru saja mulai git tanpa tahu tentang terminologi.

Contoh perbedaan yang bagus dapat dijelaskan dengan cara berikut :

--barememberi Anda hanya tempat penyimpanan (Anda tidak bisa berkembang di sana). Tanpa --bareitu memberi Anda kemampuan untuk berkembang di sana (dan memiliki tempat penyimpanan).

git initmembuat repositori git dari direktori Anda saat ini. Ia menambahkan folder .git di dalamnya dan memungkinkan untuk memulai riwayat revisi Anda.

git init --barejuga membuat repositori, tetapi tidak memiliki direktori kerja. Ini berarti bahwa Anda tidak dapat mengedit file, melakukan perubahan Anda, menambahkan file baru di repositori itu.

Kapan --barebisa membantu? Anda dan beberapa orang lainnya sedang mengerjakan proyek dan menggunakan git. Anda meng-host proyek di beberapa server ( amazon ec2). Anda masing-masing memiliki mesin Anda sendiri dan Anda mendorong kode Anda ec2. Tak satu pun dari Anda yang benar-benar mengembangkan sesuatu pada ec2(Anda menggunakan mesin Anda) - Anda hanya mendorong kode Anda. Jadi Anda ec2hanyalah penyimpanan untuk semua kode Anda dan harus dibuat sebagai --baredan semua mesin Anda tanpa --bare(kemungkinan besar hanya satu, dan yang lainnya hanya akan mengkloning semuanya). Alur kerjanya terlihat seperti ini:

masukkan deskripsi gambar di sini

Salvador Dali
sumber
1
Jadi, kita dapat mengatakan bahwa dengan menggunakan repositori --bare kita dapat membuat semacam arsitektur client-server seperti yang dilakukan subversi?
Emiliano Sangoi
14

Repositori default Git mengasumsikan bahwa Anda akan menggunakannya sebagai direktori kerja Anda. Biasanya, ketika Anda berada di server, Anda tidak perlu memiliki direktori yang berfungsi. Hanya repositori. Dalam hal ini, Anda harus menggunakan --bareopsi.

Sandro Munda
sumber
dalam repo dengan opsi --bare, jadi kita tidak bisa melihat semua file proyek? Tampaknya saya kehilangan semua file proyek saya dengan opsi --bare ..
Kit Ho
11

Repositori non-telanjang adalah default. Ini adalah apa yang dibuat saat Anda menjalankan git init, atau apa yang Anda dapatkan ketika Anda mengkloning (tanpa bareopsi) dari server.

Ketika Anda bekerja dengan repositori seperti ini, Anda bisa melihat dan mengedit semua file yang ada di repositori. Ketika Anda berinteraksi dengan repositori - misalnya dengan melakukan perubahan - Git menyimpan perubahan Anda di direktori tersembunyi yang disebut .git.

Ketika Anda memiliki server git, tidak perlu menyalin file-file tersebut. Yang Anda butuhkan hanyalah data Git yang disimpan .git. Repositori kosong persis .gitdirektori, tanpa area kerja untuk memodifikasi dan melakukan file.

Ketika Anda mengkloning dari server, Git memiliki semua informasi yang diperlukan di .gitdirektori untuk membuat copy pekerjaan Anda.

Andrew
sumber
1

Perbedaan lain antara repositori --bare dan Working Tree adalah bahwa dalam kasus pertama tidak ada komit yang hilang disimpan, tetapi hanya komit yang dimiliki oleh trek cabang yang disimpan. Di sisi lain, Pohon Kerja menjaga semua komitmen selamanya. Lihat di bawah...

Saya membuat repositori pertama (nama: git-bare ) dengan git init --bare. Ini servernya. Itu di sisi kiri, di mana tidak ada cabang jarak jauh karena ini adalah repositori jarak jauh itu sendiri.

Saya membuat repositori kedua (nama: git-working-tree ) dengan git clonedari yang pertama. Ada di kanan. Ini memiliki cabang lokal yang terhubung ke cabang terpencil.

(Teks 'pertama', 'kedua', 'ketiga', 'keempat', 'alpha', 'beta' dan 'delta' adalah komentar komit. Nama 'master' dan 'yunani' adalah nama cabang.)

Repositori lokal dan jarak jauh

Sekarang saya akan menghapus cabang bernama 'yunani' baik di git-bare (command git push --delete origin greek:) dan secara lokal di git-working-tree (perintah:) git branch -D greek. Begini tampilannya pohon:

Repositori git-bare menghapus apa yang tidak lagi dirujuk

The git-telanjang repositori menghapus baik cabang dan semua comits direferensikan. Dalam gambar kita melihat bahwa pohonnya berkurang karena alasan ini.

Di sisi lain, repositori git-working-tree , yang setara dengan repositori lokal yang umum digunakan, tidak menghapus commit, yang sekarang hanya dapat dirujuk secara langsung oleh hash Anda dengan sebuah git checkout 7fa897b7perintah. Itu sebabnya pohonnya tidak memiliki struktur yang dimodifikasi.

DI SINGKAT: Komit tidak pernah dijatuhkan di repositori pohon kerja , tetapi dihapus dalam repositori telanjang .

Dalam istilah praktis, Anda hanya dapat memulihkan cabang yang dihapus di server jika ada dalam repositori lokal.

Tetapi sangat aneh bahwa ukuran repositori telanjang tidak berkurang dalam ukuran disk setelah menghapus cabang jarak jauh. Artinya, file-file itu masih ada entah bagaimana. Untuk membuang repositori dengan menghapus apa yang tidak lagi direferensikan atau apa yang tidak pernah bisa direferensikan (kasus terakhir) gunakan git gc --pruneperintah

Sergio Cabral
sumber
Untuk menguji perintah git, cobalah: github.com/sergiocabral/App.GitPlayground
Sergio Cabral