Apakah ada jebakan untuk meletakkan $ HOME di git alih-alih menghubungkan dotfile?

38

Saya telah selama bertahun-tahun $HOMEmemeriksa seluruh direktori saya ke subversi. Ini sudah termasuk semua dotfile dan profil aplikasi saya, banyak skrip, alat, dan retasan, struktur direktori home dasar pilihan saya, tidak sedikit proyek aneh dan gudang data acak. Ini adalah hal yang baik. Sementara itu berlangsung.

Tapi itu tidak terkendali. Checkout dasar adalah sama di lusinan sistem, tetapi tidak semua hal yang sesuai untuk semua mesin saya. Bahkan tidak semua bermain dengan baik dengan distro yang berbeda.

Saya sedang dalam proses membersihkan rumah - memisahkan data di tempat yang seharusnya, memisahkan beberapa skrip sebagai proyek terpisah, memperbaiki beberapa tautan yang rusak pada hal-hal yang seharusnya otomatis, dll.

Maksud saya adalah untuk mengganti subversiondengan gituntuk checkout tingkat atas $HOME, tetapi saya ingin membagi ini ke hal-hal yang saya ingin miliki di SEMUA sistem saya, yang berarti dotfile, beberapa direktori dan beberapa skrip kustom dasar.

Dalam membaca online, banyak orang tampaknya melakukan ini menggunakan pendekatan symlink: klon ke dalam subdirektori kemudian buat symlink dari $HOMEdalam repositori. Setelah memiliki $HOMEkontrol versi lengkap di bawah saya selama lebih dari satu dekade, saya tidak suka ide pendekatan ini dan saya tidak tahu mengapa orang-orang tampak begitu benci dengan metode checkout langsung. Apakah ada jebakan yang perlu saya ketahui tentang spesifik gitsebagai checkout tingkat atas $HOME?

PS Sebagian sebagai latihan dalam pengkodean yang baik, saya juga berencana membuat checkout root saya publik di github. Menakutkan berapa banyak informasi sensitif keamanan yang saya boleh kumpulkan dalam file yang seharusnya bisa dibagikan tanpa berpikir dua kali! Kata sandi WiFi, kunci RSA tanpa frasa sandi, dll. Eeek!

Caleb
sumber
5
Penasaran apa yang mengarah pada keyakinan bahwa $ HOME harus dapat dibagikan tanpa pikir panjang‽ Bahkan kunci pribadi RSA terenkripsi tidak boleh dibagikan.
derobert
3
jika Anda sebenarnya berbicara tentang meletakkan isi direktori home Anda ke git, perhatikan saja: sulit (tapi bukan tidak mungkin) untuk menggali sejarah git dan dengan hati-hati menghapus item sensitif secara permanen (git dirancang untuk membantu mencegah kehilangan barang), dan juga ingat bahwa ketika Anda mengganti cabang atau checkout revisi sebelumnya gitakan mengubah izin file Anda 644setelah checkout yang buruk untuk hal-hal seperti kunci ssh pribadi. namun etckeepermerupakan solusi untuk menggunakan git dengan izin untuk / etc /
cwd
@derobert: Saya sangat sadar akan hal itu. Saya tidak berbicara tentang membuat $ RUMAH publik, hanya dotfiles dan skrip kenyamanan. Di situlah saya menemukan barang-barang yang bukan miliknya. Dan ya, aku harus bisa berbagi saya .zshrc, .vimrcdan hal-hal serupa tanpa harus membersihkan terlebih dahulu!
Caleb
4
Jika Anda belum melihatnya, lihat wiki dan milis vcs-home , yang pada dasarnya adalah orang-orang yang mendiskusikan hal ini - bagaimana menjaga $ HOME Anda di bawah kendali revisi.
Jim Paris
Saya tidak tahu berapa banyak Anda dapat mengubah perilaku git, tetapi setidaknya cara kerjanya di luar repositori-debian itu cukup serakah ketika datang untuk mencari file yang dilacak / tidak terlacak / dimodifikasi dan secara otomatis merasa bertanggung jawab atas setiap file. mrb sudah menyatakan ini. Kadang-kadang saya terganggu oleh perilaku serakah ini bahkan dalam proyek yang relatif kecil saya tidak ingin itu di direktori rumah saya. Mengapa ingin menggunakan git? Saya juga menggunakan sistem versi untuk menyinkronkan file konfigurasi saya di seluruh host dan saya cukup senang dengan CVS karena sangat sederhana! Git sangat (juga!)
Kuat

Jawaban:

17

Ya , setidaknya ada satu perangkap utama ketika mempertimbangkan gituntuk mengelola direktori home yang tidak menjadi perhatian subversion.

Git serakah dan rekursif secara default .

Subversi secara naif akan mengabaikan apa pun yang tidak diketahuinya dan berhenti memproses folder baik naik atau turun dari checkout Anda ketika mencapai satu yang tidak diketahuinya (atau yang dimiliki repositori berbeda). Git, di sisi lain, terus berulang ke semua direktori anak membuat pemeriksaan bersarang sangat rumit karena masalah namespace. Karena direktori home Anda kemungkinan juga merupakan tempat Anda checkout dan mengerjakan berbagai repositori git lainnya, memiliki direktori home Anda di git hampir pasti akan membuat hidup Anda berantakan.

Ternyata, ini adalah alasan utama orang checkout dotfiles mereka ke dalam folder yang terisolasi dan kemudian symlink ke dalamnya. Itu membuat git tidak suka ketika melakukan hal lain di direktori anak Anda $HOME. Meskipun ini murni masalah preferensi jika memeriksa rumah Anda menjadi subversi, itu menjadi masalah keharusan jika menggunakan git.

Namun , ada solusi alternatif. Git memungkinkan untuk sesuatu yang disebut "root palsu" di mana semua mesin repositori disembunyikan di folder alternatif yang secara fisik dapat dipisahkan dari direktori kerja checkout. Hasilnya adalah bahwa git toolkit tidak akan bingung: bahkan tidak akan MELIHAT repositori Anda, hanya copy pekerjaan. Dengan menetapkan beberapa variabel lingkungan, Anda dapat memberi tahu git di mana menemukan barang untuk saat-saat ketika Anda mengelola direktori home Anda. Tanpa variabel lingkungan yang ditetapkan, tidak ada orang yang lebih bijak dan rumah Anda terlihat seperti file klasik.

Untuk membuat trik ini mengalir sedikit lebih lancar, ada beberapa alat hebat di luar sana. The vcs-rumah milis tampaknya seperti tempat de facto untuk memulai, dan sekitar halaman memiliki bungkus nyaman up dari howtos dan pengalaman orang-orang. Sepanjang jalan ada beberapa alat kecil yang bagus seperti vcsh , mr . Jika Anda ingin menyimpan direktori home Anda langsung di git, vcsh hampir merupakan alat yang harus dimiliki. Jika Anda akhirnya membagi direktori home Anda menjadi beberapa repostories di belakang layar, gabungkan vcshdengan cara yang mrcepat dan tidak terlalu kotor untuk mengaturnya sekaligus.

Caleb
sumber
2
tetapi mengapa tidak menambahkan '*' ke file .gitignore Anda? Dengan begitu git akan mengabaikan segalanya kecuali file yang sudah ada di repositori, dan Anda dapat menambahkan file baru git add -f <file>.
ALiX
@ALiX: Karena gitalat masih menganggap Anda mengerjakan rep dir home Anda, bahkan jika Anda berada di beberapa subdirektori yang merupakan repo git terpisah untuk beberapa proyek. Solusi itu akan membuat seluruh direktori home Anda terlarang untuk semua pekerjaan git lainnya.
Caleb
5
tetapi tanda '*' di .gitignore Anda berarti bahwa semua file yang tidak ada dalam direktori home repo Anda diabaikan. dan ketika Anda memeriksa git repo baru di beberapa subdirektori, semuanya masih berfungsi seperti yang diharapkan (saya pikir). Sejauh yang saya tahu, alat-alat git akan mencari direktori .git pertama sambil memindahkan hierarki direktori. Jadi, ketika bekerja di subdirektori, repositori git yang benar akan digunakan. Tentu saja, jika Anda menggunakan variabel lingkungan git, saya kira semuanya bisa berantakan. Tetapi sebaliknya, saya tidak mengerti mengapa ini tidak berhasil.
ALiX
@ALiX benar. Repo git bersarang tampaknya berfungsi dengan baik selama Anda gitignore di repo induk. Saya bertanya-tanya apa kelemahan dari pendekatan yang sangat sederhana ini, selain dari kemungkinan masalah dengan variabel lingkungan git.
evanrmurphy
1
Telah bereksperimen dengan ini hari ini. Saya pikir /*berfungsi lebih baik daripada *karena masih mengabaikan semuanya secara default tetapi membuatnya lebih mudah untuk menambahkan direktori. Alih-alih git add -fsaya menggunakan !pola -prefixed like !/.vimrcdan !/.gitignore(untuk file .gitignore itu sendiri) untuk secara eksplisit memasukkan hal-hal dalam repo.
evanrmurphy
14

Saya tidak ingin seluruh direktori rumah saya diperiksa ke dalam kontrol versi hanya karena itu berarti setiap subdirektori yang saya masuki akan memiliki konteks kontrol versi dari direktori home saya. Perintah like git checkoutakan memiliki tindakan aktual dalam kasus itu, menyebabkan masalah jika saya secara tidak sengaja menjalankan sesuatu dari direktori yang salah, apakah itu sesuatu itu gitsendiri atau skrip yang memanggil git.

Ini juga membuatnya lebih mungkin untuk menambahkan sesuatu ke repo yang tidak Anda inginkan, yang tidak akan menjadi masalah ketika Anda telah memeriksa semuanya, tetapi sekarang menjadi masalah. Bagaimana jika Anda secara tidak sengaja menambahkan file kunci pribadi (mungkin karena kebiasaan) dan mendorongnya ke github?

Karena itu, saya pikir kerugian utama tidak benar-benar teknis - hanya ingin menyelamatkan saya dari diri saya sendiri.

Adapun symlinking: Anda bisa mengkloning repo Anda ke subdirektori, dan memiliki skrip yang memperbarui setiap symlink yang perlu diperbarui. Namun, jumlah perawatan yang diperlukan untuk skrip ini mungkin lebih besar daripada manfaat memiliki skrip itu sama sekali; symlinking mungkin ternyata kurang berhasil.

Dengan symlinks, Anda juga dapat dengan mudah membuat tambahan distro-spesifik (atau bahkan host-spesifik) yang diperiksa ke git. Skrip pembaruan symlink Anda akan mengabaikan file yang ditujukan untuk platform yang tidak kompatibel atau host yang berbeda, dan hanya memperbarui yang sesuai.

Sesuatu seperti:

HOMEREPO=$HOME/homerepo
HOST=$(hostname)
UNAME=$(uname)

for dotfile in $HOMEREPO/shared/* $HOMEREPO/host-$HOST/* $HOMEREPO/uname-$UNAME/*
do
    target=$HOME/$(basename $dotfile)
    [ ! -r $target ] && ln -s $dotfile $target
done

Secara pribadi: Saya menggunakan symlink, dan saya tidak symlink direktori; hanya file di dalamnya. Ini memberi saya beberapa fleksibilitas untuk membuat perubahan situs-lokal di direktori tersebut (mis. Menambah / menghapus file). Menyiapkan akun saya di sistem baru itu membosankan karena saya harus membuat ulang semua symlink dengan tangan.

mrb
sumber
Setiap gitperintah saya menjalankan baik akan untuk direktori home sendiri atau akan dimakamkan setidaknya satu jauh di dalam NON berkomitmen direktori. Menggunakan svnisolasi satu folder ini cukup efektif dan tidak menyebabkan saya kesulitan dalam satu dekade. Paragraf pertama Anda menunjukkan hal lain. Apakah ini sebenarnya perbedaan cara gitkerjanya?
Caleb
Konfigurasi dan skrip saya juga sudah memiliki logika kondisional untuk host dan platform yang berbeda di dalamnya, jadi menggunakan skrip untuk mensetup tautan yang berbeda karena kondisional sepertinya bukan merupakan keuntungan karena gitmudah untuk mengatur cabang. Masih sesuatu yang saya lewatkan atau ini akan turun ke preferensi?
Caleb
3
Isolasi satu folder tidak benar-benar mengisolasi di git- tidak yakin tentang svn- tetapi untuk contoh, git init foo && mkdir -p foo/bar/baz/spam && cd foo/bar/baz/spam && git status(atau perintah git lainnya) menunjukkan bahwa Anda masih dalam fookonteks kontrol versi.
mrb
Konfigurasi & skrip: Tidak semua dotfiles mendukung persyaratan, itulah sebabnya saya menyarankan pendekatan alternatif. Ini semua alasan yang saya pikir orang lebih suka untuk tidak menggunakan kontrol versi $HOME- dan versi tidak terlalu berharga untuk dotfiles imo - tetapi pada akhirnya itu adalah direktori home Anda, jadi jika Anda lebih suka menggunakan git dan ini bukan masalah bagi Anda, lakukan itu!
mrb
Terimakasih atas infonya. Sebenarnya komentar Anda tentang git yang tidak memungkinkan isolasi adalah bit yang paling berguna. Anda mungkin mengerjakan jawaban Anda dengan jelas. Subversi berperilaku sangat berbeda pada titik itu dan signifikan untuk kasus penggunaan ini.
Caleb
6

Untuk memberikan sudut pandang lain: Saya memiliki $ HOME saya di bawah git sejak sekarang dan tidak menemukan kekurangan. Saya jelas tidak menyinkronkan repo git ini ke github; Saya menggunakan layanan yang memiliki repo pribadi. Saya juga tidak meletakkan file media atau unduhan atau paket di bawah kontrol git.

  • git status adalah semacam daftar "to do, to clean".

  • Saya punya ~/tmp untuk hal-hal sementara, yang gitignored.

  • Saya suka melihat git status apa pun yang perangkat lunak yang baru diinstal berani menambahkan ke $ HOME saya, dan sering menghapus file-file ini, atau bahkan menghapus instalan para pelakunya.

  • Saya menambahkan secara manual file dan dirs lokal yang sangat berguna .gitignore , yang memiliki manfaat 'tahu apa yang Anda lakukan saat menginstal sesuatu'.

  • Jika saya membangun VM baru atau menginstal PC baru, saya hanya mengkloning rumah jarak jauh saya ke $ HOME dan segera memiliki semua yang saya butuhkan.

  • Hal-hal seperti vundle for vim plugins tidak diperlukan lagi.

Saya tidak suka kompleksitas. Ketika saya men-tweak rcfile apa pun, saya lakukan saja, komit, dan dorong. Kemudian, sebagai refleks, saya mendapatkan $ HOME setiap hari, dan selalu memiliki konfigurasi terbaru. Sesederhana itu.

Mesin saat ini di bawah rejimen ini: Laptop rumahan, PC kantor, VM kerja, plus 3 atau 4 server jarak jauh.

gb.
sumber
Apakah Anda memiliki pemeriksaan git lain yang bersarang di dalam rumah Anda?
Caleb
Tidak, saya memasukkan hal-hal lain ke direktori / work dan tidak mengkloning alat kecil seperti vim pugins.
gb.
1
Saya punya pekerjaan di dalam ~ / Sites dan melakukan pendekatan ini juga, tidak ada masalah dengan repositori git bersarang
philfreo
1
Saya telah menggunakan pengaturan ini untuk sementara waktu. Saya memiliki 'alias sq = git status -uno' dan tidak terlalu peduli dengan .gitignore (sering kali saya melihat semua cruft dan kemudian mengatakan "meh"). Saya tidak pernah mengalami masalah dengan repositori git bersarang. Saya memiliki server pribadi di mana saya melakukan git init --bareitu saya mendorong ke atas ssh (meskipun saya tidak memasukkan kata sandi dalam repo, saya punya file catatan saya di sana).
Unhammer
5

Saya sudah mencoba keduanya, dan lebih suka pendekatan symlink pada akhirnya:

  • Lihat ke mana pun
  • make install
  • Logout dan masuk lagi untuk memuat pengaturan X

Kekurangan:

  • Harus memindahkan file ke repo sebelum menambahkannya
  • Harus memelihara daftar tautan simbolik di Makefile

Keuntungan:

  • Tidak perlu untuk yang masif .gitignore(saya punya 133 dotfile di ~dalam kotak Ubuntu saya yang sederhana)
  • Dapat menjaga skrip pemeliharaan dan ~hal-hal terkait lainnya (seperti Makefiledan cleanup.sh) tidak menghalangi
  • Bisakah versi mengontrol pengaturan pribadi dan publik secara terpisah

Pembatasan:

  • Tidak seperti @ mrb, saya hanya membuat symlink di ~. Itu membuat symlinking sederhana, dan membuatnya sepele untuk memperhatikan file baru misalnya ~/.vim, dengan biaya .gitignorepemeliharaan yang sangat jarang .

Dua keunggulan terakhir memberi petunjuk skala pada kasus saya - Saya tidak ingin mengacaukan direktori home, dan saya ingin memisahkan konten pribadi dan publik.

Satu-satunya aplikasi yang saya tahu memiliki (atau setidaknya memiliki) masalah dengan penanganan symlink adalah Pidgin - Itu terus menimpa symlink saya dengan file biasa.

l0b0
sumber
Terima kasih atas masukan Anda atas pro dan kontra dari setiap pendekatan. Dalam tindak lanjut saya, saya telah menemukan ada pendekatan ketiga yang mungkin membuat yang terbaik dari kedua dunia jika Anda ok menyiapkan kabel ekstra untuk memulai.
Caleb
3

Ini satu: Jika Anda mencoba melakukan git rebase -i --rootdan Anda telah check-in .gitconfigdi komit pertama di repositori, git akan menghapus sementara .gitconfigfile, yang pada gilirannya akan membuatnya tidak dapat menyelesaikan operasi rebase karena memerlukan nama dan email Anda untuk melakukan itu, yang disimpan dalam file itu.

Anda dapat mengonfigurasinya kembali dan melakukannya git rebase --continue, tetapi setelah saya melakukan itu dan menyelesaikan operasi rebase, repositori git saya mendapatkan komit kosong tanpa komit sebelum komit yang sebelumnya komit pertama dalam repositori, yang saya tidak tahu bagaimana cara menyingkirkan.

Saya tidak tahu apa yang terjadi jika Anda melakukannya git rebase -i <commit>, dan .gitconfigdiperiksa bersama dengan komit setelahnya <commit>.

Mungkin solusi termudah adalah menahan diri untuk tidak menambah .gitconfigrepositori dan sebaliknya mendaftar .gitignore.

Halo selamat tinggal
sumber
2

Beginilah cara saya melakukannya:

  1. instal linux bersih (tidak perlu, tetapi buat hidup lebih menyenangkan di langkah 4)
  2. instal dllkeeper
  3. dijalankan git initdi rumah Anda
  4. buat .gitignore dan tambahkan semua yang sepertinya tidak menarik bagi Anda atau yang mungkin banyak berubah. Pastikan untuk menambahkan hal-hal seperti *.cache,*.lock dll. Saya tidak menyarankan untuk menambahkan/*karena Anda tidak akan diberitahu secara otomatis ketika sesuatu yang baru ditambahkan ke rumah Anda. Ini adalah pendekatan daftar hitam vs pendekatan daftar putih, di mana saya pada dasarnya ingin menjaga konfigurasi saya untuk semua perangkat lunak kecuali untuk hal-hal yang mudah menguap dan beberapa perangkat lunak yang tidak saya pedulikan. Saat nanti Anda menggabungkan, memigrasikan, atau membandingkan sistem, bisa membedakan semuanya cukup mudah. Anda dapat mengatur sistem baru Anda lebih cepat daripada jika Anda hanya memiliki .bashrc dan beberapa dotfile lain yang disimpan. Dengan cara ini Anda akan menyimpan konfigurasi yang mungkin Anda atur melalui GUI, dan tidak mengetahui dotfiles mana yang menyimpan pengaturan. (Jika ternyata Anda telah melakukan file volatil, Anda masih dapat memberitahu git untuk menganggap-tidak berubah)
  5. menjalankan etckeeper init -d /home/username
  6. menjalankan git commit -d /home/username
  7. mengatur alias di shell Anda untuk membuat baris perintah lebih bagus, seperti homekeeper checkout

Alasan menggunakan etckeeper adalah karena ia akan menyimpan metadata seperti izin untuk file Anda (agak penting untuk hal-hal tertentu seperti kunci ssh). Anda sekarang harus memiliki kait pra-komit yang akan menyimpan metadata secara otomatis. Saya tidak begitu yakin tentang pasca-checkout. Anda mungkin harus menggunakan etckeeper checkout xxx -d /home/usersaya akan melihat lebih dalam dan menguraikan jawaban ini.


sumber
-1

Masalah utama saya dengan menggunakan Git di direktori home adalah bahwa Git tidak menyimpan atribut file seperti izin file dan cap waktu. Bagi saya, penting untuk mengetahui kapan file tertentu dibuat, yang mungkin atau mungkin tidak demikian bagi Anda. Selain itu, kehilangan izin untuk file dan direktori seperti .sshitu bermasalah. Saya memahami bahwa Anda berencana untuk .sshtidak menggunakan Git, tetapi akan ada tempat lain di mana izin mungkin penting (seperti cadangan situs web yang tidak terkompresi).

dotancohen
sumber
Ini menyesatkan jika tidak salah secara faktual. Git secara default mempertahankan banyak atribut file termasuk izin. Saya telah menjaga .sshgit untuk beberapa waktu sekarang tanpa masalah, izin aman yang tepat dipertahankan. Apa yang tidak dilakukan dalam konfigurasi basis adalah mempertahankan kepemilikan atau stempel waktu; namun jika salah satu dari ini adalah masalah untuk kasus penggunaan tertentu ada plugin yang dapat membuat penanganan properti tambahan ini bagian dari alur kerja biasa (lihat metastore atau git-cache-meta).
Caleb
Bahkan jika itu tidak menyimpannya, bagaimana itu lebih buruk daripada hanya memiliki direktori home tidak dalam vcs? git tidak akan secara aktif menimpa mtimes kecuali Anda memintanya untuk mengubah file.
poolie
-1

Solusi berbasis git sangat berguna jika Anda perlu menyebarkan file Anda ke mesin yang berbeda, dan terlebih lagi jika Anda memiliki bagian yang umum untuk semua mesin, dan bagian yang khusus untuk beberapa mesin. Anda dapat membuat beberapa repositori dan menggunakan alat seperti multigit atau vcsh untuk mengkloningnya pada direktori yang sama (home dir Anda dalam kasus ini).

capr
sumber
Terima kasih, tapi mungkin Anda melewatkan pertanyaannya. Saya sangat sadar akan kegunaan untuk ini (maka dari itu mengapa saya ingin melakukannya di tempat pertama), pertanyaan ini adalah tentang setiap jebakan seseorang yang baru melakukan hal ini dengan git (seperti ketika saya bertanya) mungkin tidak menyadari . Ini sepertinya tidak menjawab pertanyaan itu sama sekali.
Caleb