Bagaimana cara mengekspor riwayat revisi dari mercurial atau git ke cvs?

100

Saya akan bekerja dengan orang lain pada kode dari proyek yang menggunakan cvs. Kami ingin menggunakan vcs terdistribusi untuk membuat pekerjaan kami dan ketika kami selesai atau mungkin sesekali kami ingin memasukkan kode kami dan semua riwayat revisi kami ke cvs. Kami tidak memiliki akses tulis ke repo cvs proyek sehingga kami tidak bisa terlalu sering melakukan. Alat apa yang dapat kita gunakan untuk mengekspor riwayat revisi ke cvs? Saat ini kami berpikir untuk menggunakan git atau mercurial tetapi kami dapat menggunakan vcs terdistribusi lain jika itu dapat mempermudah ekspor.

tatsuhirosatou
sumber
Ketika Anda mengatakan "CVS terdistribusi", saya pikir yang Anda maksud adalah "VCS terdistribusi," atau "DVCS," yang merupakan singkatan dari "sistem kontrol versi terdistribusi."
Patrick McElhaney
Maksud saya sistem kontrol versi terdistribusi.
tatsuhirosatou

Jawaban:

237

Untungnya bagi kita yang masih terpaksa menggunakan CVS, git menyediakan alat yang cukup bagus untuk melakukan apa yang ingin Anda lakukan. Saran saya (dan apa yang kami lakukan di sini di $ work):

Membuat Klon Awal

Gunakan git cvsimportuntuk menggandakan riwayat revisi CVS ke dalam repositori git. Saya menggunakan doa berikut:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout

The -Apilihan adalah opsional tapi membantu untuk membuat sejarah revisi Anda yang diimpor dari CVS terlihat lebih git-seperti (lihat man git-cvsimportuntuk info lebih lanjut tentang bagaimana hal ini sudah diatur).

Bergantung pada ukuran dan riwayat penyimpanan CVS, pengimporan pertama ini akan memakan waktu SANGAT lama. Anda dapat menambahkan -v ke perintah di atas jika Anda ingin ketenangan pikiran bahwa sebenarnya ada sesuatu yang terjadi.

Setelah proses ini selesai, Anda akan memiliki mastercabang yang seharusnya mencerminkan HEAD CVS (dengan pengecualian yang git cvsimportsecara default mengabaikan komitmen 10 menit terakhir untuk menghindari penangkapan komit yang setengah selesai). Anda kemudian dapat menggunakan git logdan teman untuk memeriksa seluruh riwayat repositori seolah-olah telah menggunakan git sejak awal.

Konfigurasi Tweaks

Ada beberapa penyesuaian konfigurasi yang akan membuat impor tambahan dari CVS (serta ekspor) lebih mudah di masa mendatang. Ini tidak didokumentasikan di git cvsimporthalaman manual jadi saya kira mereka bisa berubah tanpa pemberitahuan tetapi, FWIW:

% git config cvsimport.module cvs_module_to_checkout
% git config cvsimport.r cvs
% git config cvsimport.d $CVSROOT

Semua opsi ini dapat ditentukan di baris perintah sehingga Anda dapat melewati langkah ini dengan aman.

Impor Tambahan

Selanjutnya git cvsimportharus jauh lebih cepat daripada pemanggilan pertama. Namun, itu dilakukan cvs rlogpada setiap direktori (bahkan yang hanya memiliki file di Atticdalamnya) sehingga masih dapat memakan waktu beberapa menit. Jika Anda telah menentukan konfigurasi yang disarankan di atas, yang perlu Anda lakukan hanyalah mengeksekusi:

% git cvsimport

Jika Anda belum mengatur konfigurasi Anda untuk menentukan default, Anda harus menentukannya pada baris perintah:

% git cvsimport -r cvs -d $CVSROOT cvs_module_to_checkout

Bagaimanapun, dua hal yang perlu diingat:

  1. Pastikan Anda berada di direktori root dari repositori git Anda. Jika Anda berada di tempat lain, itu akan mencoba melakukan penyegaran cvsimportyang akan memakan waktu lama lagi.
  2. Pastikan Anda berada di mastercabang Anda sehingga perubahan dapat digabungkan (atau didasarkan kembali) ke cabang lokal / topik Anda.

Membuat Perubahan Lokal

Dalam praktiknya, saya merekomendasikan untuk selalu membuat perubahan pada cabang dan hanya menggabungkan masterketika Anda siap untuk mengekspor perubahan tersebut kembali ke repositori CVS. Anda dapat menggunakan alur kerja apa pun yang Anda suka di cabang-cabang Anda (menggabungkan, rebasing, squashing, dll) tetapi tentu saja aturan rebasing standar berlaku: jangan rebase jika ada orang lain yang mendasarkan perubahan mereka pada cabang Anda.

Mengekspor Perubahan ke CVS

The git cvsexportcommitperintah memungkinkan Anda untuk mengekspor satu komit keluar ke server CVS. Anda dapat menentukan satu ID komit (atau apa pun yang mendeskripsikan komit spesifik seperti yang didefinisikan di man git-rev-parse). Perbedaan kemudian dihasilkan, diterapkan ke pembayaran CVS dan kemudian (opsional) dikomit ke CVS menggunakan cvsklien sebenarnya . Anda dapat mengekspor setiap komitmen mikro pada cabang topik Anda, tetapi umumnya saya ingin membuat komit gabungan secara terbaru masterdan mengekspor komitmen gabungan tunggal itu ke CVS. Saat Anda mengekspor komit gabungan, Anda harus memberi tahu git induk komit mana yang akan digunakan untuk menghasilkan diff. Selain itu, ini tidak akan berfungsi jika penggabungan Anda dipercepat (lihat bagian "BAGAIMANA CARA PENGGABUNGAN" man git-mergeuntuk deskripsi tentang penggabungan maju-cepat) jadi Anda harus menggunakan--no-ffopsi saat melakukan penggabungan. Berikut contohnya:

# on master
% git merge --no-ff --log -m "Optional commit message here" topic/branch/name
% git cvsexportcommit -w /path/to/cvs/checkout -u -p -c ORIG_HEAD HEAD

Anda dapat melihat arti dari setiap opsi tersebut di halaman manual untuk git-cvsexportcommit . Anda memiliki opsi untuk menyetel -wopsi di konfigurasi git Anda:

% git config cvsexportcommit.cvsdir /path/to/cvs/checkout

Jika tambalan gagal karena alasan apa pun, pengalaman saya adalah bahwa Anda (sayangnya) mungkin lebih baik menyalin file yang diubah secara manual dan melakukan menggunakan klien cvs. Namun, hal ini tidak boleh terjadi jika Anda memastikan masterCVS sudah diperbarui sebelum menggabungkan cabang topik Anda di.

Jika komit gagal karena alasan apa pun (masalah jaringan / izin, dll), Anda dapat mengambil perintah yang dicetak ke terminal Anda di akhir keluaran kesalahan dan menjalankannya di direktori kerja CVS Anda. Biasanya terlihat seperti ini:

% cvs commit -F .msg file1 file2 file3 etc

Lain kali Anda melakukan git cvsimport(menunggu setidaknya 10 menit), Anda akan melihat patch dari komit yang Anda ekspor diimpor kembali ke repositori lokal Anda. Mereka akan memiliki ID komit yang berbeda karena komit CVS akan memiliki stempel waktu yang berbeda dan mungkin nama pelaku yang berbeda (tergantung pada apakah Anda menyiapkan file penulis di awal Anda di cvsimportatas).

Mengkloning klon CVS Anda

Jika Anda memiliki lebih dari satu orang yang perlu melakukan ini cvsimport, akan lebih efisien jika memiliki satu repositori git yang menjalankan cvsimport dan membuat semua repositori lain dibuat sebagai klon. Ini bekerja dengan sempurna dan repositori kloning dapat melakukan cvsexportcommits seperti yang dijelaskan di atas. Namun, ada satu peringatan. Karena cara CVS melakukan kembali dengan ID komit yang berbeda (seperti dijelaskan di atas), Anda tidak ingin cabang kloning Anda melacak repositori git pusat. Secara default, ini adalah cara git clonemengkonfigurasi repositori Anda tetapi ini mudah diperbaiki:

% git clone [CENTRAL_REPO_HERE]
% cd [NEW_GIT_REPO_DIR_HERE]
% git config --unset branch.master.remote
% git config --unset branch.master.merge

Setelah Anda menghapus konfigurasi ini, Anda harus secara eksplisit mengatakan di mana dan apa yang harus ditarik ketika Anda ingin menarik komit baru dari repositori pusat:

% git pull origin master

Secara keseluruhan, menurut saya alur kerja ini cukup mudah dikelola dan "hal terbaik berikutnya" saat bermigrasi sepenuhnya ke git tidaklah praktis.

Brian Phillips
sumber
3
Terima kasih. Ini sangat membantu saya, terutama tip tentang menggunakan penggabungan non-fastforward untuk menggabungkan perubahan CVS menjadi satu komit.
skiphoppy
8
Sebagai catatan, opsi -A yang Anda sarankan untuk digunakan untuk git-cvsimport disebutkan di halaman manual sebagai "tidak disarankan ... jika Anda bermaksud mengekspor perubahan kembali ke CVS nanti dengan git-cvsexportcommit (1)." Dalam kasus saya, saya sebenarnya menyukai cara penulis tampil apa adanya.
skiphoppy
2
Terima kasih atas tipnya. Satu hal praktis yang telah saya lakukan adalah menambahkan "cvs =! Git cvsimport -k -a" di bawah [alias] di .gitconfig saya. Ini membuatnya jadi "git cvs" akan DTRT (dari atas pohon).
bstpierre
1
Jika Anda melewatkan git cvsimportDebian cobaapt-get install git-cvs
Tino
5
Mac OSX mavricks sama sekali tidak memiliki cv dan tampaknya git cvsimport bergantung pada cvs. Initialized empty Git repository in /Users/gus/projects/foo/foobar/.git/ Can't exec "cvsps": No such file or directory at /Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git-cvsimport line 777. Could not start cvsps: No such file or directory git cvsimport: fatal: cvsps reported errorSayangnya, hal ini tidak membuat Anda terhindar dari tidak adanya CVS :(
Gus
22

Anda tidak boleh mempercayai cvsimport secara membabi buta dan memeriksa apakah pohon yang diimpor cocok dengan yang ada di repo CVS. Saya telah melakukan ini dengan membagikan proyek baru menggunakan plug-in CVS eclipse dan menemukan bahwa ada ketidakkonsistenan ..

Dua komit yang dilakukan dalam waktu kurang dari satu menit dengan pesan komit yang sama (untuk mengembalikan file yang salah terhapus) dikelompokkan menjadi satu komit besar, yang mengakibatkan file hilang dari pohon ..

Saya dapat mengatasi masalah ini dengan mengubah parameter 'fuzz' menjadi kurang dari satu menit.

contoh:

% git cvsimport -d $CVSROOT -C dir_to_create -r cvs -k \
  -A /path/to/authors/file cvs_module_to_checkout -z 15

Intinya: periksa pohon Anda setelah mengimpor

shil88
sumber
3

Selain jawaban Brian Phillips: ada juga git-cvsserver yang berfungsi seperti server CVS tetapi sebenarnya mengakses git repositori ... tetapi memiliki beberapa keterbatasan.

Jakub Narębski
sumber