Git Minimum yang Layak untuk Pengembangan Berbasis Batang

Nov 30 2022
Lebih sedikit lebih baik dalam hal alat yang kuat — dan terlalu rumit — seperti Git Eli adalah salah satu pendiri dan Co-CEO dari trunk.io.

Lebih sedikit lebih baik dalam hal alat yang kuat — dan terlalu rumit — seperti Git

Eli adalah salah satu pendiri dan Co-CEO dari trunk.io . Dia memegang posisi kepemimpinan teknik di Microsoft, Uber, dan Google (yang mengakuisisi startup yang dia dirikan bersama). Fokus utamanya adalah membantu tim membangun perangkat lunak yang lebih baik, lebih cepat.

Git Inferno Dante

Berkembang dalam lingkungan kolaboratif adalah operasi rumit yang melibatkan pelacakan dan koordinasi pekerjaan dari banyak pengembang. Banyak dari kita menggunakan Git sebagai kontrol versi untuk menangani semua perubahan ini. Namun dalam kata-kata Linus sendiri , Git adalah “manajer informasi dari neraka”. Ini menawarkan begitu banyak opsi dan status aneh, Anda dapat dengan mudah menemukan diri Anda berada di tempat yang buruk hingga Anda perlu mengkloning ulang dari awal — bahkan jika Anda tidak melakukan kesalahan apa pun.

Banyak dari kita tahu bahwa satu pengembang yang mempelajari referensi Git dan pohon Merkle yang mendasarinya, tetapi menjadi ahli Git mungkin tidak ada dalam deskripsi pekerjaan Anda. Saya dapat mengendarai mobil dengan sangat baik tanpa memahami cara kerja transmisi yang sebenarnya, dan pada akhirnya, Git hanyalah alat untuk mencapai tujuan.

Untuk mendapatkan hasil maksimal dari Git, Anda harus menggunakannya sesedikit mungkin untuk pengembangan berbasis trunk. Batasi perintah yang Anda gunakan, perbarui cabang fitur Anda dengan benar, dan standarkan penggunaan sebagai sebuah tim. Secara individu, Anda dapat menikmati kebebasan untuk melakukan apapun yang Anda inginkan. Tapi sebagai sebuah tim, harga kebebasan dibayar dengan gesekan.

Batasi tindakan Git Anda

Praktik termudah untuk diterapkan untuk efisiensi puncak Git adalah tetap berpegang pada subset perintah. Git dapat melakukan banyak hal, tetapi sebagian besar kekuatannya hanya ada untuk membantu Anda keluar dari situasi yang mengerikan. Jumlah perintah yang diizinkan Git versus jumlah perintah yang harus Anda panggil sangat berbeda.

Saya pernah diminta oleh CTO untuk memberikan kelas git lanjutan kepada tim tekniknya. Tanggapan saya sederhana:

pada saat Anda membutuhkan git tingkat lanjut — roda mobil sudah terlepas. mari kita fokus menggunakan inti git dengan benar.

Berikut adalah 10 perintah git yang saya gunakan untuk menyelesaikan pekerjaan sambil meminimalkan berapa kali saya mendarat di Git hell:

Manajemen Cabang

git checkout -t -b {branch-name}
Buat cabang, atur upstream ke cabang saat ini, dan alihkan ke sana. Anda juga dapat melakukan ini melalui perintah `git branch`, tetapi dibutuhkan banyak perintah. Karena saya selalu ingin beralih ke cabang saat saya membuatnya, perintah ini lebih ringkas. Buat dan checkout cabang dalam satu gerakan. Saya biasanya menamai semua cabang saya eli/{work-being-done}.

git checkout {branch-name}
Beralih ke cabang.

git branch -vv
Lihat cabang Anda saat ini dan hulunya.

git branch -D {branch-name}
Hapus cabang lokal, biasanya untuk membersihkan cabang basi/digabung menjadi utama.

Mendorong & Menarik

git fetch origin main:main
Tarik remote mainke lokal Anda main, bahkan saat Anda tidak sedang berada di maincabang! Itulah ; sangat berguna saat Anda mencoba menggabungkan yang terbaru mainke dalam cabang PR.

git push origin
Dorong kode saya ke remote; kemungkinan memutar banyak mesin di CI untuk memeriksa pekerjaan saya.

git pull
Perbarui cabang lokal saya dengan remote dengan nama yang sama.

Berkomitmen

git add -A .
Tambahkan semua yang sedang saya kerjakan (file baru dan yang diedit).

git commit -am "work"
Lihat di sini untuk menyelami pemikiran saya tentang pesan komit lokal

git merge main
Lebih banyak tentang ini di bawah ini. Saya pragmatis dan bukan rebaser dan senang memperkeruh cabang lokal saya dengan kejadian dari main.

Selalu perbarui cabang fitur Anda dengan benar

Di bagian terakhir saya , saya membahas bagaimana mengelola kode arahan ke main. Namun seringkali selama pengembangan, dan tentu saja sebelum penggabungan, Anda harus mengetahui perubahan terbaru mainkarena:

  • Anda memerlukan beberapa fitur yang ada mainuntuk melakukan pekerjaan fitur Anda.
  • Sesuatu mainberubah dan jika Anda tidak mengambilnya, Anda akan merusaknya saat Anda mencoba memasukkan kode Anda.
  • Anda hanya ingin tetap segar karena Anda seorang insinyur dan menyukai hal-hal baru yang berkilau.

Pintu 1: git merge

Ini adalah strategi gabungan saya. Ini sederhana, andal, dan tanpa embel-embel. Dasar git mergemengambil semua perubahan yang terjadi maindan menggabungkannya sebagai komit bersama perubahan Anda. Anda dapat membaca iklan yang memuakkan tentang kerugian dari solusi tanpa embel-embel ini, tetapi sejujurnya saya hanya mengangkat bahu dan berkata, "Saya tidak peduli tentang itu." Jika Anda menggabungkan cabang pekerjaan Anda, mainmaka semua omong kosong tentang polusi git-log menjadi hanya itu.

Sejujurnya tidak masalah bagaimana/mengapa/apa yang masuk ke cabang pekerjaan saya. Yang penting adalah — apakah ini dibuat, berfungsi, dan apakah kode melakukan apa yang saya inginkan? Selebihnya akademik.

Dalam praktiknya, dan saya seorang insinyur yang sangat praktis, git mergememungkinkan Anda untuk menangani konflik gabungan dengan bersih dan kembali membangun. Anda menyelesaikan setiap konflik penggabungan satu kali — dan Anda siap melakukannya. Ini adalah opsi terbaik untuk pemula, pengguna tingkat lanjut yang sibuk, dan Anda yang tidak bermimpi menjadi guru Git.

Pintu 2: git rebase

Ini adalah pilihan terburuk sejauh ini. Oke, saya tahu; praktis ada satu generasi yang melihat rebase vs menggabungkan sesuatu seperti tab vs spasi. Tetapi dalam proyek "nyata", di mana satu atau banyak tim bergabung ke repo setiap hari, rebase membutuhkan penyelesaian n konflik gabungan alih-alih satu dengan rebase gabungan atau squash (lebih lanjut di bawah).

Selain itu, setiap rebasing akan menulis ulang riwayat Git, dan itu berarti jika cabang Anda memiliki mitra jarak jauh, Anda perlu git push --forcemenginjak-injak riwayatnya dengan riwayat rebase baru cabang Anda. Ini bagus secara teori tetapi berpotensi untuk secara tidak sengaja menghapus pekerjaan Anda sebelumnya dengan cara yang sangat sulit untuk dipulihkan. Ini jauh lebih berbahaya daripada penggabungan dan sejujurnya membuat saya pusing hanya dengan memikirkannya.

Untuk tujuan artikel ini, saya mencoba mengubah basis hanya untuk mengingatkan diri sendiri betapa saya tidak menyukai alur kerja ini. Lihat apa yang dimuntahkan oleh perintah rebase sederhana ke terminal saya:

alur kerja yang baik seharusnya tidak memerlukan petunjuk untuk dikerjakan

Ada banyak kesalahan dengan terminal itu. Saya mendapat catatan tentang komit hash - tidak ingin melihatnya. Saya mendapatkan empat baris petunjuk kuning untuk mengingatkan saya bagaimana semua ini bekerja. Dan saya sekarang dalam beberapa alur kerja hanya untuk mendapatkan kode dari maincabang saya. Pohon keputusan itu sangat rumit; git rebase --skip- apa itu?! Mengapa boleh melewatkan komit? Kamu tahu apa? Jangan beritahu saya karena saya memiliki pekerjaan yang harus dilakukan.

Pintu 3: git squash rebase

Anda pasti tidak menginginkan apa yang ada di balik pintu #2, tetapi beberapa orang adalah rebaser yang tangguh. Co-founder saya, co-CEO David Apirian, telah menunjukkan kepada saya pintu masuk rahasianya ke belakang panggung untuk rebase dan itu luar biasa. Kami akan menyebutnya squash rebase .

Saya telah menegaskan kembali pentingnya kesederhanaan Git, tetapi dengan pendekatan ini, Anda dapat memiliki rebase dan memakannya juga. Anda mendapatkan lapisan ajaib dari rebase tanpa kegilaan aliran rebase standar. Dengan rebase squash, Anda dapat:

  • Lihat perbedaan dari komitmen lokal Anda sebelum mendorong ke GitHub.
  • Batalkan komit terakhir Anda dengan mudah.
  • Hindari mencemari pandangan GitHub tentang permintaan penarikan Anda dengan banyak komitmen lokal kecil.

Langkah 1 — hancurkan semua komitmen lokal Anda:

git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message

git rebase main

Anda dapat menyatukan semua ini menjadi satu perintah uber untuk menarik main terbaru, menghancurkan semua komit Anda, dan mengubah basis pada main terbaru:

git reset --soft $(git merge-base HEAD main) &&
git commit -am "" --allow-empty-message &&
git fetch origin main:main &&
git rebase main

[alias]
 smartcommit = !git add -A . && git commit -am "" --allow-empty-message
 squash = !git reset --soft $(git merge-base HEAD main) && git commit -am "" --allow-empty-message
 squashrebase = !git squash && git fetch origin main:main && git rebase main
 smart = !git smartcommit && git squashrebase

Salah satu aspek yang lebih keren dari selalu menekan komitmen lokal Anda adalah bahwa di atas Anda git logadalah semua pekerjaan yang telah Anda lakukan di cabang. Pekerjaan lokal Anda sekarang lebih mirip dengan tampilan PR yang digabungkan dengan squash saat mendarat di main.

Anda dapat kapan saja melepaskan komit terakhir dari HEAD dengan cabang lokal Anda dan melihat semua pekerjaan yang telah Anda lakukan main. Ini mirip dengan tampilan mendetail yang diberikan GitHub tentang apa yang berubah, tetapi memungkinkan Anda untuk tetap berada di terminal dan menghindari peralihan yang membingungkan di antara dua UI yang berbeda.

Saya harus mengakui bahwa pertama kali David menunjukkan kepada saya alur kerja ini, saya terkesan. Dia sebagian besar telah membunuh rebasenaga dan kemampuan untuk melihat secara lokal semua file yang telah Anda ubah di cabang Anda sangat keren.

Sementara squash rebasing membantu Anda mempertahankan kondisi aliran yang lebih baik, sebagian besar pengembang lebih baik menggabungkan saja. Menggunakan rebase atau squash rebase secara tidak benar akan mengakibatkan gesekan yang mematikan produktivitas.

Perangkap bantuan cabang GitHub

kotak centang ini di GitHub tampaknya membantu… tetapi ternyata tidak

GitHub menawarkan pengaturan ini ☝️ untuk menyarankan penggabungan mainsecara otomatis ke cabang Anda jika kedaluwarsa. Pengaturan ini seringkali kontra-produktif. Saya ingin cabang lokal saya menjadi satu-satunya sumber kebenaran untuk PR saya, dan tidak ada orang lain (termasuk GitHub) yang mendorongnya. Bekerja dengan GitHub di cabang pribadi saya harus menjadi jalan satu arah. Saya membuat kode secara lokal dan mendorong.

Jika Anda mengonfigurasi GitHub untuk mulai mendorong pembaruan ke cabang pekerjaan Anda, Anda meminta lalu lintas untuk mulai menuju ke arah yang salah. Dan itu resep untuk rasa sakit.

Masalah ini muncul juga ketika peninjau kode memberi Anda sedikit saran komit pada permintaan penarikan Anda dan Anda dengan senang hati menerapkannya. Jika Anda kemudian melakukan pekerjaan apa pun di cabang lokal Anda sebelum menarik perubahan itu… Anda telah membuka sedikit masalah.

Saya sering menemukan bahwa saya tidak sengaja melakukan ini pada diri saya sendiri ketika saya mencoba mendorong pembaruan saya kembali ke jarak jauh dan git memberi tahu saya bahwa saya tidak sinkron. Pada saat itu, saya memiliki dua opsi:

  1. git push --forcedan menerbangkan apa pun di remote bukan di cabang lokal Anda. Umumnya segala sesuatu dengan kata kekuatan bersifat merusak dan membuat putus asa.
  2. git merge origin/{my-work-branch}untuk menggabungkan perubahan jarak jauh ke dalam tampilan lokal cabang.

Pengaturan GitHub ini ️☝️ membutuhkan PR untuk diperbarui mainsebelum bergabung ke dalamnya. Ini umumnya “memecahkan” potensi untuk rusak main; namun, ini hanya berfungsi dengan repo berkecepatan sangat rendah. Begitu segelintir pengembang mencoba menggabungkan beberapa PR per hari, mereka akhirnya berlomba untuk bergabung main— atau mendapati diri mereka terus-menerus melakukan penggabungan/rebase mainke cabang mereka untuk menjadi "terbaru" lagi, dan pada dasarnya berlomba dengan rekan kerja mereka menjadi yang pertama bergabung. Menyakitkan. Biasanya jika Anda menginginkan fitur ini tetapi Anda bukan pengembang tunggal, Anda mungkin menginginkan antrean gabungan — yang merupakan cara yang dapat diskalakan untuk mencapai induk tanpa kerusakan. Ini adalah sesuatu yang kami rasa cukup penting untuk diproduksi dengan Trunk Merge .

Minimalkan Git untuk nilai maksimum

Dengan menjaga penggunaan Git Anda sesederhana mungkin, Anda memberi pengembang lebih sedikit tali untuk menggantung diri dan lebih banyak waktu untuk melakukan pekerjaan pengembangan yang benar-benar penting. Jadikan Git sebagai peran pendukung, dan bukan menjadi protagonis. Untuk mempertahankan lingkungan pengembangan yang waras dan kolaboratif, ingatlah untuk:

  • Pilih area permukaan Git terkecil untuk digunakan dan pertahankan.
  • Selalu kelola perubahan upstream Anda dengan cara yang sama.
  • Standarisasikan praktik di seluruh tim Anda sehingga rekan-rekan Anda juga tidak keluar jalur.