Git

Belum masuk. Progresmu tidak tersimpan.

Masuk
  • Bab 8 dari 8
  • 35 menit
  • 4 soal kuis

Perintah Lanjutan dan Praktik Terbaik

Di bab ini (12 bagian)
  1. Tujuan
  2. git stash: laci sementara
  3. git cherry-pick: ambil satu commit saja
  4. git tag: menandai rilis
  5. git bisect: mencari commit biang bug
  6. .gitignore: yang tidak perlu dilacak
  7. Pesan commit yang baik
  8. Praktik terbaik
  9. Kesalahan umum
  10. Lembar contekan
  11. Coba sendiri
  12. Rangkuman

Tujuan bab ini

  • Menyimpan pekerjaan setengah jadi dengan git stash, menyalin satu commit dengan git cherry-pick, dan menandai rilis dengan git tag.
  • Mencari commit penyebab bug dengan git bisect.
  • Menulis .gitignore yang benar dan berhenti melacak file yang terlanjur di-commit.
  • Menulis pesan commit ala Conventional Commits dan menghindari kesalahan yang paling sering bikin repo berantakan.

git stash: laci sementara

Bayangkan kamu sedang mengedit index.html, belum siap commit, lalu tiba-tiba diminta memperbaiki bug di cabang lain. git stash menyimpan perubahan itu ke "laci" sementara dan mengembalikan folder kerjamu ke kondisi commit terakhir.

git status --short
git stash
git stash list
 M index.html
Saved working directory and index state WIP on main: f907659 feat: halaman awal
stash@{0}: WIP on main: f907659 feat: halaman awal

Beri nama supaya tidak bingung saat stash menumpuk: git stash push -m "gaya setengah jadi". Stash disusun seperti tumpukan: yang terbaru selalu stash@{0}. Untuk mengembalikan, pakai git stash pop: perubahan teratas diterapkan lagi lalu dihapus dari daftar (Dropped refs/stash@{0}). Kalau ingin menerapkan tanpa menghapus, pakai git stash apply.

Satu jebakan: secara default stash hanya membawa file yang sudah dilacak. File baru yang belum pernah di-add tetap tertinggal, dan kalau hanya ada file seperti itu, Git menjawab No local changes to save. Tambahkan -u (git stash -u) agar file untracked ikut disimpan.

git cherry-pick: ambil satu commit saja

Kadang kamu butuh satu commit dari cabang lain, misalnya perbaikan typo di cabang fitur, tanpa ikut menggabungkan fitur yang belum selesai. git cherry-pick menyalin commit itu ke cabang aktif.

git switch main
git cherry-pick bfdea42
[main ebc1e27] fix: perbaiki typo judul
 1 file changed, 1 insertion(+)

Perhatikan hash-nya berubah dari bfdea42 menjadi ebc1e27. Cherry-pick membuat commit baru dengan isi perubahan yang sama, bukan memindahkan commit lama. Gunakan secukupnya; kalau kamu butuh banyak commit dari satu cabang, biasanya merge lebih tepat.

git tag: menandai rilis

Tag adalah penanda permanen ke satu commit, umumnya untuk versi rilis seperti v1.0.0. Berbeda dengan branch, tag tidak bergerak saat ada commit baru. Ada dua jenis:

  • Lightweight: git tag v1.0.0. Hanya nama yang menunjuk ke commit, tanpa info tambahan.
  • Annotated: git tag -a v1.1.0 -m "rilis 1.1". Disimpan sebagai objek tag tersendiri lengkap dengan nama pembuat, tanggal, dan pesan. Ini yang disarankan untuk rilis resmi.
git tag
git cat-file -t v1.0.0
git cat-file -t v1.1.0
v1.0.0
v1.1.0
commit
tag

Tag lightweight langsung menunjuk ke objek commit, sedangkan annotated punya objek tag sendiri. git show v1.1.0 menampilkan baris Tagger: dan pesannya. Tag tidak ikut terkirim dengan git push biasa; kirim dengan git push origin v1.1.0 atau semuanya sekaligus dengan git push --tags.

git bisect: mencari commit biang bug

Fitur kemarin masih jalan, hari ini rusak, dan di antaranya ada puluhan commit. git bisect melakukan pencarian biner: Git memilih commit di tengah, kamu bilang bagus atau rusak, lalu rentangnya dibelah dua lagi.

git bisect start
git bisect bad              # commit sekarang rusak
git bisect good HEAD~5      # lima commit lalu masih benar
# Git checkout commit tengah, kamu uji, lalu jawab:
git bisect good             # atau git bisect bad

Setelah beberapa langkah Git menyimpulkan, misalnya 090012b... is the first bad commit. Tutup sesi dengan git bisect reset untuk kembali ke cabang semula. Dengan 6 commit cukup 3 langkah, dengan 1000 commit sekitar 10 langkah.

Masih satu keluarga dengan perintah penolong ini: git reflog mencatat semua pergerakan HEAD, sehingga commit yang "hilang" setelah reset biasanya masih bisa dikejar.

.gitignore: yang tidak perlu dilacak

File .gitignore di akar repo memberi tahu Git file mana yang diabaikan: dependensi, hasil build, file editor, dan yang paling penting, file rahasia.

# Dependensi dan hasil build
node_modules/
dist/

# Rahasia, jangan pernah di-commit
.env
*.pem

# Log, kecuali satu
*.log
!penting.log

Polanya:

PolaArti
node_modules/abaikan seluruh folder itu
*.logabaikan semua file berakhiran .log
!penting.lognegasi: file ini tetap dilacak walau cocok pola sebelumnya
/rahasia.envhanya file di akar repo, bukan di subfolder

Cek file mana yang kena aturan dengan git status --short --ignored (ditandai !!) atau git check-ignore -v app.log, yang menunjukkan baris aturan penyebabnya.

Penting: .gitignore hanya berlaku untuk file yang belum pernah dilacak. Kalau .env terlanjur di-commit, menambahkannya ke .gitignore tidak berpengaruh; git status tetap menampilkan M .env saat isinya berubah. Hentikan pelacakannya dengan:

git rm --cached .env
git commit -m "chore: berhenti lacak .env"

--cached menghapus file dari index saja; file di disk tetap ada. Tapi riwayat lama masih menyimpan isinya, jadi kunci yang sudah ter-push harus dianggap bocor dan segera diganti.

Pesan commit yang baik

Pesan commit dibaca berkali-kali, termasuk oleh dirimu enam bulan lagi. Banyak tim memakai Conventional Commits:

<tipe>(<cakupan>): <ringkasan singkat>

feat(auth): tambah login dengan Google
fix(api): perbaiki validasi email kosong
docs(readme): perbarui panduan instalasi

Tipe yang umum: feat (fitur baru), fix (perbaikan bug), docs (dokumentasi), style (format kode), refactor (penataan ulang tanpa ubah perilaku), test (pengujian), chore (tugas rutin), dan perf (peningkatan performa).

Aturan praktisnya: kalimat perintah ("tambah", bukan "menambahkan"), ringkasan maksimal sekitar 50 karakter, satu commit untuk satu perubahan logis, dan alasan perubahan ditulis di badan pesan. Hindari pesan seperti update, fix bug, asdf, atau ..

Praktik terbaik

  • Commit kecil dan sering. Mudah ditinjau, mudah di-revert.
  • Pull sebelum push. Konflik ketahuan lebih awal.
  • Satu cabang satu tujuan. Jangan campur perbaikan bug dengan fitur baru.
  • Tulis README dan .gitignore sejak awal.
  • Review sebelum merge. Pull request adalah mekanisme menjaga kualitas, bukan formalitas.

Kesalahan umum

  • Commit file rahasia. Password dan API key yang sudah di-push dianggap bocor selamanya.
  • Push atau force push langsung ke main. git push --force bisa menghapus commit teman; lindungi cabang utama dan lewat PR.
  • Rebase riwayat publik. Menulis ulang commit bersama mengacaukan kerja tim.
  • Commit file biner besar. Repo membengkak; pakai Git LFS bila memang perlu.
  • Menumpuk perubahan berhari-hari. Makin lama ditunda, makin besar konfliknya.

Lembar contekan

KelompokPerintah
Dasargit config --global user.name, git init, git clone <url>, git status, git add ., git commit -m "pesan", git log --oneline --graph
Cabanggit branch, git switch -c <cabang>, git switch <cabang>, git merge <cabang>, git rebase <cabang>, git branch -d <cabang>, git merge --abort
Remotegit remote -v, git push -u origin main, git fetch, git pull
Lanjutangit stash, git stash pop, git tag -a v1.0.0, git revert <hash>, git reflog

Coba sendiri

mkdir lab-lanjut && cd lab-lanjut && git init -b main
echo "<h1>Toko</h1>" > index.html
git add . && git commit -m "feat: halaman awal"
echo "<p>promo</p>" >> index.html
git stash
git status --short          # kosong
git stash pop
git status --short          # " M index.html" kembali
git commit -am "feat: tambah promo"
git tag -a v1.0.0 -m "rilis pertama"
git log --oneline --decorate -n 1

Baris terakhir kira-kira 81880e5 (HEAD -> main, tag: v1.0.0) feat: tambah promo (hash-mu akan berbeda). Lanjutkan dengan .gitignore:

echo "RAHASIA=123" > .env
echo "x" > app.log
printf '.env\n*.log\n' > .gitignore
git status --short --ignored
?? .gitignore
!! .env
!! app.log

Rangkuman

  • git stash menyimpan perubahan sementara, git stash pop mengembalikan dan menghapusnya, -u ikut membawa file untracked.
  • git cherry-pick <hash> menyalin satu commit sebagai commit baru di cabang aktif.
  • Tag lightweight hanya penunjuk; tag annotated (-a -m) menyimpan pembuat, tanggal, dan pesan. Kirim dengan git push --tags.
  • git bisect mencari commit penyebab bug lewat pencarian biner; akhiri dengan git bisect reset.
  • .gitignore hanya berlaku untuk file untracked; pakai git rm --cached untuk berhenti melacak, dan ganti kunci yang bocor.
  • Tulis pesan commit tipe(cakupan): ringkasan, commit kecil, jangan commit rahasia, dan jangan force push ke main.

Selesaikan bab ini

  1. 1. Baca materi
  2. 2. Kuis (4 soal)

Cek pemahaman

  1. 1Apa output git stash list yang terakhir?

    $ git stash list
    stash@{0}: On main: gaya setengah jadi
    stash@{1}: WIP on main: f907659 feat: halaman awal
    $ git stash pop
    $ git stash list
  2. 2File .env terlanjur di-commit. Perintah apa yang menghentikan pelacakannya tanpa menghapus file dari disk?

  3. 3Tag lightweight menyimpan nama pembuat, tanggal, dan pesan, sama seperti tag annotated.

  4. 4Pesan commit mana yang paling sesuai dengan Conventional Commits?