6 poin oleh GN⁺ 2023-11-03 | 1 komentar | Bagikan ke WhatsApp
  • Git memiliki banyak duplikasi dan penggunaan ulang istilah yang tetap membingungkan meski sudah lama dipakai, sehingga sulit memprediksi perilaku sebenarnya hanya dengan menghafal perintah
  • Kata dan simbol yang sama seperti HEAD, heads, detached HEAD, ours/theirs, ../... berubah makna tergantung konteks
  • index, staged, cached semuanya terkait dengan .git/index, tetapi reset, revert, restore, meski namanya mirip, memiliki dampak berbeda pada riwayat commit, working tree, dan pointer branch
  • Track pada remote oleh main berbeda dari remote-tracking branch seperti origin/main, sementara checkout menggabungkan perpindahan branch dan pemulihan file dalam satu perintah
  • Untuk memahami Git, kita perlu melihat model internal yang mengaitkan branch, reference, commit, index, dan status remote-tracking, bukan hanya perintah individual

HEAD, branch, detached HEAD

  • Di Git, heads mengacu pada branch, dan secara internal branch disimpan di direktori .git/refs/heads
    • Glosarium resmi Git membedakan branch sebagai semua commit di atasnya dan head sebagai commit terbaru, tetapi keduanya bisa dilihat sebagai dua cara memandang objek yang sama
  • HEAD menunjuk ke branch saat ini dan disimpan di .git/HEAD
    • Ungkapan “head adalah branch, dan HEAD adalah branch saat ini” sendiri menunjukkan dengan baik kebingungan istilah Git
  • detached HEAD state adalah kondisi ketika HEAD menunjuk langsung ke ID commit, bukan ke branch
    • Jika melakukan checkout pada tag, karena tag bukan branch, kita bisa masuk ke kondisi detached HEAD
    • Dalam kondisi ini, git pull tidak bekerja, dan git push juga tidak bekerja kecuali dengan cara khusus
    • git commit, git merge, git rebase, git cherry-pick bisa dilakukan, tetapi commit baru tidak terhubung ke branch mana pun sehingga bisa sulit ditemukan
    • Kita bisa keluar dari kondisi detached HEAD dengan membuat branch baru atau berpindah ke branch yang sudah ada

ours dan theirs yang berubah pada merge dan rebase

  • Dalam penyelesaian konflik, git checkout --ours file.txt memilih file sisi “ours”, tetapi titik acuan pada merge dan rebase berbeda
  • Pada merge, branch saat ini adalah ours, sedangkan branch yang digabungkan masuk adalah theirs
    • Contoh: setelah git checkout merge-into-ours, jika menjalankan git merge from-theirs, branch saat ini menjadi ours
  • Pada rebase, branch saat ini adalah theirs, sedangkan branch target rebase adalah ours
    • Contoh: setelah git checkout theirs, jika menjalankan git rebase ours, branch target menjadi ours
  • Perbedaan ini terkait dengan cara git rebase main secara internal berulang kali menggabungkan commit dari branch saat ini ke salinan branch main
  • ourstheirs menjelaskan istilah ours dan theirs secara singkat
    • “current change” dan “incoming change” di VSCode juga bisa membingungkan dengan cara yang sama

Pesan status remote dan fast-forward

  • Your branch is up to date with 'origin/main' bukan berarti main saat ini adalah status terbaru di remote
    • Artinya branch lokal sama dengan origin/main pada saat terakhir git fetch atau git pull
    • Jika fetch terakhir dilakukan 5 hari lalu, maka “terbaru” itu berdasarkan kondisi 5 hari lalu
  • Git menyimpan informasi waktu fetch terbaru di reflog, tetapi pesan status tidak menampilkan waktu “berdasarkan fetch terakhir”
  • can be fast-forwarded berarti branch remote berada di depan branch lokal, dan karena tidak ada commit terpisah di lokal, pointer saja bisa digeser maju
    • Contoh: jika main adalah A-B-C dan origin/main adalah A-B-C-D-E, setelah git pull keduanya menjadi A-B-C-D-E
    • Dalam kasus ini tidak ada kemungkinan konflik merge
  • Jika fast-forward tidak memungkinkan, berarti kedua branch sudah bercabang
    • Contoh: jika main memiliki commit X yang tidak ada di origin/main, dan origin/main memiliki D, E yang tidak ada di main, fast-forward tidak memungkinkan
    • Saat itu Git menampilkan bahwa kedua branch berada dalam kondisi diverged dan masing-masing memiliki jumlah commit berbeda

Sintaks pemilihan commit: ^, ~, .., ...

  • HEAD^ dan HEAD~ sama-sama menunjuk ke 1 commit sebelumnya
    • HEAD^^^, HEAD~~~, HEAD~3 semuanya menunjuk ke 3 commit sebelumnya
  • Pada commit yang memiliki beberapa parent seperti merge commit, makna HEAD^2, HEAD^3 berbeda
    • HEAD^ adalah parent pertama
    • HEAD^2 adalah parent kedua
    • HEAD^3 adalah parent ketiga
    • HEAD~3 berarti parent dari parent dari parent, sehingga berbeda dari HEAD^3
  • git log main..test dan git log main...test juga bekerja secara berbeda
    • main..test menampilkan commit yang hanya ada di test
    • test..main menampilkan commit yang hanya ada di main
    • main...test menampilkan commit yang hanya ada di kedua sisi
  • Pada git diff, .. dan ... ditafsirkan berbeda dari git log
    • git diff test..main membandingkan dengan menyertakan perubahan di sisi test dan perubahan di sisi main
    • git diff test...main membandingkan common ancestor dengan ujung sisi main, sehingga hanya menampilkan diff satu sisi
  • Kebingungan notasi titik juga dibahas lebih lanjut di pain in dots

reference, refspec, tree-ish

  • Di Git, reference dipakai dengan beberapa makna
    • Branch dan tag seperti main, v0.2
    • HEAD yang menunjuk ke branch saat ini
    • Ekspresi seperti HEAD^^^ yang ditafsirkan sebagai ID commit
  • Dokumentasi Git secara ketat menyebut ekspresi seperti HEAD^^^ sebagai “revision parameters”, tetapi dalam penggunaan sehari-hari ekspresi itu bisa diperlakukan seperti reference
  • symbolic reference berarti reference yang menunjuk ke reference lain, seperti HEAD
    • HEAD adalah konsep sentral yang sangat memengaruhi perilaku perintah inti Git
  • Pengaturan remote di .git/config berisi refspec
    • Contoh: +refs/heads/main:refs/remotes/origin/main
    • Dalam banyak kasus, orang memakai apa adanya nilai yang dibuat oleh git clone atau git remote add default
  • tree-ish mengacu pada objek yang bisa menjadi THING dalam git checkout THING .
    • ID commit
    • Reference commit seperti main, HEAD^^, v0.3.2
    • Subdirektori di dalam commit seperti main:./docs
    • Dalam praktiknya, sering kali cukup dipahami sebagai “commit atau reference commit”

index, staged, cached

  • index, staged, cached semuanya terkait dengan .git/index
    • .git/index adalah file yang digunakan saat melakukan stage perubahan dengan git add
  • Istilah yang menunjuk ke hal yang sama tersebar di berbagai perintah
    • git diff --cached
    • git rm --cached
    • git diff --staged
    • .git/index
  • Namun flag --index dan --cached tidak selalu bermakna sama
    • Tulisan dari maintainer utama Git, Junio Hamano, menjelaskan perbedaan detailnya
  • Index juga mencantumkan untracked files demi alasan performa, tetapi secara umum staging area tidak dianggap mencakup untracked files

reset, revert, restore

  • reset, revert, restore adalah kata yang mirip, tetapi di Git objek yang dipengaruhinya berbeda
  • git revert COMMIT membuat commit baru di branch saat ini yang melakukan kebalikan dari COMMIT
    • Jika COMMIT menambahkan 3 baris, commit baru akan menghapus 3 baris tersebut
  • git reset --hard COMMIT secara paksa mengembalikan branch saat ini ke titik COMMIT
    • Ini operasi yang sangat berbahaya karena menghapus perubahan baru setelah COMMIT
  • git restore --source=COMMIT PATH mengembalikan file di PATH ke kondisi saat COMMIT
    • File lain atau riwayat commit tidak diubah
  • git reset --hard dan git restore . bila dipakai sendiri umumnya bekerja mirip, tetapi git reset --hard COMMIT dan git restore --source COMMIT . bekerja sangat berbeda

track, remote-tracking branch, untracked files

  • Git memakai kata track dalam tiga cara
    • Untracked files: pada git status berarti file yang tidak dikelola Git dan tidak termasuk dalam commit
    • Remote-tracking branch seperti origin/main adalah reference lokal yang berisi ID commit yang ditunjuk oleh main di remote origin pada saat terakhir git pull atau git fetch
    • Branch lokal bisa dikonfigurasi untuk track branch remote, seperti pada “branch foo set up to track remote branch bar from origin”
  • Pernyataan bahwa main adalah branch yang track remote berbeda dari pernyataan bahwa origin/main adalah remote-tracking branch
  • main adalah branch sungguhan, sehingga kita bisa membuat commit dan melakukan merge di sana
    • Jika dikonfigurasi di .git/config untuk track main remote, git pull dan git push bisa dipakai dengan nyaman
  • Meski namanya “remote-tracking branch”, origin/main bukan branch biasa
    • Tidak bisa langsung diberi commit
    • Hanya diperbarui saat mengambil status main terbaru dari remote dengan git pull atau git fetch

checkout, reflog, merge/rebase/cherry-pick

  • git checkout memasukkan dua operasi berbeda ke dalam satu perintah
    • git checkout BRANCH berpindah branch
    • git checkout file.txt membuang perubahan unstaged pada file.txt
  • Untuk mengurangi kebingungan ini, Git membagi fungsinya menjadi git switch dan git restore, tetapi checkout lama masih tetap bisa digunakan
  • reflog adalah reference log, yaitu catatan tentang apa yang pernah ditunjuk oleh sebuah reference
    • Reference adalah istilah luas yang mencakup branch, tag, dan HEAD
    • Reflog bisa membantu keluar dari situasi Git yang sangat buruk, misalnya saat tidak sengaja menghapus branch penting
  • merge, rebase, dan cherry-pick menggabungkan commit dengan cara berbeda
    • merge membuat satu commit baru yang menggabungkan dua branch
    • rebase menyalin commit dari branch saat ini satu per satu ke atas branch target
    • cherry-pick mirip dengan rebase, tetapi sintaksnya berbeda dan menyalin commit ke branch saat ini
  • git rebase --onto main otherbranch mybranch bisa dipakai untuk memindahkan hanya sebagian commit dari mybranch ke atas main
    • Dalam struktur contoh, ini bisa digunakan saat ingin me-rebase hanya F, G ke atas main
    • Sintaks ini sulit diingat karena berisi tiga nama branch

commit dan istilah membingungkan lainnya

  • commit dipakai di Git baik sebagai kata kerja maupun kata benda
    • Kata kerja: “seringlah melakukan commit”
    • Kata benda: commit terbaru di main
  • Commit Git bisa dilihat dengan tiga cara
    • Snapshot dari kondisi saat ini semua file
    • Diff terhadap commit parent
    • History dari semua commit sebelumnya
  • Setiap perintah memperlakukan commit secara berbeda
    • git show memperlakukan commit seperti diff
    • git log memperlakukan commit seperti history
    • git restore memperlakukan commit seperti snapshot
  • blob, tree, origin, upstream, downstream, hubungan fetch dan pull, stash, worktree, subtree, submodule juga termasuk istilah Git yang membingungkan
  • Di antara istilah GitHub, “pull request”, “squash and merge”, “rebase and merge” disebut sebagai contoh yang membingungkan

Tiga sumbu kebingungan yang berulang

  • Istilah Git yang sangat membingungkan dapat diringkas menjadi tiga hal
    • head adalah branch, dan HEAD adalah branch saat ini
    • “remote tracking branch” dan “branch that tracks a remote” adalah dua hal berbeda
    • index, staged, cached semuanya menunjuk ke objek yang sama
  • the most confusing git terminology dari 2012 juga membahas bagaimana istilah Git terkait dengan istilah CVS dan Subversion
  • Kebingungan istilah Git bukan hanya pada beberapa fitur khusus, tetapi berulang di seluruh fitur inti
  • Khususnya saat membahas branch, “tracking” dipakai dalam beberapa cara sehingga perbedaannya sulit disadari saat pertama melihatnya
  • Beberapa penjelasan mencakup sudut Git yang jarang dipakai, sehingga masih ada catatan bahwa mungkin terdapat kesalahan

1 komentar

 
GN⁺ 2023-11-03
Pendapat di Hacker News
  • Saya dulu sulit menghafal sebagian besar istilah ini, tetapi kunci yang membuat semuanya masuk akal adalah bahwa banyak hal di Git pada akhirnya adalah pointer yang menunjuk ke commit
    Nama branch, HEAD, dan tag semuanya adalah pointer. HEAD menunjuk ke commit yang sedang kita lihat, dan nama branch seperti my-feature menunjuk ke commit terbaru di branch itu. Jika menjalankan git checkout -b my-feature dari main, maka main, my-feature, dan HEAD semuanya akan menunjuk ke commit terbaru di main
    Setiap kali melakukan commit di my-branch, HEAD dan my-branch bergerak agar menunjuk ke commit baru. detached HEAD berarti kondisi ketika tidak ada branch yang menunjuk ke commit yang ditunjuk oleh HEAD. Perbedaan tag dan branch adalah tag menunjuk ke commit tertentu dan tidak bergerak
    Hal lain yang membingungkan adalah banyak perintah tampak tidak konsisten karena Git mengasumsikan argumen default. git checkout file.txt sama dengan git checkout HEAD -- file.txt, dan ketika berada di my-branch, git rebase main sama dengan git rebase main my-branch. Namun bentuk yang terakhir bisa dijalankan dari branch lain juga
    Terakhir, ketika semuanya kacau, perintah yang bisa mengeluarkan kita dari kondisi aneh apa pun adalah git reflog. Perintah ini menampilkan semua commit yang pernah ditunjuk oleh HEAD. Tetap saja, senang melihat Git mengakui kebingungan ini dan membuat perintah dengan antarmuka yang tidak terlalu mengejutkan dan lebih sederhana
    • Kalau memakai nama yang diberikan Git untuk konsep ini, “pointer commit” adalah refs. Karena itulah namanya reflog
      Hal lain yang sering tidak terpikir oleh banyak pengguna Git adalah bahwa ref branch atau tag remote yang sudah di-fetch juga semuanya ref, jadi bisa direferensikan di mana pun nama ref bisa dipakai
      Misalnya jika ingin berkata, “Saya tidak peduli apa isi branch ini, jangan fast-forward, jangan merge, jangan rebase, cukup timpa branch lokal dengan isi remote,” lakukan seperti ini: git checkout foo, git reset --hard origin/foo
    • Lebih tepatnya, pointer HEAD tidak menunjuk langsung ke commit; biasanya ia menunjuk ke pointer branch seperti my-branch, lalu pointer branch itu menunjuk ke commit. Kondisi detached HEAD adalah pengecualiannya
      Saat melakukan commit di my-branch, bukan HEAD dan my-branch yang sama-sama berpindah ke commit baru; HEAD tetap menunjuk ke pointer my-branch, dan hanya my-branch yang bergerak agar menunjuk ke commit baru. Tentu saja, jika mengikuti HEAD melalui my-branch sampai ke commit, kita akan sampai ke commit baru
      detached HEAD adalah kondisi ketika HEAD menunjuk langsung ke commit, bukan ke pointer branch. Bahkan dalam kondisi detached HEAD, HEAD dan pointer branch bisa sama-sama menunjuk ke commit terbaru. Jika melihat git log --decorate, alih-alih tampilan biasa (HEAD -> my-branch), pada commit terbaru biasanya akan terlihat seperti (HEAD, my-branch)
    • Penjelasan ini bagus. Namun bagian yang kadang lebih membingungkan adalah bahwa tag ada dua jenis. Sebagian besar tag adalah lightweight tag yang menunjuk ke objek commit seperti disebutkan, dan tidak lebih dari itu
      Sebaliknya, annotated tag bisa berisi pesan, timestamp, SHA, dan lain-lain. Ini adalah objek Git yang sesungguhnya dan perilakunya cukup mirip dengan objek commit, tetapi biasanya tetap mereferensikan objek Git lain, umumnya commit
    • Kalau Anda tipe yang terlalu berhati-hati seperti saya, sebelum memulai prosedur rumit yang rawan konflik atau banyak perpindahan, menjalankan git rev-parse HEAD lalu menyalin string itu ke tempat aman juga bagus
      Ada rasa tenang karena kita menandai secara persis keadaan terakhir yang diyakini benar. Biasanya kita bisa kembali ke keadaan terakhir yang baik, bukan ke titik beberapa langkah setelah masuk ke kekacauan. Tentu saja dengan asumsi tidak sembarangan memakai hal seperti git gc atau git filter-branch
    • Penjelasan ini juga menunjukkan dengan baik bahwa struktur tree internal Git-lah yang mengendalikan semuanya
      Kedengarannya seperti lelucon, tetapi sebenarnya bukan lelucon: pernyataan bahwa untuk memakai Git kita benar-benar perlu gelar ilmu komputer tidak sepenuhnya salah. Saya setuju bahwa argumen default Git menciptakan pengalaman penggunaan yang sangat tidak konsisten
      git checkout ., git reset --hard/soft, dan git cleanup semuanya tampak sangat mirip, tetapi sebenarnya sangat berbeda. Meski begitu, saya tetap lebih suka Git daripada Perforce atau SVN. Dulu saya sedikit lebih suka Mercurial, tetapi saya tidak tahu apakah masih begitu sekarang
      git reflog adalah rajanya dan menunjukkan kebenaran
  • Sudah sekitar 10 tahun sejak Git “memenangi” perang version control berkat satu lagi tren teknologi tanpa dasar yang kuat, tetapi kita masih kesulitan melakukan hal-hal yang seharusnya sepele
    Saya ingat pernah membaca tulisan bahwa Linus Torvalds terkejut orang-orang mulai memakai Git secara langsung tanpa menambahkan lapisan yang lebih ramah di atasnya. Jika industri ini mampu melakukan introspeksi, kita akan mengakui bahwa memilih Git adalah kesalahan dan pindah ke sistem version control lain. Jangan membuang waktu luar biasa banyak untuk alat yang tugasnya hanya menyimpan teks
    • Saya tidak melihat Git sebagai alat penyimpanan teks. Ini adalah alat yang mengoordinasikan perubahan yang dilakukan banyak orang pada “teks” yang sama dengan cukup presisi dan andal, tanpa menghambat progres siapa pun. Coba lakukan sekali dengan Word, perbedaannya besar
      Tentu saja masih bisa dibuat lebih baik. Namun kebencian yang diterima Git selalu mengejutkan. Git adalah alat yang hebat, dan jauh lebih maju daripada alat seperti Word atau Google Docs yang dibuat untuk non-developer
      Mungkin karena saya cukup tua untuk mengingat masa ketika Subversion masih jadi raja
    • Sangat setuju
      Setiap minggu saya melihat rekan kerja kebingungan karena Git, melihat postingan minta bantuan secara online, dan melihat lagi tulisan yang mencoba menjelaskan ulang hal yang seharusnya sederhana seperti artikel ini
      Saya tidak ingat ada orang yang saat coding membuang berjam-jam untuk membatalkan kekacauan yang mereka buat sendiri di SVN, TFVC, Perforce, dan sebagainya
      Alat ada untuk membuat hidup lebih mudah. Kalau tidak bisa melakukan itu, tidak layak menghabiskan waktu untuknya
    • Bahkan pada 2013 pun sama sekali belum jelas bahwa Git akan menang. Pengguna darcs, Mercurial, svn, bahkan cvs masih cukup banyak, dan tool pada masa itu biasanya punya plugin yang mendukung semuanya

Saya masih berharap keragaman seperti itu tetap ada. Monokultur Git juga berarti bahwa apa pun yang ingin menggantikan Git harus lebih dulu mengimplementasikan ulang Git. Jadi kita jadi terikat pada Git nyaris selamanya, seperti ASCII atau tombol Scroll Lock

  • Git menang karena alasan yang bagus, dan jelas lebih baik daripada yang sebelumnya. Sekarang mungkin sedang populer mencela Git seperti jQuery, tetapi saat muncul dulu ia merupakan perbaikan yang jelas
  • Saya baru-baru ini menulis tentang masalah serupa, mengapa kita bisa terjebak dengan Git
    Kekhawatiran utamanya adalah GitHub terlalu bagus, sehingga kita akan terikat pada Git kecuali GitHub memisahkan Git dari mesin pengelolaan teks dan mengizinkan mesin lain juga
    https://trolololo.xyz/github
    https://news.ycombinator.com/item?id=38098109
  • Terminologi Git terasa seperti studi kasus klinis: banyak istilah baru masuk akal setelah Anda memahami cara kerjanya, tetapi hampir tidak masuk akal jika Anda tidak tahu detail implementasinya atau jika diletakkan berdampingan dengan istilah lain
    Ini istilah seperti abstraksi yang bocor
    • Sebagian benar, tetapi ini juga karena bagian-bagian Git yang berbeda dibuat oleh orang yang berbeda dan diberi nama secara terpisah. Linus awalnya menyebutnya cache, istilah yang paling bernuansa ilmu komputer
      Setelah itu Junio tampaknya mengubahnya menjadi index, yang lebih spesifik untuk sistem kontrol versi terdistribusi, dan kebanyakan pengguna menyebutnya staging area. Kini evolusi istilah ini membatu seperti fosil di UI dan internal Git
    • Bukannya masuk akal; ini hanya penamaan yang ceroboh. Memberi nama yang baik butuh usaha, dan para pengembang awal Git tidak melakukannya
    • Bayangkan jika untuk penggunaan dasar Anda harus mengetahui internal sistem operasi, IDE, dan compiler; pada dasarnya itu adalah desain API yang buruk
  • “Your branch is up to date with origin/master” adalah kebohongan terbesar yang saya dengar setiap hari. Karena itu setiap kali saya langsung saja pull
    • Secara ketat itu benar. origin/master bukan master yang ada di origin, melainkan commit yang ditunjuk oleh origin/master terakhir yang diketahui. Nilai ini diperbarui saat fetch, dan pull otomatis melakukan fetch
      Jika melihat ls -l .git/refs/remotes/origin/master, Anda bisa tahu bahwa origin/master hanyalah sebuah file di sistem Anda. Anda juga bisa melihat kapan ia berubah. Ia tidak diperbarui secara ajaib
      Jika ada perubahan saat menjalankan git fetch origin, timestamp dan isinya akan berubah. Anda bisa memeriksanya dengan cat .git/refs/remotes/origin/master
      Dasar-dasar Git sangat sederhana, sampai struktur data inti dan beberapa operasi bisa diimplementasikan dalam sehari. Mengetahui hal ini benar-benar berharga. Entah bagaimana Git berhasil membangun antarmuka pengguna yang sangat rumit di atas inti yang cukup sederhana
    • Pesan itu hanya berarti Git tidak akan mengakses internet atau remote repository untuk memeriksa pembaruan kecuali diperintah secara eksplisit. Menurut saya sifat ini sendiri bagus. Hanya saja pesannya bisa dibuat lebih jelas
    • Seharusnya kira-kira “Your branch is up to date with the local copy of origin/master, last updated on XXXX-XX-XX:XX:XX:XX”
    • Saya menghapus branch master lokal. Biasanya saya tidak bisa push ke master, atau memang tidak ingin bekerja langsung di master. Kalau begitu tidak ada alasan untuk menyimpan branch master lokal yang bisa diubah
      Jadi yang perlu diperbarui hanya origin/master, dan fetch sudah cukup untuk itu
    • git fetch && git pull
      Saya menunggu hari ketika bisa pensiun 3 tahun lagi dan cuci tangan dari sampah rusak ini
  • Saya sudah memakai Git hampir sejak masa-masa awalnya, tetapi baru minggu ini mengetahui porcelain. Ada proyek yang mem-parsing output git status, dan menambahkan flag --porcelain benar-benar membantu. Ia menghasilkan output yang lebih ringkas dan lebih mudah di-parse oleh program
    Saya jadi penasaran berapa banyak command yang punya output yang lebih mudah dibaca mesin, sampai akhirnya membuka halaman “Git Internals - Plumbing and Porcelain” di git-scm. Ringkasnya, sejak awal Git ditulis lebih sebagai kumpulan alat untuk menangani version control daripada sebagai sistem version control yang terpoles
    Banyak orang yang memakai Git sejak awal mempelajari tugas-tugas version control lewat command level rendah ini, lalu menyebarkan workflow itu ke orang lain. Inilah lapisan plumbing. Belakangan Git membuat lapisan yang lebih dipoles, yang disebut porcelain
    Saya masih belum sepenuhnya tahu command mana masuk lapisan yang mana, tetapi ini membantu saya memahami workflow baru yang direkomendasikan dalam beberapa tahun terakhir. Ini juga membuat saya bisa menilai lebih baik saat mengubah workflow saya sendiri
    https://git-scm.com/book/en/v2/Git-Internals-Plumbing-and-Po...
    • Ini sinyal jelas bahwa Linus puas dengan plumbing, yaitu struktur internalnya, tetapi menganggap porcelain, yaitu UI-nya, perlu dibenahi. Awalnya semua porcelain adalah skrip yang memanggil plumbing
      Sayangnya, untuk membuatnya lebih cepat mereka meng-hardcode UI itu, tetapi tidak memperbaikinya
  • Gaya menulis Julia benar-benar bagus. Ia menulis hal yang sangat bernilai bahkan bagi developer veteran, sambil tetap mempertahankan nada yang ramah dan tidak mengecualikan orang yang baru masuk ke bidang ini
  • Sepertinya saya terkena “sindrom Stockholm Git”. Istilah-istilah ini tidak terasa begitu membingungkan, tetapi sepertinya itu terutama karena saya hampir tidak mempelajari sistem lain dan sudah sangat terikat pada Git sejak sekitar 2011
    Kalau dipikir-pikir, saat pertama mulai saya pasti sangat kebingungan, tetapi sepertinya saya pura-pura tidak begitu agar terlihat keren
    • Setelah melihat CLI sistem version control Fossil, saya sadar bahwa saya memang punya sindrom Stockholm. Terlalu intuitif
    • Sebelum memakai Git saya memakai cvs dan svn, dan dibanding svn, Git jauh lebih mudah dipahami
    • Satu-satunya version control lain yang pernah saya pakai adalah Plastic SCM, dan entah itu sindrom Stockholm atau bukan, Git jauh lebih baik
  • Hal-hal yang layak dilihat juga: Git staging area secara harfiah adalah istilah yang disepakati semua orang

https://news.ycombinator.com/item?id=28143078
“Your branch is up to date with ‘origin/main’” sebenarnya agak menyesatkan. Itu bisa dipahami sebagai berarti branch main sudah terbaru, padahal sebenarnya tidak demikian
Namun tidak perlu terlalu menempelkan “secara ketat” pada hal ini. Bukankah masalah dua jenderal berlaku di sini? Kalau benar-benar ditelisik dengan sangat teliti, kita tidak bisa tahu apakah tepat pada saat ini ia “terbaru”. Bahkan jika melakukan fetch sebelum status, tetap sama
Jadi apa ekspektasi yang masuk akal? Kira-kira bahwa ref yang ada di database objek di komputer saya sama dengan ref di database objek lain yang jauh di sana saat terakhir kali diperiksa
Pemanggilan status sederhana tidak bisa melakukan fetch jaringan, atau setiap kali mengingatkan prinsip dasar alat yang sedang dipakai. Setidaknya menurut saya begitu. Namun mengejutkannya, banyak komentar di jawaban StackOverflow justru menganggap keduanya diperlukan
Frasa seperti “is up to date with the origin’s main as of your last fetch 5 days ago” lebih masuk akal. Karena itu hanya memberi tahu sudah berapa lama sejak terakhir kali fetch dilakukan
[1] https://stackoverflow.com/questions/27828404/why-does-git-st...
Satu lagi: saya sempat mengira ORIG_HEAD terkait dengan “origin’s head” seperti FETCH_HEAD. Ternyata bukan. “Pseudoref” ini tampaknya dipakai sebagai titik simpan sebelum penulisan ulang yang lebih kompleks seperti rebase, dan diimplementasikan sebelum reflog ada. Mungkin maksudnya “original head”

  • Saya cukup pro-Git, tetapi soal redaksi pesan itu saya setuju dengan penulis. Hanya saja saya tidak setuju dengan alternatif yang dia usulkan
    “Your branch is up to date with ‘origin/main’” secara teknis benar, tetapi ungkapan up to date jika dibaca sekilas menyiratkan dua hal. Bahwa main sama dengan origin/main, dan origin/main juga terbaru; dengan kata lain terasa seperti baru diperbarui saat perintah dijalankan, atau otomatis dijaga tetap terbaru dan sinkronisasi terbaru berhasil
    Ini bukan sinyal yang dibaca mesin dan harus benar selama satu siklus CPU, melainkan pesan status yang terlihat oleh pengguna. Tanpa membawa-bawa teori jaringan pun, interpretasi seperti itu masuk akal
    “Up to date” lebih dekat artinya dengan sudah mengejar secara waktu, bukan ruang. Posisi branch lokal lebih dekat ke ruang, yaitu “branch ini menunjuk ke mana”, sedangkan status ref remote lebih dekat ke waktu, yaitu “kapan terakhir kali saya memperbarui ref remote”. Tentu saja ini sangat subjektif dan keduanya bisa bermakna dua arah
    Redaksi yang lebih baik bisa berupa “Your branch matches origin/main”, “Your branch’s head is the same as origin/main”, atau “Your branch is pointing to the same commit as origin/main”. Ini kompromi antara kejelasan dan kepanjangan. Seperti usulan penulis, bisa juga ditambahkan dalam tanda kurung “remote ref last updated 5 days ago”
  • Saya tidak setuju bahwa pemanggilan status yang melakukan fetch jaringan itu menjengkelkan. Menurut saya operasi jaringan harus eksplisit, bukan implisit. Saat menjalankan git status, saya ingin mengetahui status repository saya yang ada di sistem file
    Kalau ingin tahu apa yang terjadi di remote lain, saya bisa melakukan fetch sendiri lalu membandingkannya
  • Yang diharapkan adalah mendapatkan informasi terbaru berdasarkan saat perintah status dimulai. Memang bisa ada race condition saat informasi dicetak ke terminal, tetapi itu jendela waktu yang sangat kecil
    Secara umum ini berarti menginginkan fetch. Masalah dua jenderal hanya berlaku di sisi remote. Jika remote tidak menerima konfirmasi bahwa klien sudah menerima data, remote bisa terus mengirim ulang untuk sementara waktu. Itu bukan masalah klien
    Jika klien tidak menerima data dari server, perilaku yang benar mestinya berhenti lalu menampilkan error setelah timeout, dan kemungkinan fetch saat ini memang melakukan itu
  • Tahap paling berharga dalam mempelajari Git adalah memiliki model mental yang benar. Semuanya adalah graf
    Alat ini sering dibagikan, dan cocok juga di sini. Ia memvisualisasikan model internal Git dan efek dari berbagai perintah
    https://learngitbranching.js.org/
    Yang saya pelajari dari memakai alat ini 10 menit lebih banyak daripada sekitar 10 tahun pengalaman Git sebelumnya. Sangat direkomendasikan
  • Saya tidak ingin menambah lagi, tetapi fakta bahwa orang-orang Bitbucket menciptakan istilah pull request juga bermasalah
    “pull” adalah tindakan menggabungkan perubahan remote ke repository lokal. Yang sebenarnya diminta pengguna adalah agar server menggabungkan perubahan remote miliknya ke sebuah branch. Istilah GitLab, “merge request”, adalah ungkapan yang tepat
    Saya pernah melihat seseorang melakukan fetch lalu commit menghilang. Itu tersembunyi karena repository bergerak mundur dalam waktu. Git menyembunyikan detail seperti itu di status, jadi kalau tidak memakai git-prompt atau powerline-shell, rasanya bekerja dalam gelap
    • Ide awal yang tersisa di git-request-pull(1) adalah bahwa kita semua punya repository Git masing-masing di tempat seperti kernel.org/git atau redhat.com/git, lalu meminta lewat email agar orang lain melakukan pull dari repository yang berada di server, organisasi, dan domain berbeda
      GitHub terinspirasi oleh perintah request-pull milik Git, tetapi menafsirkannya ulang sebagai penggabungan dari satu repository GitHub ke repository GitHub lain
    • Dari sudut pandang server, pengguna adalah remote dan server adalah lokal. Jadi pengguna meminta server untuk melakukan pull dari pihak pengguna
      Setidaknya saya selalu membacanya begitu
    • Buku Git menjelaskan asal-usul istilah ini dan mengapa istilah itu masuk akal
      Ringkasnya, itu bukan permintaan kepada server, melainkan permintaan kepada orang lain. Kita meminta orang tersebut untuk melakukan pull branch kita agar ia meninjau perubahan yang ingin kita kontribusikan ke proyek

[0] https://git-scm.com/book/en/v2/Distributed-Git-Contributing-...

  • “pull request” dipopulerkan oleh GitHub, dan menurut saya istilah itu cukup baik. Perbedaan apakah sebenarnya melakukan pull dari repositori lain atau membuat “merge request” di dalam repositori yang sama tidak terlalu menarik. “merge request” terasa seperti istilah khas GitLab
  • Ini selalu yang paling sulit saya pahami. Rasanya tentu saja seharusnya bukan pull request, melainkan push request atau merge request