Pertanyaan Git: Abaikan file untuk repositori publik, tetapi tidak untuk pribadi


Saya menyebarkan aplikasi Rails di Heroku (untuk saat ini) melalui git, dan juga ingin memiliki versi publik untuk dilihat orang. Beberapa file sensitif dan hanya boleh dilakukan dan didorong di cabang "heroku", tetapi bukan cabang "publik". Apa cara terbaik untuk masalah ini?

(SAYA melakukan tahu tentang variabel Config Heroku, yang sangat bagus sebagai solusi sementara, tetapi tidak menyenangkan jika dan ketika saya perlu berganti host.)

Kedua cabang tidak perlu disinkronkan setiap saat - Saya tidak apa-apa dengan menggabungkan cabang "master" secara berkala ke dalam cabang "publik" dan mendorongnya ke github secara terpisah.

Saya telah mencoba berbagai hal:

  • terpisah .gitignore file dan strategi penggabungan "kita" - ini tidak bekerja pada awalnya, dan setelah mengotak-atiknya untuk sementara waktu saya memutuskan itu menjadi terlalu rumit hanya agar saya bisa mencapai tugas yang tampaknya sederhana

  • menggunakan suatu kebiasaan exclude file, dan menambahkan berikut ini ke .git/config... ini tidak berhasil:

.git / config

[branch "public"]
  excludesfile = +info/exclude_from_public

Apa cara terbaik untuk memiliki repositori pribadi dan publik berbagi kode yang sama, tetapi mengabaikan file sensitif di repositori publik?

Anda dapat mengasumsikan bahwa tidak ada kode yang dilakukan atau didorong, yaitu ini adalah repositori yang baru diinisialisasi.

(Pertanyaan ini telah ditanyakan sebelumnya dalam berbagai bentuk, tetapi tidak ada jawaban yang langsung ke depan atau jawabannya tampak sangat hacky. Saya di sini hanya untuk menanyakan ini dengan cara yang sangat sederhana, dan semoga menerima tanggapan yang sangat sederhana.)


32
2018-01-04 04:23


asal


Jawaban:


Saya akan memberikan jawaban submodul kedua, tetapi cobalah untuk memberikan beberapa klarifikasi. Pertama, git tidak berurusan dengan file tetapi dengan commit. Tidak ada cara untuk memfilter file atau jalur di cabang karena cabang sebenarnya adalah penunjuk ke komit. Ketika Anda mengecualikan atau mengabaikan Anda hanya menyimpan file dari yang ditambahkan ke repositori Anda. tidak ada file 'file sensitif' bahkan dalam repositori, hanya di direktori kerja Anda.

Submodul hanya referensi ke repositori lain yang disimpan dalam repositori Anda, dan komit spesifik yang memeriksa repositori adalah pelacakan. Anda dapat mengatakan pembaruan menggunakan

git submodule update --recursive sensitive-files

Untuk menyederhanakan hal-hal, Anda dapat melakukan symlink di tempat yang tepat menunjuk ke path submodule.

ln -sf sensitive-files/shadow passwd

Kemudian tambahkan symlink seperti yang Anda lakukan pada file lain ..

Ingat submodul hanya memeriksa repositori git, Anda dapat dengan mudah membatasi akses ke repositori yang sebenarnya dan menjadikannya publik utama.

Diperbarui:

Maaf saya melewatkan pemberitahuan, jika Anda masih mengerjakan ini.

Anda dapat memiliki beberapa symlink dalam repositori pribadi Anda yang merujuk pada repositori pribadi (submodule) yang dicentang dalam subdirektori. Masing-masing database atau apa pun yang digunakan oleh instance Rails bisa menjadi symlink ke dalam subdirektori pribadi tersebut.

Juga, Anda tidak perlu menunjuk jauh ke repositori pribadi, hanya sebuah entri dalam file .gitmodules yang dikelola secara otomatis oleh git submodule. Anda masih perlu melindungi repositori pribadi sehingga hanya instance Heroku yang dapat mengaksesnya. Untuk itu saya menyarankan memasang gitosis pada server jika Anda bisa atau menggunakan beberapa solusi hosting git pribadi lainnya. Tambahkan kunci ssh publik yang cocok dengan kunci instan instance Anda ke daftar pengguna yang diizinkan. (Aku tidak terbiasa dengan cara melakukan ini di Heroku.)

Ketika Anda mendorong perubahan Anda ke heroku, haruslah mengunduh secara rekursif semua submodul yang disebutkan dalam repositori.


16
2018-01-14 03:23



Anda bisa membuat hook pre-commit di repo lokal Anda, di sini Anda dapat menulis skrip untuk memeriksa cabang yang saat ini diperiksa dan menghapus file yang menyinggung jika ada sebelum commit diproses. Ini menghindari file-file yang pernah dicatat dalam sejarah Git dari cabang yang salah.

#!/bin/bash
current_branch="$(git branch | sed -e 's/^*//')"
if [ $current_branch != "heroku" ]; then 
    // Delete sensitive files before commit
    rm -f dir1/dir2/exclude_from_public
    rm -f dir1/dir2/exclude_from_public_also
fi
exit 0

Atau, skrip hanya bisa memeriksa file dan mengembalikan kode keluar "1", memberi tahu Anda bahwa commit tidak dapat dilanjutkan karena berisi file sensitif.

Peringatannya adalah Anda harus menyerahkan skrip ini kepada siapa saja yang bekerja di cabang "herichi" istimewa, dan selalu memasukkannya ke dalam repo lokal Anda sendiri.

Idealnya Anda akan melakukan pemeriksaan ini juga di sisi server; tapi sayangnya GitHub hanya menawarkan varian Web dari hook pasca-terima, jadi kecuali Anda melakukan repo hosting sendiri, pendekatan ini hanya dapat dilakukan secara lokal.


7
2018-01-13 17:47



Salah satu cara untuk melakukan ini adalah dengan meletakkan file pribadi Anda dalam a submodule, dan lihat modul itu dari repo publik Anda. (Bergantian, Anda bisa menempatkan Anda publik file dalam submodul, dan lihat repo itu dari repo pribadi Anda.)


2
2018-01-04 04:28



Berikut adalah beberapa pertanyaan dan jawaban StackOverflow lainnya di sepanjang baris "bagaimana Anda melakukan penggabungan saat mengabaikan beberapa file":

Yang paling sederhana yang bisa saya pikirkan, adalah menggunakan alias'Ed Merge yang akan menghapus file pribadi sebelum melakukan commit gabungan. Ini akan berhasil jika Anda bersedia hidup dengan gabungan yang tidak maju-cepat. Ini dia alias:

git config alias.merge-master-exclude-private '!git merge --no-commit --no-ff master && (git diff --name-only HEAD..master | grep -f private_files | while read f; do git reset HEAD -- "$f"; rm -f "$f"; done; git commit -m "Merge master, excluding private files.")'

Kemudian edit private_files file dan tambahkan pola file yang bersifat pribadi; sebagai contoh secret_file.*$. Anda bisa mengganti private_files dalam alias dengan "$(git rev-parse --show-toplevel)"/private_files untuk membaca private_files dari direktori level teratas.

Menggunakan git merge-master-exclude-private untuk melakukan penggabungan. Ini akan melakukan penggabungan non-fast-forward tanpa melakukan, menemukan file yang cocok dengan pola di private_files mengajukan, reset indeks file pribadi yang ditemukan, hapus file pribadi di direktori kerja, lalu komit. Ini harus menangani file yang memiliki spasi putih di nama mereka.

Jika Anda tidak ingin melakukan commit, memberi Anda kesempatan untuk mengedit pesan commit, hapus -m "Merge master, excluding private files." dari alias.


2
2018-01-13 21:28



Seorang pria bernama David Albert menulis alat yang disebut Junk untuk memecahkan hampir persis masalah ini. Ini memungkinkan file dari repositori "sampah" yang terpisah hidup berdampingan dengan yang ada di repositori utama Anda.

File-file pribadi akan memiliki komit terpisah dari yang publik, tetapi mungkin melakukan pekerjaan itu.


2
2018-01-19 17:25



Buat 2 cabang. Cabang yang memiliki file pribadi tidak akan didorong ke repo publik. Setelah penggabungan, kembalikan file yang dipermasalahkan git checkout HEAD^ -- files that should not have been merged, rm other files, git add -A dan git commit --amend -C HEAD. Saya tidak yakin apa perbedaan dalam file yang dimaksud tetapi Anda mendapatkan ide. Buatlah skrip kecil untuk ini dan Anda siap untuk pergi. Anda bahkan dapat melakukan daftar file sensitif yang Anda komit di root dan skrip bisa bertindak dari itu.


1
2018-01-04 06:24



Saya tahu ini mengesampingkan pertanyaan, tetapi saya hanya akan memiliki dua repositori git. Kemudian Anda bisa menambahkannya secara permanen ke daftar abaikan di repositori publik.

Anda dapat memiliki repositori kedua untuk file pribadi, dan skrip kecil untuk menyalin perubahan ke lokasi yang benar pada sistem produksi, saat melakukan penerapan Anda.

Ini mengurangi risiko bahwa ketika Anda pergi berlibur dan magang baru memperbarui repo publik, informasi pribadi Anda secara tidak sengaja akan bocor. ;-)


0
2018-01-17 07:25



Terlihat seperti yang bisa Anda gunakan mine.

Pada dasarnya, ini memberitahu git untuk menghindari hal-hal mengikuti konvensi <file or directory>_mine_ dan alat itu sendiri memberi Anda snapshot, clean, dan restore fungsi, bukan versi lengkap, tetapi untuk barang-barang pribadi itu melakukan trik dengan baik.

Semua ini cukup ringkas.


0
2017-08-05 03:31