Working tree, staging area, dan HEAD bukan lagi istilah asing — section Dasar Repository sudah memetakan ketiganya sebagai tiga area dengan peran berbeda. Begitu kita mulai menyunting berkas, peta itu berubah menjadi pertanyaan praktis: suntingan yang barusan disimpan berada di area mana, dan perintah mana yang tepat untuk melihat isinya? Jawabannya terpusat pada satu perintah, git diff, yang punya tiga bentuk pembandingan — dan masing-masing menghubungkan pasangan area yang berbeda. Tertukar-tukarnya ketiganya adalah kebingungan klasik pengguna baru, jadi chapter ini menegaskan posisi working tree di antara dua area lainnya lewat tiga kondisi repository yang dibangun bertahap.

Tiga Pasangan yang Bisa Dibandingkan #

Git selalu bisa membandingkan isi berkas pada tiga tempat: versi terakhir yang sudah dicatat (ditunjuk HEAD), versi di staging area (disebut juga index), dan versi yang sedang kita sunting di working tree. Perintah git status dari chapter sebelumnya hanya melaporkan ada tidaknya perbedaan antar area; git diff menampilkan isi perbedaannya baris demi baris. Karena ada tiga area, tersedia tiga pasangan pembandingan:

Diagram tersebut memetakan setiap perintah ke pasangan area yang dibandingkan. Ketiganya menjawab tiga pertanyaan berbeda:

PerintahPasangan yang dibandingkanPertanyaan yang dijawab
git diffworking tree vs indexApa yang berubah sejak terakhir kali di-git add?
git diff --cachedindex vs HEADApa isi calon commit berikutnya?
git diff HEADworking tree vs HEADSeberapa jauh berkas menyimpang dari commit terakhir?

Opsi --cached punya kembar bernama --staged: keduanya opsi yang sama, dan nama lama berasal dari masa ketika staging area masih disebut cache — kisah tiga nama untuk satu benda sudah kita bahas pada chapter Staging Area . Daftar opsi selengkapnya terdokumentasi pada dokumentasi git diff .

Menyiapkan Repository Latihan #

Kita mulai dari repository kecil yang bersih supaya setiap kondisi dapat dibangun dari nol:

bash
mkdir latihan-diff && cd latihan-diff
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf '# Situs Dokumentasi\n\nKumpulan catatan teknis tim.\n' > README.md
git add README.md
git commit -m "Commit awal situs dokumentasi"

Output yang Dihasilkan:

text
[main (root-commit) 849aa8b] Commit awal situs dokumentasi
 1 file changed, 3 insertions(+)
 create mode 100644 README.md

Satu commit tercatat dan git status menjawab nothing to commit, working tree clean: ketiga area menampung isi README.md yang sama. Hash pada keluaran dihitung dari isi commit, jadi nilainya berbeda di komputer pembaca.

Kondisi 1: Suntingan Hanya di Working Tree #

Kondisi pertama adalah yang paling sering terjadi: kita menyimpan suntingan di editor dan belum menyentuh git add sama sekali.

bash
printf '# Situs Dokumentasi\n\nKumpulan catatan teknis tim.\nBagian panduan pengguna ditambahkan di halaman utama.\n' > README.md
git status

Output yang Dihasilkan:

text
On branch main
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

no changes added to commit (use "git add" and/or "git commit -a")

Perintah git status menempatkan README.md pada daftar Changes not staged for commit — suntingan ada di working tree, belum di keranjang. Sekarang kita uji pembandingan pertama:

bash
git diff

Output yang Dihasilkan:

text
diff --git a/README.md b/README.md
index 5d6c796..663b3c9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # Situs Dokumentasi
 
 Kumpulan catatan teknis tim.
+Bagian panduan pengguna ditambahkan di halaman utama.

Cukup dua hal untuk saat ini: baris berawalan - adalah isi lama, baris berawalan + adalah isi baru, dan baris tanpa awalan adalah konteks. Empat baris pembuka hanyalah kepala diff — bedah lengkap formatnya kita lakukan pada chapter Melihat Perbedaan Perubahan .

Perintah git diff --cached tidak mencetak apa pun karena index masih identik dengan HEAD — tidak ada yang bisa dibandingkan. Sebaliknya, git diff HEAD mencetak keluaran yang sama persis:

bash
git diff HEAD

Output yang Dihasilkan:

text
diff --git a/README.md b/README.md
index 5d6c796..663b3c9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # Situs Dokumentasi
 
 Kumpulan catatan teknis tim.
+Bagian panduan pengguna ditambahkan di halaman utama.

Identitas tersebut wajar: karena index sama dengan HEAD, membandingkan working tree ke keduanya jatuh pada pasangan yang sama. Kesimpulan “kedua perintah sama saja” terasa benar di kondisi ini — kondisi berikutnya membuktikan kesimpulan itu hanya berlaku sementara.

Kondisi 2: Suntingan Sudah Masuk Staging Area #

Kondisi kedua: suntingan yang sama kita pindahkan ke keranjang.

bash
git add README.md
git status

Output yang Dihasilkan:

text
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   README.md

Judul daftar berganti menjadi Changes to be committed — keranjang commit berikutnya kini berisi versi baru README.md. Posisi tiga area ikut bergeser: index dan working tree sama-sama memuat versi baru, sementara HEAD masih menampung versi lama. Akibatnya git diff tidak lagi mencetak apa pun — working tree dan index identik; yang ramai sekarang pembandingan kedua:

bash
git diff --cached

Output yang Dihasilkan:

text
diff --git a/README.md b/README.md
index 5d6c796..663b3c9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # Situs Dokumentasi
 
 Kumpulan catatan teknis tim.
+Bagian panduan pengguna ditambahkan di halaman utama.

Inilah isi calon commit berikutnya — perintah yang tadi sunyi di kondisi 1 kini menjadi sumber informasi utama. Bentuk git diff --staged menghasilkan keluaran yang sama persis. Adapun git diff HEAD pun masih menampilkan suntingan yang sama: working tree tetap berbeda dari HEAD, kini lewat jalur index.

Kondisi 3: Staged, Lalu Disunting Lagi #

Kondisi ketiga menjelaskan mengapa pemisahan tiga area begitu berharga. Commit belum dibuat, lalu kita menyunting README.md sekali lagi — baris kedua ditambahkan setelah baris pertama:

bash
printf '# Situs Dokumentasi\n\nKumpulan catatan teknis tim.\nBagian panduan pengguna ditambahkan di halaman utama.\nGlosarium singkat kini tertaut dari halaman utama.\n' > README.md
git status

Output yang Dihasilkan:

text
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   README.md

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   README.md

README.md kini muncul di dua daftar sekaligus: keranjang memuat suntingan pertama, sedangkan working tree memuat kedua suntingan. Format ringkas merangkum keadaan ganda ini dalam satu baris:

bash
git status -s

Output yang Dihasilkan:

text
MM README.md

Kode MM berarti kolom staging dan kolom working tree sama-sama melaporkan perubahan — pola yang sempat disinggung pada chapter git status . Pada kondisi inilah ketiga pembandingan benar-benar menghasilkan tiga kisah berbeda:

bash
git diff

Output yang Dihasilkan:

text
diff --git a/README.md b/README.md
index 663b3c9..b42bd08 100644
--- a/README.md
+++ b/README.md
@@ -2,3 +2,4 @@
 
 Kumpulan catatan teknis tim.
 Bagian panduan pengguna ditambahkan di halaman utama.
+Glosarium singkat kini tertaut dari halaman utama.

Pembandingan working tree vs index hanya melaporkan satu baris baru — suntingan kedua yang belum masuk index; pasangan hash 663b3c9..b42bd08 membandingkan versi di index (sudah memuat suntingan pertama) dengan versi di working tree. Lanjut ke pembandingan kedua:

bash
git diff --cached

Output yang Dihasilkan:

text
diff --git a/README.md b/README.md
index 5d6c796..663b3c9 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # Situs Dokumentasi
 
 Kumpulan catatan teknis tim.
+Bagian panduan pengguna ditambahkan di halaman utama.

Pembandingan index vs HEAD menampilkan hanya suntingan pertama — versi yang terkunci di index sejak git add di kondisi 2; suntingan kedua tidak muncul karena belum pernah di-git add. Pembandingan ketiga menggabungkan semuanya:

bash
git diff HEAD

Output yang Dihasilkan:

text
diff --git a/README.md b/README.md
index 5d6c796..b42bd08 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,5 @@
 # Situs Dokumentasi
 
 Kumpulan catatan teknis tim.
+Bagian panduan pengguna ditambahkan di halaman utama.
+Glosarium singkat kini tertaut dari halaman utama.

Working tree dibandingkan langsung dengan HEAD, sehingga kedua suntingan — yang staged maupun yang belum — tampil bersamaan. Tiga perintah, tiga keluaran berbeda, semuanya benar; yang membedakan hanyalah pasangan area yang ditanya.

Ketiga kondisi di atas memberi kacamata lengkap: git diff membaca pekerjaan yang sedang berjalan, git diff --cached membaca calon commit, dan git diff HEAD membaca total penyimpangan dari riwayat. Kosakata untuk menyebut keadaan berkas itu sendiri — untracked, modified, staged — beserta aturan perpindahannya adalah bahasan berikutnya. Lanjut ke Status File .