6 poin oleh GN⁺ 2024-05-27 | 1 komentar | Bagikan ke WhatsApp
  • Ini adalah PDF yang merangkum tugas-tugas yang sering membuat buntu di Git agar bisa cepat dicari, seperti membuat commit, berpindah branch, membandingkan perubahan, sinkronisasi remote, dan perintah membatalkan perubahan
  • Alur kerja lokal berpusat pada git status, git add, git commit, dan git diff, dengan cara memeriksa status sebelum dan sesudah staging lalu membuat commit
  • Pekerjaan branch ditangani dengan git switch, git checkout, git branch, git merge, git rebase, dan git cherry-pick untuk membuat, berpindah, menggabungkan, dan menyusun ulang
  • Penelusuran riwayat dan pemulihan mencakup git log, git blame, git show, git reflog, git reset, dan git restore, serta branch, tag, HEAD, dan branch remote juga bisa dipakai sebagai referensi commit
  • Pekerjaan repository remote membahas prosedur mengambil dan mengirim perubahan dengan git remote add, git fetch, git pull, git push, git push --force-with-lease, dan git push --tags

Memulai repository dan memeriksa status saat ini

  • Memulai repository baru:
    • git init
  • Mengkloning repository yang sudah ada:
    • git clone $URL
  • Memeriksa lokasi dan status saat ini:
    • git status

Menyiapkan dan membuat commit

  • Menambahkan file yang belum dilacak:
    • git add $FILE
  • Menambahkan semua file yang belum dilacak dan semua perubahan yang belum di-stage:
    • git add .
  • Memilih hanya sebagian perubahan file untuk di-stage:
    • git add -p
  • Menghapus atau memindahkan file:
    • git rm $FILE
    • git mv $OLD $NEW
  • Mengecualikan file dari pelacakan Git tanpa menghapus file tersebut:
    • git rm --cached $FILE
  • Membatalkan semua staging:
    • git reset HEAD
  • Membuat commit:
    • git commit
    • Membuka editor teks untuk menulis pesan
  • Commit dengan langsung menentukan pesannya:
    • git commit -m 'message'
  • Commit beserta pesan dengan menyertakan perubahan yang belum di-stage:
    • git commit -am 'message'

Berpindah dan mengelola branch

  • Berpindah branch:
    • git checkout $NAME
    • git switch $NAME
  • Membuat branch:
    • git checkout -b $NAME
    • git switch -c $NAME
  • Melihat daftar branch:
    • git branch
  • Mengurutkan branch berdasarkan commit terbaru:
    • git branch --sort=-committerdate
  • Menghapus branch:
    • git branch -d $NAME
  • Menghapus branch secara paksa:
    • git branch -D $NAME

Menelusuri riwayat dan melacak kode

  • Melihat riwayat branch:
    • git log main
  • Melihat hubungan dua branch dalam bentuk grafik:
    • git log --graph a b
  • Melihat log satu baris:
    • git log --oneline
  • Melihat siapa yang terakhir mengubah setiap baris file:
    • git blame $FILENAME
  • Melihat semua commit yang memodifikasi file:
    • git log $FILENAME
  • Mencari commit yang menambahkan atau menghapus teks tertentu:
    • git log -S banana

Membandingkan perubahan

  • Melihat perbedaan antara commit dan parent commit-nya:
    • git show $COMMIT_ID
  • Melihat perbedaan antara merge commit dan parent-parent yang digabungkan:
    • git show --remerge-diff $COMMIT_ID
  • Melihat ringkasan diff:
    • git diff $COMMIT_ID --stat
    • git show $COMMIT_ID --stat
  • Membandingkan dua commit:
    • git diff $COMMIT_ID $COMMIT_ID
  • Membandingkan hanya file tertentu dengan commit:
    • git diff $COMMIT_ID $FILENAME
  • Membandingkan seluruh perubahan yang sudah di-stage dan yang belum di-stage:
    • git diff HEAD
  • Membandingkan hanya perubahan yang sudah di-stage:
    • git diff --staged
  • Membandingkan hanya perubahan yang belum di-stage:
    • git diff

File konfigurasi dan opsi

  • File konfigurasi Git lokal:
    • .git/config
  • File konfigurasi Git global:
    • ~/.gitconfig
  • Daftar file yang diabaikan:
    • .gitignore
  • Menentukan opsi konfigurasi:
    • git config user.name 'Julia'
  • Menentukan opsi global:
    • git config --global ...
  • Menambahkan alias:
    • git config alias.st status
  • Melihat opsi konfigurasi yang tersedia:
    • man git-config

Mengubah riwayat dan memulihkan file

  • Membatalkan commit terbaru sambil mempertahankan working directory:
    • git reset HEAD^
  • Membatalkan rebase yang gagal:
    • git reflog BRANCHNAME
    • git reset --hard $COMMIT_ID
  • Menggabungkan 5 commit terakhir menjadi satu:
    • git rebase -i HEAD^^^^^^
    • Ubah pick menjadi fixup untuk commit yang akan digabungkan
  • Mengambil versi file dari branch atau commit lain:
    • git checkout $COMMIT_ID $FILE
    • git restore $FILE --source $COMMIT_ID
  • Mengubah pesan commit atau menambahkan file yang terlewat:
    • git commit --amend

Menggabungkan branch

  • Fast-forward merge untuk memperbarui branch saat ini dari branch lain:
    • git switch main
    • git merge banana
  • Menyalin satu commit ke branch lain:
    • git cherry-pick $COMMIT_ID
  • Menggabungkan branch yang sudah bercabang dengan rebase:
    • git switch banana
    • git rebase main
  • Menggabungkan branch yang sudah bercabang dengan merge:
    • git switch main
    • git merge banana
    • git commit
  • Menggabungkan branch yang sudah bercabang dengan squash merge:
    • git switch main
    • git merge --squash banana
    • git commit

Sinkronisasi dengan repository remote

  • Menambahkan repository remote:
    • git remote add $NAME $URL
  • Push branch main ke remote origin:
    • git push origin main
  • Mengirim branch yang pertama kali di-push ke origin dan menetapkan branch pelacakan:
    • git push -u origin $NAME
  • Push branch saat ini ke branch pelacakan remote:
    • git push
  • Force push:
    • git push --force-with-lease
  • Push tag:
    • git push --tags
  • Mengambil perubahan tanpa mengubah branch lokal:
    • git fetch origin main
  • Fetch semua branch:
    • git fetch --all
  • Rebase ke branch saat ini setelah fetch:
    • git pull --rebase
  • Merge ke branch saat ini setelah fetch:
    • git pull origin main
    • git pull

Cara mereferensikan commit

  • Berbagai referensi bisa digunakan di posisi $COMMIT_ID:
    • Branch: main
    • Tag: v0.1
    • ID commit: 3e887ab
    • Branch remote: origin/main
    • Commit saat ini: HEAD
    • Commit 3 langkah sebelumnya: HEAD^^^
    • Commit 3 langkah sebelumnya: HEAD~3

Membuang perubahan

  • Menghapus semua perubahan yang sudah di-stage dan yang belum di-stage untuk satu file:
    • git checkout HEAD $FILE
  • Menghapus perubahan yang belum di-stage untuk satu file:
    • git checkout $FILE
  • Menghapus semua perubahan yang sudah di-stage dan yang belum di-stage:
    • git reset --hard
  • Menyimpan perubahan yang sudah di-stage dan yang belum di-stage ke stash:
    • git stash
  • Menghapus file yang belum dilacak:
    • git clean

1 komentar

 
GN⁺ 2024-05-27
Opini Hacker News
  • Ada beberapa perintah yang terasa seperti permata tersembunyi: git diff --staged menampilkan perbedaan antara commit terakhir dan isi yang saat ini sudah di-stage, jadi berguna untuk memastikan hanya perubahan yang dimaksud yang masuk saat menambahkan file atau hunk secara terperinci
    git log <file> hanya menampilkan commit yang mengubah file tersebut, sehingga mengurangi kebutuhan menelusuri seluruh git log, dan sangat berguna terutama untuk file yang jarang berubah
    Saat memakai git add --patch, kalau ingin memilih lebih rinci daripada hunk yang dibagi Git, coba gunakan opsi e. Ada panduan tentang cara menyertakan/mengecualikan baris individual, jadi tidak perlu menghafalnya

    • Baru tahu bahwa git diff --staged adalah alias dari git diff --cached. Aku sudah memakai cached selama bertahun-tahun, tetapi staged memang jauh lebih intuitif. Hanya saja aku tidak tahu apakah bisa menghapus memori otot ini
    • Kalau banyak membuat alias untuk perintah-perintah seperti ini, waktu yang dihemat lumayan banyak, dan hambatan untuk menata pekerjaan dengan lebih baik juga jadi lebih rendah
      Kalau tertarik, boleh dilihat atau mengusulkan alias: https://gitlab.com/Falimonda/gitrc
    • Jika mengatur git config --global commit.verbose true, Git akan otomatis memasukkan diff yang sudah di-stage ke area komentar di editor pesan commit
  • Salah satu perintah favorit yang tidak ada di daftar adalah git log -LstartLine,endLine:fileName
    Seperti git blame yang diperluas, perintah ini menunjukkan bagaimana baris-baris yang ditentukan berubah dari waktu ke waktu dan siapa yang mengubahnya. Tetap melacak meski nomor baris berubah atau file dipindahkan
    Ini menjawab pertanyaan seperti “siapa, kapan, dan mengapa melakukan ini?” atau “sejak kapan jadi begini?”

  • Teringat kutipan Phil Karlton: “Hanya ada dua hal sulit dalam ilmu komputer: invalidasi cache dan penamaan.”
    Dari sudut pandang itu, nama perintah Git blame terasa cukup aneh, dan ternyata bukan hanya aku yang berpikir begitu
    What does 'git blame' do? https://stackoverflow.com/questions/31203001/what-does-git-blame-do
    Blame someone else for your bad code https://news.ycombinator.com/item?id=27963868
    Git blame should be called git credit https://dev.to/damcosset/git-blame-should-be-called-git-credit-27h5
    Does Git Blame sound too negative? https://www.reddit.com/r/ProgrammerHumor/comments/r5lzyo/does_git_blame_sound_too_negative_just_look_up/

    • Mengingat nama alatnya adalah git, blame terasa seperti nama yang sesuai dengan mereknya
    • Setuju. Di konfigurasi aku mengganti blame menjadi who. Sebenarnya karena pengguna Vim garis keras, aku cukup memakai w
  • Aku suka cara aku belajar Git. Awalnya mulai dengan Sourcetree, GUI Git pihak ketiga, dan itu sangat mudah digunakan serta dipahami
    Setelah itu pindah ke git gui, tetapi tahap ini boleh saja dilewati. Kemudian aku merasa repot membuka UI, jadi belajar perintah terminal
    Aku merekomendasikannya untuk pemula Git, tetapi ini hanya pengalaman n=1-ku

    • Yang aku tahu tentang Git hanya sekitar clone, pull, commit, dan push, dan sejauh ini itu sudah cukup. Git memang bisa sesederhana itu. Tentu saja, kalau perlu, penggunaan yang lebih kompleks juga bisa dipelajari
    • Aku tidak ingin kembali ke perintah terminal. Repositori Git dan alur kerja jauh lebih mudah dipahami ketika divisualisasikan, jadi Git pada dasarnya hampir seperti alat yang menuntut ditangani lewat GUI
      Saat mulai memakai Magit, barulah Git mulai kupahami
    • Aku pindah dari Sourcetree ke Fork. Sangat mirip, tetapi performanya jauh lebih baik dan UI-nya mulus. Kecuali kalau Sourcetree membaik dalam beberapa tahun terakhir
    • Jalurnya mirip, tetapi aku memakai GitKraken dan Sublime Merge, dan karena memudahkan pekerjaan yang rumit, Sublime Merge tetap kupakai
      Tidak ada yang bisa kukatakan tentang Sublime Merge selain pujian
  • Saya penasaran apakah ada alasan historis mengapa Git menjadi rumit secara tidak perlu
    Melihat cheat sheet ini, kerumitannya makin terasa

    • Betul. Itu karena Git adalah alat yang dibuat Linus Torvalds untuk memungkinkan dan mengembangkan pengembangan kernel Linux
      Bahwa Git kemudian dipakai seluas ini mungkin adalah “kecelakaan yang membahagiakan”, atau bisa juga sebuah kemalangan. GitHub memang berjasa besar memopulerkan Git lewat “hosting Git gratis”, tetapi saya tidak menganggap Git sebagai sistem version control yang ideal untuk banyak proyek
      Karena dibuat untuk Linus dan Linux, istilah dan alur kerjanya kadang terasa kebalikan dari sistem version control biasa lainnya. Nama Pull Request pun berasal dari pengembangan Linux, karena Linus atau maintainer menarik perubahan ke dalam pohon kernel. Di sistem lain biasanya disebut Merge Request, dan istilah itu jauh lebih logis karena perubahan dari mana pun digabungkan ke dalam tree
      Git adalah salah satu dari sedikit distributed version control system open-source yang mampu menangani codebase raksasa dengan cepat, sehingga inersianya juga menjadi besar di perusahaan-perusahaan besar
      Untuk proyek pribadi, saya jauh lebih menyukai dan benar-benar memakai Mercurial, tetapi saat mencoba Hg pada codebase besar seperti Android AOSP, performanya sangat tersendat. Mercurial punya antarmuka pengguna dan tata perintah yang lebih baik, juga fitur untuk menjalankan web server secara instan guna melihat tree perubahan, tetapi karena ditulis dengan Python, performa dan skalabilitasnya tidak ideal
    • Sebagian kerumitan itu muncul karena pada versi awal biaya menambahkan subcommand baru cukup besar. Akibatnya, fungsi terus ditambahkan ke subcommand lama seperti git checkout, sehingga pengalaman pengguna menjadi makin membingungkan
      Di Git modern, biaya menambahkan subcommand baru sudah berkurang, dan mereka mulai menambahkan perintah yang lebih spesifik seperti git switch
    • Untuk sebagian besar alur kerja, menurut saya cukup mengetahui beberapa perintah Git seperti log, add, commit, pull, dan push. Ada juga tool GUI
      Sejujurnya, untuk pekerjaan biasa saya tidak menganggap Git serumit itu. Hanya saja ada banyak fitur kuat yang bisa dipakai saat dibutuhkan
    • Git bukan rumit secara tidak perlu. Alur kerja yang hendak didukung Git memang luar biasa rumit, dan pengguna sasarannya, yaitu developer kernel, sangat teknis sehingga kerumitan bukan masalah besar
      Developer kernel harus berkomunikasi satu sama lain secara terdesentralisasi, dan bekerja lagi di atas pekerjaan orang lain. Bagaimana cara bekerja dalam proyek dengan 15.000 orang yang menulis kode? Git dibuat untuk tujuan itu
      Git serumit yang diperlukan untuk mendukung alur kerja yang menjadi sasaran desainnya. Membuat alat yang lebih sederhana itu mudah, tetapi alat itu tidak akan bisa mendukung alur kerja kompleks seperti pengembangan kernel Linux. Jadi Git tidak rumit secara tidak perlu, tetapi untuk penggunaan sederhana memang lebih rumit daripada yang dibutuhkan
      Jika butuh frontend yang tidak terlalu rumit, ada banyak alat yang membuat Git lebih mudah digunakan. Kalau Anda bukan developer software penuh waktu, saya tidak menyarankan memakai Git secara langsung. Namun jika Anda developer penuh waktu, layak meluangkan waktu untuk memahami konsep internalnya, dan setelah dipahami, Git cukup elegan dibandingkan hal-hal yang dilakukannya
      Saya tidak akan menjadikan pengetahuan Git sebagai penentu kelayakan seseorang sebagai developer software, tetapi jika mencari tahu sendiri cara kerja sistem dasar seperti ini tidak memberi Anda dopamin, mungkin bidang ini bukan selera Anda. Itu juga tidak apa-apa; ada hal yang cocok dan tidak cocok untuk setiap orang
      Untuk belajar navigasi Git, saya merekomendasikan https://learngitbranching.js.org. Tentu saja https://xkcd.com/1597/ juga berlaku
    • Karena desain UI yang baik adalah keterampilan tersendiri dan butuh upaya tambahan, sehingga biasanya diabaikan begitu saja
  • Saya belum tahu git add -p, ternyata sangat berguna
    -p, --patch memungkinkan kita memilih hunk patch antara index dan working tree secara interaktif untuk ditambahkan ke index. Ini memberi kesempatan meninjau perbedaan sebelum menambahkan perubahan ke index

    • Jika memungkinkan, saya memilih sendiri hunk dari pekerjaan saat ini dan merakitnya menjadi commit yang koheren. Ini membantu saya menata ulang apa yang saya kerjakan di kepala, dan ketika harus menjelaskannya kepada seseorang, saya bisa menjelaskan dengan mengikuti alur commit
  • Yang ingin saya tambahkan di sini adalah kombinasi git commit --fixup $COMMIT_ID dan git rebase -i upstream/master --autosquash
    Ini sudah menjadi elemen wajib dalam alur kerja saya belakangan ini. Contoh Julia memakai HEAD^^^^^ untuk me-rebase 5 commit sebelumnya, tetapi sampai baru-baru ini saya memakai HEAD~5. Namun sekarang saya tahu bahwa ternyata saya bisa langsung me-rebase semua commit sampai upstream HEAD

    • git commit --fixup $COMMIT_ID sepertinya harus segera saya adopsi. Saya selalu membuat commit perbaikan kecil seperti “oops GET users/me”, lalu pada interactive rebase berikutnya memindahkannya secara manual untuk di-fixup, tetapi cara ini jauh lebih baik
    • Saya baru mempelajari ini belakangan, dan ini sangat bagus saat bekerja dengan stacked patch di Gerrit
  • “Menggabungkan 5 commit terakhir menjadi satu: git rebase -i HEAD^^^^^^” sepertinya yang benar adalah git rebase -i HEAD~5
    Dengan asumsi bahwa yang ingin di-rebase hanyalah histori linear
    https://stackoverflow.com/questions/2221658/whats-the-difference-between-head-and-head-in-git

  • Pencerahan terbesar bagi saya adalah saat memahami bahwa semua commit masih tersimpan di dalam. Tag dan branch hanya menunjuk ke commit, dan commit yang dulu ditunjuk oleh sebuah branch juga tidak hilang
    Banyak perintah, mungkin bisa dibilang hampir semuanya, bersifat non-destruktif, sehingga mudah merujuk ke keadaan lama sebuah branch
    Saya pernah melihat git reflog, tetapi terutama hanya memakainya untuk mengingat “branch yang dulu saya kerjakan itu apa ya?”
    Saya jadi punya rasa takut yang setengah sehat terhadap operasi yang bisa membawa saya masuk ke tengah penyelesaian konflik yang tidak diinginkan. Biasanya konflik terjadi karena saya merujuk commit atau branch yang salah
    Rasa takut itu belum sepenuhnya hilang, tetapi setidaknya saya sudah cukup nyaman memulihkan pekerjaan lama di sela-sela operasi seperti rebase

    • Jujutsu sepenuhnya menghilangkan rasa takut seperti itu
      Kalau tidak tahu apakah suatu operasi akan menimbulkan konflik, saya tinggal mencobanya dan melihat hasilnya. Kalau terjadi konflik, saya menyelesaikannya, atau membatalkan operasi yang membuat konflik itu, atau membuat commit baru di tempat lain dan membiarkan konfliknya ditangani nanti
      Kalau sudah tahu akan ada konflik, saya menyalin branch terkait lalu mencocokkannya terlebih dahulu, atau menjalankan operasi yang menimbulkan konflik dan mencoba proses penyelesaiannya. Kalau penyelesaiannya jadi berantakan, saya bisa membatalkan sebagian penyelesaian dan terus mencoba, menundanya sebentar lalu mengerjakan hal lain, atau membuang seluruh tree
  • Terus terang saja, Git sebaiknya ditinggalkan dan lihat JJ
    https://martinvonz.github.io/jj/v0.17.1/
    Bahkan Linus pun kemungkinan menganggap UI Git buruk. JJ punya alur kerja yang luar biasa

    • Saya sulit setuju soal tidak adanya index. Mungkin itu membuat sebagian alur kerja lebih sederhana, tetapi baik atau buruk, saya sudah terlalu terbiasa dengan index Git sehingga cara kerja saya sepertinya akan berubah cukup besar
      Namun selain mencobanya sedikit, saya belum pernah memakainya secara mendalam untuk pekerjaan nyata, jadi sulit untuk menyimpulkan dengan tegas