Kodeloka
  1. Kodeloka
  2. Kelas Git & CI/CD
  3. Materi

Git Fundamentals · Modul 1 dari 20

Fondasi Git - Model Objek, Staging Area & Commit

Memahami Git dari dalam: blob, tree, commit, dan bagaimana working directory, staging area, serta repository saling berhubungan.

1. Git Menyimpan Snapshot, Bukan Perbedaan

Sistem kontrol versi lama seperti SVN menyimpan daftar perubahan per berkas. Git bekerja berbeda: setiap commit adalah potret utuh seluruh proyek pada saat itu. Berkas yang tidak berubah tidak disalin ulang — Git cukup menunjuk ke objek yang sudah ada.

💡 Empat jenis objek di dalam .git
  • Blob — isi sebuah berkas. Tidak menyimpan nama berkas.
  • Tree — sebuah direktori. Berisi daftar nama berkas beserta blob/tree yang ditunjuknya.
  • Commit — menunjuk ke satu tree akar, ditambah pengarang, pesan, waktu, dan commit induk.
  • Tag — penunjuk bernama ke sebuah objek, biasanya commit, dengan pesan dan penanda tangan.

Nama tiap objek adalah hash SHA-1 dari isinya. Konsekuensinya penting: dua berkas dengan isi identik hanya disimpan sekali, dan mengubah satu byte saja pada commit lama akan mengubah hash-nya beserta seluruh commit sesudahnya. Inilah yang membuat riwayat Git tidak bisa dipalsukan diam-diam.

Membedah objek secara langsung
# Lihat jenis sebuah objek
git cat-file -t HEAD          # => commit

# Lihat isinya
git cat-file -p HEAD
# tree 9f2b3c...
# parent 4a1de8...
# author Budi <[email protected]> 1712345678 +0700
# committer Budi <[email protected]> 1712345678 +0700
#
# menambahkan validasi form login

# Telusuri tree-nya
git cat-file -p HEAD^{tree}

# Hash sebuah isi tanpa menyimpannya
echo "halo" | git hash-object --stdin

2. Tiga Wilayah Git

  Working Directory        Staging Area (Index)        Repository (.git)
  berkas yang Anda edit    calon commit berikutnya     riwayat permanen
         │                          │                          │
         │──── git add ────────────>│                          │
         │                          │──── git commit ─────────>│
         │<─── git restore ─────────│                          │
         │<─────────────── git restore --source=HEAD ──────────│

Hampir semua kebingungan pemula soal Git berasal dari tidak memisahkan tiga wilayah ini. git status selalu memberi tahu Anda berkas berada di wilayah mana.

git status
git status -s            # ringkas: XY nama-berkas
# Kolom pertama  = keadaan di staging area
# Kolom kedua    = keadaan di working directory
#
# M_  = sudah di-stage, siap commit
# _M  = berubah tapi belum di-stage
# MM  = sudah di-stage, LALU diubah lagi setelahnya
# ??  = berkas baru yang belum dilacak Git

3. Menyusun Commit dengan Rapi

# Menambahkan berkas ke staging area
git add berkas.js
git add .                    # semua perubahan di direktori sekarang
git add -A                   # semua perubahan di seluruh repositori

# Memilih BAGIAN dari sebuah berkas -- sangat berguna
git add -p berkas.js
# y = ambil bagian ini, n = lewati, s = pecah lagi jadi lebih kecil,
# e = sunting manual, q = keluar

# Melihat apa yang akan masuk ke commit
git diff                     # working directory vs staging area
git diff --staged            # staging area vs commit terakhir
git diff HEAD                # working directory vs commit terakhir
📌 git add -p mengubah cara Anda bekerja

Anda sering menyelesaikan dua hal berbeda dalam satu sesi ngoding. git add -p memungkinkan Anda memecahnya menjadi dua commit yang bersih dan terpisah, alih-alih satu commit campur aduk berjudul "perbaikan macam-macam". Riwayat yang bersih membuat git bisect dan git revert menjadi jauh lebih berguna nanti.

4. Menulis Pesan Commit yang Berguna

git commit -m "perbaiki kebocoran koneksi pada pool database"

# Pesan panjang dengan badan penjelasan
git commit
# Baris 1  : ringkasan maksimal ~50 karakter, kalimat perintah
# Baris 2  : kosong
# Baris 3+ : KENAPA perubahan ini dibuat, bukan APA yang diubah
💡 Conventional Commits

Format yang banyak dipakai karena bisa dibaca mesin untuk membuat changelog dan menentukan versi otomatis:

feat(auth): tambahkan login dengan Google
fix(api): tangani timeout pada pemanggilan layanan pembayaran
docs(readme): perbarui langkah instalasi
refactor(db): pisahkan query builder dari repository
perf(cache): kurangi round-trip Redis pada endpoint katalog
test(order): tambahkan kasus uji pembatalan pesanan
chore(deps): naikkan versi driver postgres

# Perubahan yang merusak kompatibilitas
feat(api)!: ganti format respons error menjadi RFC 7807

Awalan feat menaikkan versi minor, fix menaikkan patch, dan tanda ! atau footer BREAKING CHANGE: menaikkan versi mayor.

5. HEAD, Branch, dan Referensi

Branch di Git hanyalah sebuah berkas teks berisi hash commit. Itu sebabnya membuat branch di Git nyaris tanpa biaya, berbeda dengan SVN yang menyalin seluruh direktori.

cat .git/HEAD
# ref: refs/heads/main

cat .git/refs/heads/main
# 4a1de8f9c2b3...

# Notasi penunjuk relatif
HEAD        # commit tempat Anda berada sekarang
HEAD~1      # satu commit ke belakang (induk)
HEAD~3      # tiga commit ke belakang
HEAD^       # induk pertama
HEAD^2      # induk KEDUA -- hanya ada pada merge commit

6. Membatalkan: reset, restore, revert

Tiga perintah ini sering tertukar. Bedanya terletak pada wilayah mana yang mereka sentuh.

PerintahYang berubahAman untuk riwayat publik?
git restore berkasWorking directory sajaYa
git restore --staged berkasStaging area sajaYa
git reset --soft HEAD~1Hanya penunjuk branch; perubahan tetap di stagingTidak
git reset --mixed HEAD~1Branch + staging area (default)Tidak
git reset --hard HEAD~1Semuanya — perubahan hilangTidak
git revert <commit>Membuat commit BARU yang membatalkanYa — ini yang benar untuk branch bersama
🚫 Aturan emas

Gunakan git revert untuk commit yang sudah dipush ke branch bersama. git reset menulis ulang riwayat; bila riwayat itu sudah dipakai orang lain, Anda memaksa semua rekan tim membereskan kekacauan di repositori lokal mereka masing-masing.

7. Jaring Pengaman: reflog

# Riwayat SEMUA perpindahan HEAD, termasuk yang "hilang"
git reflog

# 4a1de8f HEAD@{0}: reset: moving to HEAD~1
# 9c2b3f1 HEAD@{1}: commit: menambahkan fitur ekspor
# 7e4a2d8 HEAD@{2}: checkout: moving from main to fitur-baru

# Memulihkan commit yang terlanjur di-reset --hard
git reset --hard 9c2b3f1
# atau selamatkan ke branch baru
git branch penyelamat 9c2b3f1
📌 Hampir tidak ada yang benar-benar hilang di Git

Selama commit pernah dibuat, ia tercatat di reflog selama kurang lebih 90 hari sebelum garbage collector membersihkannya. Sebelum panik karena reset --hard, jalankan git reflog — kemungkinan besar pekerjaan Anda masih ada di sana.