Bagaimana cara saya bekerja dengan repositori git di dalam repositori lain?

284

Saya memiliki repositori media Git tempat saya menyimpan semua file master dan skrip JavaScript dan CSS yang akan saya gunakan di berbagai proyek.

Jika saya membuat proyek baru yang berada di repositori Git sendiri, bagaimana cara menggunakan file JavaScript dari repositori media saya di proyek baru saya dengan cara yang membuatnya jadi saya tidak perlu memperbarui kedua salinan skrip ketika saya membuat perubahan ?

Brent O'Connor
sumber
Silakan lihat jawaban subtree di bawah ini dari @ ruslan-kabalin. Catatan: kait pra-komitmen (atau terlalu banyak berkomitmen ) adalah salah satu cara untuk menangani keberatan yang diajukan oleh Robert Dundon
Hedgehog

Jawaban:

348

Kuncinya adalah git submodules .

Mulai membaca bab Submodules dari Buku Komunitas Git atau Manual Pengguna

Katakanlah Anda memiliki repositori PROJECT1, PROJECT2, dan MEDIA ...

cd /path/to/PROJECT1
git submodule add ssh://path.to.repo/MEDIA
git commit -m "Added Media submodule"

Ulangi pada repo lainnya ...

Sekarang, yang paling keren adalah, bahwa setiap kali Anda melakukan perubahan pada MEDIA, Anda dapat melakukan ini:

cd /path/to/PROJECT2/MEDIA
git pull
cd ..
git add MEDIA
git commit -m "Upgraded media to version XYZ"

Ini baru mencatat fakta bahwa submodule MEDIA DALAM PROYEK2 sekarang di versi XYZ.

Ini memberi Anda kontrol 100% untuk versi MEDIA apa yang digunakan setiap proyek. git submodules sangat bagus, tetapi Anda perlu bereksperimen dan mempelajarinya.

Dengan kekuatan besar datang peluang besar untuk digigit di pantat.

gahooa
sumber
Alur kerja ini mengingatkan saya pada penggunaan modul NPM pribadi stackoverflow.com/questions/7575627/…
cyrf
Jika Anda lebih suka default menjadi versi terbaru, Anda dapat menambahkan skrip untuk menyebarkan komitmen MEDIA ke semua proyek yang bergantung.
jiggunjer
3
Bagaimana ini berintegrasi dengan github?
theonlygusti
27

Pertimbangkan untuk menggunakan subtree daripada submodules, ini akan membuat hidup pengguna repo Anda lebih mudah. Anda dapat menemukan panduan lebih rinci dalam buku Pro Git .

Ruslan Kabalin
sumber
6
Berikut ini adalah artikel informatif lainnya mengenai subtree vs. submodule: blogs.atlassian.com/2013/05/...
Benny Neugebauer
3
Per artikel itu, salah satu kelemahannya adalah:> Tanggung jawab untuk tidak mencampur kode super dan sub proyek dalam komitmen ada pada Anda. Tidak ada yang punya waktu untuk itu (IMO)
Robert Dundon
20

Jika saya memahami masalah Anda dengan baik, Anda menginginkan hal-hal berikut:

  1. Simpan file media Anda dalam satu repositori git tunggal, yang digunakan oleh banyak proyek
  2. Jika Anda memodifikasi file media di salah satu proyek di mesin lokal Anda, itu akan segera muncul di setiap proyek lain (jadi Anda tidak ingin melakukan + push + pull sepanjang waktu)

Sayangnya tidak ada solusi utama untuk apa yang Anda inginkan, tetapi ada beberapa hal yang dengannya Anda dapat membuat hidup Anda lebih mudah.

Pertama, Anda harus memutuskan satu hal penting: apakah Anda ingin menyimpan untuk setiap versi di repositori proyek Anda referensi ke versi file media? Jadi misalnya jika Anda memiliki proyek bernama example.com, apakah Anda perlu tahu style.css mana yang digunakan 2 minggu lalu, atau yang terbaru selalu (atau sebagian besar) yang terbaik?

Jika Anda tidak perlu mengetahuinya, solusinya mudah:

  1. buat repositori untuk file media dan satu untuk setiap proyek
  2. buat tautan simbolis dalam proyek Anda yang menunjuk ke repositori media yang dikloning secara lokal. Anda dapat membuat tautan simbolis relatif (mis. ../Media) dan menganggap bahwa semua orang akan checkout proyek sehingga direktori media berada di tempat yang sama, atau menulis nama tautan simbolis ke .gitignore, dan semua orang dapat memutuskan di mana ia meletakkan file media.

Namun, dalam sebagian besar kasus, Anda ingin mengetahui informasi versi ini. Dalam hal ini Anda memiliki dua pilihan:

  1. Simpan setiap proyek dalam satu repositori besar. Keuntungan dari solusi ini adalah Anda hanya akan memiliki 1 salinan repositori media. Kerugian besar adalah bahwa jauh lebih sulit untuk beralih di antara versi proyek (jika Anda checkout ke versi yang berbeda, Anda akan selalu memodifikasi SEMUA proyek)

  2. Gunakan submodula (seperti yang dijelaskan dalam jawaban 1). Dengan cara ini Anda akan menyimpan file media dalam satu repositori, dan proyek hanya akan berisi referensi ke versi repo media tertentu. Tetapi dengan cara ini Anda biasanya memiliki banyak salinan lokal dari repositori media, dan Anda tidak dapat dengan mudah memodifikasi file media di semua proyek.

Jika saya jadi Anda, saya mungkin akan memilih solusi pertama atau ketiga (tautan simbolik atau submodula). Jika Anda memilih untuk menggunakan submodul, Anda masih dapat melakukan banyak hal untuk membuat hidup Anda lebih mudah:

  1. Sebelum melakukan, Anda dapat mengganti nama direktori submodule dan menaruh symlink ke direktori media umum. Saat Anda siap untuk melakukan, Anda dapat menghapus symlink dan menghapus kembali submodule, dan kemudian melakukan.

  2. Anda dapat menambahkan salah satu salinan repositori media Anda sebagai repositori jarak jauh ke semua proyek Anda.

Anda dapat menambahkan direktori lokal sebagai remote dengan cara ini:

cd /my/project2/media
git remote add project1 /my/project1/media

Jika Anda memodifikasi file di / my / project1 / media, Anda dapat mengkomitnya dan menariknya dari / my / project2 / media tanpa mendorongnya ke server jauh:

cd /my/project1/media
git commit -a -m "message"
cd /my/project2/media
git pull project1 master

Anda bebas untuk menghapus komit ini nanti (dengan reset git) karena Anda belum membagikannya dengan pengguna lain.

gyim
sumber
1
untuk proyek terkait web di mana Anda bekerja dari dalam wwwfolder Apache , Anda harus meletakkan .htaccessfile di root baik wwwfolder atau proyek Anda, dengan Options +FollowSymLinksdi dalamnya, atau lebih baik lagi <IfModule mod_rewrite.c>{new line}Options +FollowSymLinks{new line}RewriteEngine on{new line}</IfModule> (ganti {new line}dengan baris baru yang sebenarnya`)
3

Saya punya masalah dengan subtree dan submodules yang disarankan jawaban lain ... terutama karena saya menggunakan SourceTree dan sepertinya cukup bermasalah.

Sebagai gantinya, saya akhirnya menggunakan SymLinks dan itu sepertinya berfungsi dengan baik sehingga saya mempostingnya di sini sebagai alternatif yang memungkinkan.

Ada panduan lengkap di sini: http://www.howtogeek.com/howto/16226/complete-guide-to-symbolic-links-symlinks-on-windows-or-linux/

Tetapi pada dasarnya Anda hanya perlu mklink kedua jalur dalam command prompt yang ditinggikan. Pastikan Anda menggunakan awalan tautan keras / J. Sesuatu di sepanjang baris ini: mklink / JC: \ projects \ MainProject \ plugins C: \ projects \ SomePlugin

Anda juga dapat menggunakan jalur folder relatif dan menaruhnya di kelelawar untuk dieksekusi oleh setiap orang ketika mereka pertama kali memeriksa proyek Anda.

Contoh: mklink / J. \ Asset \ TaqtileTools .. \ TaqtileHoloTools

Setelah folder ditautkan, Anda mungkin perlu mengabaikan folder di dalam repositori utama yang merujuknya. Kalau tidak, Anda baik untuk pergi.

Catatan Saya telah menghapus jawaban rangkap saya dari pos lain karena kiriman itu ditandai sebagai pertanyaan rangkap untuk pertanyaan ini.

ickydime
sumber