Solusi sederhana: Hapus cabang 'kerja' setelah penggabungan
Jawaban singkat: Anda dapat menggunakan git sesuka Anda (lihat di bawah untuk alur kerja sederhana), termasuk penggabungan. Pastikan saja mengikuti setiap ' git merge work ' dengan ' git branch -d work ' untuk menghapus cabang kerja sementara.
Penjelasan latar belakang:
Masalah penggabungan / dcommit adalah bahwa setiap kali Anda 'git svn dcommit' cabang, riwayat gabungan cabang itu 'diratakan': git lupa tentang semua operasi penggabungan yang masuk ke cabang ini: Hanya isi file dipertahankan, tetapi fakta bahwa konten ini (sebagian) berasal dari cabang lain yang spesifik hilang. Lihat: Mengapa git svn dcommit kehilangan riwayat komit gabungan untuk cabang lokal?
(Catatan: Tidak banyak yang bisa dilakukan git-svn tentang hal itu: svn sama sekali tidak memahami penggabungan git yang jauh lebih kuat. Jadi, di dalam repositori svn, informasi penggabungan ini tidak dapat direpresentasikan dengan cara apa pun.)
Tapi ini adalah seluruh masalah. Jika Anda menghapus cabang 'work' setelah digabungkan ke dalam 'cabang master' maka repositori git Anda 100% bersih dan terlihat persis seperti repositori svn Anda.
Alur kerja saya:
Tentu saja, saya pertama kali mengkloning repositori svn remote ke repositori git lokal (ini mungkin membutuhkan waktu):
$> git svn clone <svn-repository-url> <local-directory>
Semua pekerjaan kemudian terjadi di dalam "direktori-lokal". Setiap kali saya perlu mendapatkan pembaruan dari server (seperti 'pembaruan svn'), saya lakukan:
$> git checkout master
$> git svn rebase
Saya melakukan semua pekerjaan pengembangan saya di 'pekerjaan' cabang terpisah yang dibuat seperti ini:
$> git checkout -b work
Tentu saja, Anda dapat membuat cabang sebanyak mungkin untuk pekerjaan Anda dan menggabungkan serta menyusun ulang di antara mereka sebanyak yang Anda inginkan (hapus saja ketika Anda selesai melakukannya --- seperti yang dibahas di bawah). Dalam pekerjaan normal saya, saya sangat sering melakukan:
$> git commit -am '-- finished a little piece of work'
Langkah selanjutnya (git rebase -i) adalah opsional --- itu hanya membersihkan sejarah sebelum mengarsipkannya di svn: Setelah saya mencapai batu stabil mil yang ingin saya bagikan dengan orang lain, saya menulis ulang sejarah 'pekerjaan' ini cabang dan bersihkan pesan komit (pengembang lain tidak perlu melihat semua langkah kecil dan kesalahan yang saya buat di jalan --- hanya hasilnya). Untuk ini, saya lakukan
$> git log
dan salin hash sha-1 dari commit terakhir yang aktif di repositori svn (seperti yang ditunjukkan oleh git-svn-id). Lalu aku menelepon
$> git rebase -i 74e4068360e34b2ccf0c5869703af458cde0cdcb
Cukup tempel sha-1 hash svn commit terakhir kami alih-alih milikku. Anda mungkin ingin membaca dokumentasi dengan 'git help rebase' untuk detailnya. Singkatnya: perintah ini pertama kali membuka editor yang menyajikan komit Anda ---- cukup ubah 'pilih' menjadi 'squash' untuk semua komit yang ingin Anda hancurkan dengan komit sebelumnya. Tentu saja, baris pertama harus tetap sebagai 'pick'. Dengan cara ini, Anda dapat menyingkat banyak komitmen kecil Anda menjadi satu atau lebih unit yang berarti. Simpan dan keluar dari editor. Anda akan mendapatkan editor lain yang meminta Anda untuk menulis ulang pesan log komit.
Singkatnya: Setelah saya menyelesaikan 'peretasan kode', saya memijat cabang 'pekerjaan' saya sampai terlihat bagaimana saya ingin mempresentasikannya kepada programmer lain (atau bagaimana saya ingin melihat pekerjaan dalam waktu beberapa minggu ketika saya menelusuri sejarah) .
Untuk mendorong perubahan ke repositori svn, saya lakukan:
$> git checkout master
$> git svn rebase
Sekarang kita kembali ke cabang 'master' lama yang diperbarui dengan semua perubahan yang terjadi pada waktu yang bersamaan di repositori svn (perubahan baru Anda disembunyikan di cabang 'kerja').
Jika ada perubahan yang mungkin berbenturan dengan perubahan 'pekerjaan' baru Anda, Anda harus menyelesaikannya secara lokal sebelum Anda mendorong pekerjaan baru Anda (lihat detail lebih lanjut di bawah). Kemudian, kita bisa mendorong perubahan kita ke svn:
$> git checkout master
$> git merge work # (1) merge your 'work' into 'master'
$> git branch -d work # (2) remove the work branch immediately after merging
$> git svn dcommit # (3) push your changes to the svn repository
Catatan 1: Perintah 'git branch -d work' cukup aman: Perintah ini hanya memungkinkan Anda untuk menghapus cabang yang tidak Anda perlukan lagi (karena mereka sudah bergabung ke cabang Anda saat ini). Jika Anda mengeksekusi perintah ini secara tidak sengaja sebelum menggabungkan pekerjaan Anda dengan cabang 'master', Anda mendapatkan pesan kesalahan.
Catatan 2: Pastikan untuk menghapus cabang Anda dengan 'git branch -d work' antara penggabungan dan dcommit: Jika Anda mencoba untuk menghapus cabang setelah dcommit, Anda mendapatkan pesan kesalahan: Ketika Anda melakukan 'git svn dcommit', git lupa bahwa cabang Anda telah digabung dengan 'master'. Anda harus menghapusnya dengan 'git branch -D work' yang tidak melakukan pemeriksaan keamanan.
Sekarang, saya segera membuat cabang 'pekerjaan' baru untuk menghindari peretasan di cabang 'master' secara tidak sengaja:
$> git checkout -b work
$> git branch # show my branches:
master
* work
Mengintegrasikan 'pekerjaan' Anda dengan perubahan pada svn:
Inilah yang saya lakukan ketika 'git svn rebase' mengungkapkan bahwa orang lain mengubah repositori svn ketika saya sedang mengerjakan cabang 'work' saya:
$> git checkout master
$> git svn rebase # 'svn pull' changes
$> git checkout work # go to my work
$> git checkout -b integration # make a copy of the branch
$> git merge master # integrate my changes with theirs
$> ... check/fix/debug ...
$> ... rewrite history with rebase -i if needed
$> git checkout master # try again to push my changes
$> git svn rebase # hopefully no further changes to merge
$> git merge integration # (1) merge your work with theirs
$> git branch -d work # (2) remove branches that are merged
$> git branch -d integration # (2) remove branches that are merged
$> git svn dcommit # (3) push your changes to the svn repository
Ada solusi yang lebih kuat:
Alur kerja yang disajikan sederhana: Menggunakan kekuatan git hanya dalam setiap putaran 'update / hack / dcommit' --- tetapi meninggalkan sejarah proyek jangka panjang sama linearnya dengan repositori svn. Ini tidak apa-apa jika Anda hanya ingin mulai menggunakan git merge dalam langkah pertama kecil dalam proyek svn lawas.
Ketika Anda menjadi lebih akrab dengan git gabung, silakan menjelajahi alur kerja lainnya: Jika Anda tahu apa yang Anda lakukan, Anda dapat mencampur git gabung dengan svn merge ( Menggunakan git-svn (atau serupa) hanya untuk membantu penggabungan svn? )