SVN: ekuivalen eksternal dalam Git?

177

Saya memiliki dua proyek SVN yang digunakan dari repositori SVN lain menggunakan svn: externals .

Bagaimana saya bisa memiliki struktur tata letak repositori yang sama di Git?

dsimard
sumber
Anda harus melihat ke dalam submit Git . Itu harus memungkinkan apa yang Anda cari.
foxxtrot
7
Adakah yang punya jawaban baru untuk ini dalam 4 tahun terakhir, atau apakah dunia git sama dengan hari ini?
DougW
4
@ DougW Ya, saya punya jawaban baru di bawah ini : git submodulesekarang dapat ditiru svn:external(sejak Maret 2013).
VonC
Untuk versi terbaru dari Git saya sarankan untuk membaca tentang submodules Git dalam dokumentasi resmi Git.
Bulki S Maslom

Jawaban:

134

Git memiliki dua pendekatan yang mirip dengan, tetapi tidak persis setara dengan svn: eksternal:

  • Subtree menggabungkan masukkan kode proyek eksternal ke dalam sub-direktori terpisah dalam repo Anda. Ini memiliki proses terperinci untuk diatur dan kemudian sangat mudah bagi pengguna lain, karena secara otomatis disertakan ketika repositori diperiksa atau dikloning. Ini bisa menjadi cara yang nyaman untuk memasukkan ketergantungan dalam proyek Anda.
    Mudah untuk menarik perubahan dari proyek lain, tetapi rumit untuk mengirimkan perubahan kembali. Dan jika proyek lain harus bergabung dari kode Anda, sejarah proyek akan digabung dan dua proyek secara efektif menjadi satu.

  • Git submodules ( manual ) tautan ke komit tertentu di repositori proyek lain, seperti svn: eksternal dengan-rargumen. Submodules mudah diatur, tetapi semua pengguna harus mengelola submodula, yang tidak secara otomatis disertakan dalam checkout (atau klon).
    Meskipun mudah untuk mengirimkan perubahan kembali ke proyek lain, hal itu dapat menyebabkan masalah jika repo telah berubah. Oleh karena itu umumnya tidak pantas untuk mengirimkan perubahan kembali ke proyek yang sedang dalam pengembangan aktif.

Paul
sumber
17
FYI, sekarang mungkin untuk menentukan revisi spesifik dengan svn: eksternal sekarang (sejak 1,5 atau 1,6 saya percaya?)
Nate Parsons
9
FYI, git submodules dapat dikelola dan dikomit secara otomatis. git membuat file .gitmodules yang dapat / harus dikomit seperti halnya file .gitignore. Lihat [ git-scm.com/book/en/Git-Tools-Submodules] untuk informasi lebih lanjut.
mikijov
5
@NateParsons Selalu dimungkinkan untuk menentukan angka revisi yang tepat svn:externals. Dengan revisi 1.5, sintaks diubah ke format yang lebih fleksibel. Apa yang ditambahkan adalah pengalamatan URL relatif.
David W.
@NateParsons tetapi apakah mungkin untuk menghilangkan revisi dengan
submit
Saya pikir tidak mungkin untuk mengirimkan file tunggal submodule seperti dengan svn: externals
user1911091
38

Seperti yang saya sebutkan dalam " Pembaruan versi baru submodule Git ", Anda dapat mencapai fitur eksternal SVN yang sama dengan submitula Git 1.8.2:

git config -f .gitmodules submodule.<path>.branch <branch>

Ini cukup untuk submodule untuk mengikuti cabang (seperti dalam komit TERBARU dari cabang terpencil dari repo hulu submodule ). Yang perlu Anda lakukan adalah:

git submodule update --remote

Itu akan memperbarui submodule.

Detail lebih lanjut ada di " git submodulepelacakan terbaru ".

Untuk mengonversi submodule yang ada menjadi satu pelacakan cabang : lihat semua langkah di " Git submodules: Tentukan cabang / tag ".

VONC
sumber
Bisakah Anda melakukan checkout sebagian dengan svn:externals?
nowox
@nowox Ya, Anda dapat melakukan checkout jarang (git 1.7+ stackoverflow.com/a/2372044/6309 ) yang terkait dengan submodules ( stackoverflow.com/a/17693008/6309 )
VonC
sayangnya semua jawaban yang berhubungan dengan checkout jarang tidak pernah memberikan contoh :( Saya akan mencoba untuk menulis contoh
inti
Masih ada masalah dengan ini. Anda masih harus mendapatkan seluruh riwayat repositori di mana Anda hanya perlu satu bagian kecil. Dalam kasus saya adalah 100kB lebih dari 2GB. Tentu saja saya bisa menggunakan --depthtetapi itu tidak benar-benar mengatasi masalah.
nowox
@nowox Yang terbaik adalah mengajukan pertanyaan baru yang menjelaskan dengan tepat kasus penggunaan Anda: Saya tidak tahu apakah repo 2GB Anda adalah submodule, atau repo utama dengan submodule, dan apa yang sebenarnya Anda perlu ekstrak darinya.
VonC
3

Saya penulis alat gil (git links)

Saya punya solusi alternatif untuk masalah - gil (git links) tool

Hal ini memungkinkan untuk menggambarkan dan mengelola dependensi repositori git yang kompleks.

Juga memberikan solusi untuk masalah dependensi submodules git rekursif .

Pertimbangkan Anda memiliki dependensi proyek berikut: grafik dependensi repositori sampel git

Kemudian Anda dapat mendefinisikan .gitlinksfile dengan deskripsi relasi repositori:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

Setiap baris menggambarkan tautan git dalam format berikut:

  1. Nama unik repositori
  2. Jalur relatif repositori (dimulai dari jalur file .gitlinks)
  3. Repositori git yang akan digunakan dalam perintah git clone Cabang repositori untuk checkout
  4. Baris kosong atau baris yang dimulai dengan # tidak diuraikan (diperlakukan sebagai komentar).

Akhirnya Anda harus memperbarui repositori sampel root Anda:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

Sebagai hasilnya, Anda akan mengkloning semua proyek yang diperlukan dan menghubungkannya satu sama lain dengan cara yang benar.

Jika Anda ingin mengkomit semua perubahan dalam beberapa repositori dengan semua perubahan dalam repositori terkait anak Anda dapat melakukannya dengan satu perintah:

gil commit -a -m "Some big update"

Perintah pull, push bekerja dengan cara yang sama:

gil pull
gil push

Alat Gil (git links) mendukung perintah berikut:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

Lebih lanjut tentang masalah ketergantungan submodul git rekursif .

chronoxor
sumber
1
Anda harus meletakkan penafian di bagian atas posting yang mengatakan bahwa Anda adalah penulis gil.
Daniel Kamil Kozar