1. Stash — Menyimpan Pekerjaan Sementara
# Simpan perubahan dan bersihkan working directory
git stash push -m "eksperimen tata letak keranjang"
# Sertakan berkas yang belum dilacak Git
git stash push -u -m "termasuk berkas baru"
# Simpan hanya berkas tertentu
git stash push -m "hanya css" src/gaya.css
git stash list
# stash@{0}: On fitur: eksperimen tata letak keranjang
# stash@{1}: On main: perbaikan cepat
git stash show -p stash@{0} # lihat isinya
git stash pop # terapkan dan HAPUS dari daftar
git stash apply stash@{1} # terapkan tapi TETAP simpan
git stash drop stash@{0}
git stash clear # hapus semua -- hati-hati
# Membuat branch langsung dari stash
git stash branch fitur/eksperimen stash@{0}
Stash tidak muncul di git status maupun git log. Pekerjaan yang di-stash berbulan-bulan lalu sering terlupakan sepenuhnya. Selalu beri pesan yang jelas dengan -m, dan untuk pekerjaan yang serius lebih baik buat branch daripada mengandalkan stash.
2. Worktree — Beberapa Branch Sekaligus
Masalah klasik: Anda sedang di tengah pekerjaan, lalu ada bug produksi yang harus segera diperbaiki. Alih-alih stash lalu berpindah branch, buka saja direktori kerja kedua.
# Buat direktori kerja baru untuk branch hotfix git worktree add ../proyek-hotfix -b hotfix/pembayaran-gagal # Sekarang ada dua direktori dari SATU repositori: # ~/proyek -> branch fitur/keranjang # ~/proyek-hotfix -> branch hotfix/pembayaran-gagal git worktree list git worktree remove ../proyek-hotfix git worktree prune # bersihkan catatan yang sudah usang
Semua worktree berbagi satu direktori .git yang sama, sehingga tidak ada objek yang digandakan dan tidak perlu fetch dua kali. Ini juga sangat berguna saat perlu membandingkan dua versi berdampingan, atau menjalankan uji panjang di satu branch sambil terus bekerja di branch lain.
3. Submodule — Repositori di Dalam Repositori
git submodule add https://github.com/org/pustaka-bersama.git vendor/pustaka # Meng-clone proyek yang punya submodule git clone --recurse-submodules https://github.com/org/proyek.git # Bila terlanjur clone biasa git submodule update --init --recursive # Memperbarui submodule ke commit terbaru upstream git submodule update --remote vendor/pustaka git add vendor/pustaka git commit -m "chore: naikkan versi pustaka-bersama" git submodule status
Repositori induk hanya mencatat satu hash commit dari submodule, bukan branch. Akibatnya: orang lupa --recurse-submodules saat clone dan mendapat direktori kosong; submodule sering berada dalam keadaan detached HEAD; dan perubahan di submodule harus di-commit dan dipush secara terpisah sebelum commit di repositori induk, kalau tidak rekan tim akan mendapat referensi ke commit yang tidak ada.
Alternatif yang biasanya lebih baik: publikasikan pustaka bersama sebagai paket berversi (npm, Go module, PyPI) dan pakai manajer dependensi biasa. Pertimbangkan submodule hanya bila Anda benar-benar butuh menyematkan repositori pada commit tertentu.
4. Subtree — Alternatif yang Lebih Ramah
# Menyalin isi repositori lain ke sebuah direktori git subtree add --prefix=vendor/pustaka \ https://github.com/org/pustaka-bersama.git main --squash # Menarik pembaruan git subtree pull --prefix=vendor/pustaka \ https://github.com/org/pustaka-bersama.git main --squash
Berbeda dari submodule, isi subtree benar-benar berada di dalam repositori Anda. Orang yang meng-clone tidak perlu tahu apa pun tentang subtree — semuanya langsung ada.
5. Hooks — Otomatisasi pada Peristiwa Git
| Hook | Kapan berjalan | Kegunaan umum |
|---|---|---|
pre-commit | Sebelum commit dibuat | Lint, format, pindai rahasia |
commit-msg | Setelah pesan ditulis | Validasi format Conventional Commits |
pre-push | Sebelum push | Jalankan unit test |
post-merge | Setelah merge | Jalankan npm install bila lockfile berubah |
pre-receive | Di server, sebelum menerima | Tolak push yang melanggar kebijakan |
#!/bin/sh set -e # Tolak commit yang mengandung penanda konflik if git diff --cached | grep -q "^+<<<<<<<"; then echo "❌ Ada penanda konflik yang belum dibereskan." exit 1 fi # Tolak commit yang mengandung debugger if git diff --cached --name-only | grep -E '\.(js|ts)$' | xargs -r grep -l "debugger"; then echo "❌ Hapus dulu pernyataan debugger." exit 1 fi npm run lint echo "✅ Pemeriksaan pre-commit lolos."
.git/hooks tidak ikut ter-clone
Direktori .git bersifat lokal, sehingga hook yang Anda buat di sana tidak akan dimiliki rekan tim. Agar hook berlaku untuk semua orang, simpan skripnya di dalam repositori dan arahkan Git ke sana:
git config core.hooksPath .githooks
Atau pakai alat pengelola seperti pre-commit (Python), husky + lint-staged (Node.js), atau lefthook yang memasang hook otomatis saat instalasi dependensi.
Siapa pun bisa melewati hook dengan git commit --no-verify. Hook adalah alat bantu kenyamanan, bukan penegakan aturan. Aturan yang benar-benar wajib harus ditegakkan di pipeline CI dan branch protection di sisi server, yang tidak bisa dilewati siapa pun.
6. Menjaga Rahasia Tidak Masuk Repositori
.env .env.* !.env.example *.pem *.key node_modules/ dist/ __pycache__/ .DS_Store
# Berkas terlanjur dilacak padahal sudah masuk .gitignore? git rm --cached .env git commit -m "chore: berhenti melacak berkas .env" # Memeriksa mengapa sebuah berkas diabaikan git check-ignore -v config/rahasia.json
Menghapusnya di commit berikutnya tidak cukup — nilainya tetap ada di riwayat dan bisa dibaca siapa pun. Langkah yang benar, berurutan: (1) segera cabut dan ganti kredensial tersebut — ini yang paling penting dan tidak boleh ditunda; (2) baru bersihkan riwayat dengan git filter-repo atau BFG Repo-Cleaner; (3) koordinasikan dengan tim karena riwayat akan ditulis ulang.