Struktur Repositori Mercurial dengan komunikasi perusahaan kelas berat, manajemen konfigurasi & persyaratan pengujian

16

Saya adalah pengguna Subversion lain yang berjuang untuk mendidik kembali diri saya sendiri dalam Tao tentang kontrol versi terdistribusi.

Ketika menggunakan Subversion, saya adalah penggemar berat pendekatan proyek-kecil, dan, dengan sebagian besar mantan majikan saya, kami akan menyusun cabang repositori kami; tag & trunk sebagai berikut:

branches-+
         +-personal-+
         |          +-alice-+
         |          |       +-shinyNewFeature
         |          |       +-AUTOMATED-+
         |          |                   +-shinyNewFeature
         |          +-bob-+
         |                +-AUTOMATED-+
         |                            +-bespokeCustomerProject
         +-project-+
                   +-shinyNewFeature
                   +-fixStinkyBug
tags-+
     +-m20110401_releaseCandidate_0_1
     +-m20110505_release_0_1
     +-m20110602_milestone
trunk

Di dalam pohon sumber itu sendiri, kami akan menggunakan (seperti) struktur berikut:

  (src)-+
        +-developmentAutomation-+
        |                       +-testAutomation
        |                       +-deploymentAutomation
        |                       +-docGeneration
        |                       +-staticAnalysis
        |                       +-systemTest
        |                       +-performanceMeasurement
        |                       +-configurationManagement
        |                       +-utilities
        +-libraries-+
        |           +-log-+
        |           |     +-build
        |           |     +-doc
        |           |     +-test
        |           +-statistics-+
        |           |            +-build
        |           |            +-doc
        |           |            +-test
        |           +-charting-+
        |           |          +-build
        |           |          +-doc
        |           |          +-test
        |           +-distributedComputing-+
        |           |                      +-build
        |           |                      +-doc
        |           |                      +-test
        |           +-widgets-+
        |                     +-build
        |                     +-doc
        |                     +-test
        +-productLines-+
        |              +-flagshipProduct-+
        |              |                 +-coolFeature
        |              |                 +-anotherCoolFeature
        |              |                 +-build
        |              |                 +-doc
        |              |                 +-test
        |              +-coolNewProduct
        +-project-+
                  +-bigImportantCustomer-+
                  |                      +-bespokeProjectOne
                  |                      +-bespokeProjectTwo
                  +-anotherImportantCustomer-+
                                             +-anotherBespokeProject

Idenya adalah (dan masih) menggunakan struktur repositori untuk membantu struktur komunikasi antara tim teknik; bagian bisnis yang menghadap pelanggan dan berbagai pemangku kepentingan lainnya & pakar domain.

Intinya: Sumber dokumen yang duduk di salah satu direktori "proyek" biasakan (dan dapatkan uang) hanya sekali. Dokumen yang berada di salah satu direktori "productLines" menghasilkan uang sebanyak produk yang dijual. Dokumen yang berada di salah satu direktori "perpustakaan" menghasilkan uang sebanyak produk mana pun yang menggunakannya dijual.

Itu membuat gagasan amortisasi biaya eksplisit, dan membantu membangun dukungan untuk penggunaan kembali dokumen sumber di seluruh bisnis.

Ini juga berarti bahwa ada struktur umum di mana alat otomasi bangunan kami dapat beroperasi. (Skrip build kami menjalankan hierarki sumber mencari folder "build" di mana mereka menemukan file konfigurasi yang menentukan bagaimana setiap komponen akan dibangun; proses serupa terjadi untuk pembuatan dan pengujian dokumentasi).

Secara signifikan, produk tempat saya bekerja biasanya membutuhkan waktu yang lama untuk menjalankan tes pengukuran & karakterisasi kinerja; dari 20 hingga 200 jam; menghasilkan suatu tempat antara beberapa GB hingga beberapa TB hasil uji yang diproses / data antara (yang harus disimpan dan diikat ke konfigurasi sistem tertentu sehingga peningkatan kinerja dari waktu ke waktu dapat diukur). Masalah ini membuat manajemen konfigurasi menjadi pertimbangan penting, dan juga memaksakan beberapa persyaratan untuk sentralisasi, karena biasanya sumber daya komputasi yang diperlukan untuk menjalankan pengukuran kinerja dan tes karakterisasi terbatas; (sekelompok kecil 64-128 core).

Sebagai satu catatan akhir; sistem integrasi berkelanjutan tahu bahwa ia perlu memicu pembangunan; analisis statis; uji asap & uji unit dijalankan setiap kali trunk dimodifikasi, setiap kali "tag" cabang diubah, dan setiap kali cabang "OTOMATIS" dimodifikasi. Dengan cara ini, pengembang individu dapat menggunakan sistem CI dengan cabang pribadi mereka, kemampuan penting, IMHO.

Sekarang, inilah pertanyaan saya: Bagaimana saya bisa meniru semua hal di atas (dan memperbaikinya, jika mungkin), dengan Mercurial.

--edit:

Cara berpikir saya saat ini adalah menggunakan Repositori Subversion pusat, untuk menentukan struktur keseluruhan, tetapi untuk memungkinkan penggunaan hg sebagai klien sehingga pengembang dapat memiliki repo tersedia secara lokal.

William Payne
sumber
1
Wow. Jawaban yang bagus untuk ini adalah esai yang sangat panjang.
Ed James
Saya pikir pertanyaan kuncinya adalah bagaimana dan di mana penggabungan kode akan terjadi karena itu mungkin akan menentukan jalur resistensi paling sedikit. Jadi, bagaimana kode digabungkan?
Wyatt Barnett
Biasanya, gabungan mungkin datang dari cabang pribadi ke proyek atau cabang fitur, dan kemudian ke bagasi. Saya tidak pernah mengalami terlalu banyak kesulitan dengan penggabungan (kami menggunakan TortoiseSVN pada Win32), meskipun kami tidak pernah berlari terlalu lama (paling banyak satu iterasi) tanpa mengintegrasikan kembali ke bagasi. Kami cenderung melakukan sebagian besar pekerjaan kami di bagasi, walaupun tujuannya adalah untuk menyederhanakan manajemen manusia daripada alur kerja pengembangan. (Salah satu pengembang utama, banyak pengembang yang bekerja secara independen, sehingga memiliki semua yang ada di dalam bagasi membuatnya lebih mudah di pengembangan pemimpin tersebut untuk melacak apa yang sedang terjadi.)
William Payne
Satu titik kunci adalah ketergantungan yang kuat pada pengujian yang didorong oleh sistem CI, terutama pada tingkat pengujian sistem. Ini untuk membantu membangun kepercayaan bahwa pengembang yang berbeda tidak mengganggu satu sama lain, dan untuk mempromosikan mentalitas iterasi-kecil. (Juga, beban berat komputasi yang diperlukan untuk menjalankan tes sistem berarti bahwa ada lebih sedikit pertentangan untuk sumber daya komputasi jika orang bekerja terutama pada trunk).
William Payne

Jawaban:

10

Jawaban Spoike sangat bagus, tetapi ada beberapa hal yang menurut saya layak untuk ditambahkan yang terlalu besar untuk dikomentari.

Organisasi cabang

Dengan Mercurial Anda dapat dengan senang hati mengabaikan seluruh bagan organisasi pertama Anda. Seperti yang dikatakan Spoke, setiap repositori memiliki set tag, cabang (nama dan anonim) sendiri dan dapat diatur sesuai dengan kebutuhan bisnis.

Jika bespokeProjectTwomemerlukan versi khusus chartingperpustakaan, maka Anda akan bercabang charting, menambahkan fasilitas baru dan menggunakannya bespokeProjectTwo. Fasilitas baru (dan bug mereka) tidak akan digunakan oleh proyek lain yang akan merujuk chartingperpustakaan standar . Jika chartingpustaka utama memiliki bug yang diperbaiki, Anda bisa menggabungkan perubahan itu ke cabang. Jika proyek lain juga membutuhkan fasilitas ini, Anda bisa mendapatkan proyek tersebut untuk menggunakan cabang khusus , atau menggabungkan cabang ke dalam jalur utama dan menutup cabang.

Juga, tidak ada yang menghentikan Anda memiliki kebijakan untuk struktur nama cabang untuk menyediakan fasilitas spesifik seperti cabang OTOMASI Anda.

Organisasi direktori

Tidak ada alasan mengapa Anda tidak dapat menyimpan direktori sumber Anda persis seperti Mercurial. Satu-satunya perbedaan adalah bahwa sedangkan dengan Subversion Anda memiliki (src)repositori monolitik tunggal , dengan Mercurial Anda lebih baik membelah menjadi repositori yang secara logis dikelompokkan. Dari struktur pohon sumber Anda, saya mungkin akan mengekstrak masing-masing berikut ini sebagai repositori individu:

src-+
      +-(developmentAutomation)
      +-libraries-+
      |           +-(log)
      |           +-(statistics)
      |           +-(charting)
      |           +-(distributedComputing)
      |           +-(widgets)
      +-productLines-+
      |              +-(flagshipProduct)
      |              +-(coolNewProduct)
      +-project-+
                +-bigImportantCustomer-+
                |                      +-(bespokeProjectOne)
                |                      +-(bespokeProjectTwo)
                +-anotherImportantCustomer-+
                                           +-(anotherBespokeProject)

Ini memungkinkan setiap produk atau proyek yang dipesan lebih dahulu untuk menggunakan kombinasi perpustakaan, pada revisi apa pun. Lihatlah sub-repositori lincah untuk mengetahui cara mudah mengelola perpustakaan mana yang digunakan untuk versi produk atau proyek apa pun.

Alur kerja

Alternatif untuk alur kerja Spoike yang disarankan (pengembang menarik dari repo yang diberkati, bekerja secara lokal, mengeluarkan permintaan tarik dan akhirnya integrator menarik perubahan itu & menggabungkannya) akan menggunakan sistem integrasi berkelanjutan sebagai perantara.

Seperti sebelumnya, pengembang menarik dari repo yang diberkati dan bekerja secara lokal, tetapi ketika selesai, mereka menarik dari repo yang diberkati lagi dan menggabungkan diri sebelum mendorong ke repo yang tidak diberkati. Setiap perubahan pada repo yang tidak diberkati kemudian ditinjau (baik secara manual atau otomatis) dan dipindahkan ke repo yang diberkati hanya jika disetujui.

Ini berarti bahwa integrator hanya menerima atau menolak perubahan, tidak melakukan penggabungan. Dalam pengalaman saya, hampir selalu lebih baik bagi pengembang yang menulis kode untuk melakukan penggabungan daripada bagi orang lain untuk melakukannya.

Seperti yang disarankan dalam buku lincah, kait dapat digunakan untuk mengotomatisasi prosedur ini:

Ketika seseorang mendorong set perubahan ke server yang menarik semua orang, server akan menguji set perubahan sebelum menerima itu sebagai permanen, dan menolaknya jika gagal melewati rangkaian uji. Jika orang hanya menarik perubahan dari server pemfilteran ini, itu akan berfungsi untuk memastikan bahwa semua perubahan yang ditarik orang telah diperiksa secara otomatis.

Masalah lain

Masalah dataset uji besar juga dapat diselesaikan dengan menempatkan data uji ke dalam sub-repositori mercurial . Ini akan mencegah repositori kode membengkak dengan data uji, sambil tetap menjaga data uji di bawah kontrol revisi.

Mark Booth
sumber
Sekali lagi, jawaban lain yang sangat bagus dan informatif. Terima kasih.
William Payne
RE: Organisasi Cabang. Saya setuju bahwa bagan organisasi pertama dapat dengan senang hati diabaikan. Itu tidak mengomunikasikan alur kerja dengan sangat baik, jadi tidak menyediakan utilitas nyata di luar memperkuat konvensi. Saya ingin menggantinya, dengan sesuatu yang sangat mengomunikasikan alur kerja (sesederhana mungkin), dan mendorong sering melakukan. Mungkin memanggil cabang utama "trunk / development" setiap hari akan melakukan itu?
William Payne
RE: Organisasi Direktori. Saya menggunakan organisasi direktori sumber sebagai sarana komunikasi bawah sadar; memaksakan struktur tersirat pada organisasi kode (dan melalui itu pada bisnis secara keseluruhan). Saya mulai mengerti bahwa Mercurial cenderung digunakan dengan cara yang sangat sangat fleksibel; tapi saya benar-benar ingin membatasi fleksibilitas itu untuk memaksakan struktur pada cara orang berpikir tentang bisnis dengan memaksakan struktur pada cara dokumen mereka diorganisasikan di stasiun kerja dan area penyimpanan jaringan kami. (Lebih banyak komunikasi korporat daripada teknologi.)
William Payne
RE: Alur kerja. Saya berpikir bahwa alur kerja yang paling sederhana adalah dengan menarik dari repositori "harian", mengerjakannya secara lokal, lalu (sering) mendorong kembali ke repositori "harian", memulai analisis statis, tes asap & tes regresi melalui sistem CI. Saya senang repo utama menjadi "rusak", selama saya tahu tentang hal itu, dan selama itu diperbaiki lagi dengan cepat. Bahkan, saya sedang mempertimbangkan untuk membuat komitmen pada repo "harian" satu - satunya cara agar seseorang dapat menyusun & membangun, untuk mendorong seringnya komitmen & cakupan pengujian yang baik. (Jauh lebih penting daripada kemampuan untuk bekerja dalam isolasi, IMHO).
William Payne
@ WillillPayne - Terima kasih. Meskipun Mercurial fleksibel, dengan repositori, cabang, dan kait yang tepat, Anda dapat membangun dalam batasan apa pun yang Anda inginkan, di tingkat organisasi atau repositori. Secara pribadi, saya akan mulai hanya dengan kontrol organisasi, dan beberapa pengait CI, dan memperluas kontrol tersebut di masa depan ketika kebutuhan mereka menjadi jelas. Selain itu, penggunaan sub-repo secara bijaksana dapat, misalnya, mendorong orang memeriksa berbagai hal secara lokal dalam struktur yang sama seperti pada server, misalnya dengan memiliki productLinesatau bigImportantCustomersebagai super-repo.
Mark Booth
9

Oke, mencoba menjawab ini dengan sederhana.

Apa yang perlu Anda ketahui

Hal pertama yang perlu Anda ketahui: Mercurial adalah kontrol versi terdistribusi dan memiliki beberapa properti yang harus Anda ketahui tercantum di bawah ini.

  • Sumber berasal dari satu repositori, tempat repositori itu dapat dikloning. Semua repositori yang dikloning dapat berbagi kode satu sama lain melalui sinkronisasi (dengan perintah tarik dan tekan, yang dapat dibatasi akses).
  • Setiap pengguna yang memiliki salinan kode, memiliki tiruan dari repositori. Jika mereka ingin bercabang, mereka dapat melakukannya di klon lokal mereka. Itu berarti Anda tidak perlu mengatur bagaimana setiap pengguna harus bercabang. Mereka dapat melakukan ini untuk diri mereka sendiri.
  • Tag dibuat dalam mercurial oleh komit (yang sama dengan tag keras di git). Ini berarti Anda tidak perlu direktori di dalam struktur repositori Anda untuk tag.
  • Model yang biasa digunakan orang dalam DVCS (yang digunakan di github dan bitbucket) adalah melakukannya secara semi-terpusat.

    Setiap pengguna memiliki repositori publik (dalam beberapa bagian atau pada server yang aman) dan repositori pribadi (di workstation mereka sendiri). Keduanya adalah klon dari repositori integrator "diberkati". Setiap kali mereka merasa siap untuk mempublikasikan kode mereka, mereka dapat mendorong perubahan dari ke repositori publik mereka. Integrator kemudian dapat memilih pengguna mana yang akan menarik kode ke dalam repositori "diberkati".

    Jika integrator tidak dapat menggabungkan beberapa kode pengguna dengan mudah, maka perubahan ditolak dan terserah kepada pengguna tertentu untuk memperbarui repositori mereka dan memperbaiki sendiri gabungan tersebut. Biasanya tidak terlalu sulit jika Anda sering menggabungkan (karena lebih sedikit kode yang perlu digabung) dan biasanya pengguna tersebut harus tahu apa yang salah dengan merger.

Pengaturan repositori per proyek

Jadi pengaturan yang biasa adalah bahwa untuk setiap proyek ada yang berikut:

  • Repositori baca-saja publik yang menjadi tanggung jawab integrator. Itu "diberkati".

    Yaitu semua pengguna dapat menarik / mengambil konten tetapi tidak memiliki akses untuk mendorongnya.

  • Setiap pengguna dapat memiliki klon publik sendiri dari repositori.

    Pengaturan termudah yang dimasukkan ke drive share (meskipun Anda mungkin mempertimbangkan hosting seperti bitbucket). Integrator menerima permintaan tarik dari pengguna dan mencoba menarik kode baru dari repositori ini. Ketika penggabungan dilakukan tanpa hambatan, dimasukkan ke dalam repositori read-only. Jika tidak, maka pengguna diminta untuk memperbaiki konflik gabungan yang muncul dengan memperbarui dan menggabungkannya untuk diri mereka sendiri secara lokal.

  • Setiap pengguna dapat memiliki klon pribadi dari repositori mereka sendiri.

    Praktik yang baik adalah menarik dari klon publik mereka, tetapi tidak masalah jika mereka menarik dari publik mereka atau integrator. Semua komit dapat diidentifikasi secara unik sehingga menggabungkan komit yang Anda lupa untuk ambil di publik yang relatif mudah untuk diperbaiki (dengan mendorong perubahan dari privat ke publik, secara otomatis mendapat perubahan integrator juga).

Organisasi kode sumber

Seperti cara mengatur sumber proyek itu sendiri adalah sesuatu yang perlu Anda pikirkan. Jika suatu artefak perlu dikendalikan sumbernya maka taruh dalam kendali sumber. Secara pribadi saya tidak suka ide memeriksa artefak yang dibuat oleh build atau runtime (karena risiko tinggi konflik penggabungan pada jenis artefak ini) seperti biner atau file log.

Anda juga dapat memeriksa konfigurasi, selama memungkinkan pengembang untuk melanjutkan dan tidak mengacaukan konfigurasi untuk rilis atau lingkungan live / produksi (seperti pengaturan aplikasi / server web). Ini mengarah pada anggapan bahwa jika konfigurasi yang Anda lakukan secara serius menghambat pengembang untuk memulai dalam waktu lima menit setelah mereka memeriksa kode, maka itu perlu dilakukan refactored. Persyaratan lain adalah harus sangat sulit bagi pengembang untuk mengacaukan rilis atau lingkungan live / produksi.

Anda menyebutkan bahwa Anda memiliki data uji yang perlu dikaitkan dengan beberapa versi kode. Sekarang ini sedikit rumit karena sistem-DVCS seperti Mercurial dan Git memiliki kecenderungan untuk menjadi lambat ketika Anda memeriksa data yang BESAR. Dalam pengalaman saya itu menjadi sangat tak tertahankan setelah 5 GB file biner (jarak tempuh Anda mungkin berbeda, jadi Anda harus menguji cara kerjanya untuk Anda). Namun saya akan merekomendasikan agar Anda memasukkan data yang dihasilkan ke dalam repositori itu sendiri dan meminta sistem pengujian Anda untuk menandainya dengan benar saat memeriksanya (dan / atau membuat file teks untuk tujuan data meta yang sama).

Saya harap ini semua masuk akal. Berikan komentar di bawah jika saya melewatkan beberapa detail atau jika ada sesuatu yang perlu dijelaskan lebih lanjut dan saya akan mencoba mengedit.

Spoike
sumber
+1 untuk respons yang sangat bagus dengan beberapa poin yang sangat berguna. Menanggapi bagian pertama dari jawaban Anda, saya belum memahami pentingnya setiap pengguna memiliki repositori publik mereka sendiri. Mungkin saya perlu berpikir lebih banyak tentang bagaimana alur kerja peer-to-peer dapat diatur.
William Payne
Menanggapi bagian kedua dari jawaban Anda, seluruh poin (dalam pikiran saya) memiliki satu repositori untuk seluruh organisasi adalah untuk menciptakan citra mental bersama tentang bagaimana pekerjaan disusun, dan untuk membuatnya lebih mudah untuk menemukan komponen yang dapat digunakan kembali. (Sangat banyak Katedral daripada Bazaar, tapi itu adalah lingkungan tempat saya bekerja). Saya benar-benar ingin tahu cara mencapai rasa organisasi terstruktur yang sama (sistem pengarsipan) dengan DCVS.
William Payne
Menanggapi bagian ketiga dari jawaban Anda: Saya setuju dengan sepenuh hati bahwa sistem kontrol sumber adalah untuk dokumen sumber, dan artefak turunan tidak termasuk di sana. Saya juga setuju bahwa tidak praktis untuk menyimpan binari besar dari setiap deskripsi di VCS. Namun, saya yakin Anda dapat menyimpan binari besar di lokasi jaringan yang disepakati, dengan nama yang ditentukan, dan merujuknya dari dalam VCS. Misalnya, lingkungan build dapat disimpan dengan nama image disk VM, dan dirujuk dari berbagai skrip build. (mis: membangun saya di build_env_A). Hal yang sama berlaku untuk data uji.
William Payne
Di masa lalu, saya telah menggunakan hierarki direktori pada drive jaringan, di mana nama direktori diturunkan dari nomor revisi subversi + hash lokasi cabang untuk mengikat file perantara & hasil pengujian dengan revisi tertentu. Ini berarti bahwa kami memiliki keterlacakan tanpa perlu menyimpan file turunan dalam kontrol versi.
William Payne