Di Halaman Ini

git status

Ringkasnya: git status adalah perintah hanya-baca yang memeriksa keadaan working directory, staging area (index), dan riwayat commit (HEAD). Dengan perbandingan tiga arah yang cepat, Git melaporkan file yang belum dilacak, diubah, atau di-stage untuk commit berikutnya. Ini adalah alat utama untuk memantau keadaan repository sebelum menulis perubahan ke disk.


Apa Sebenarnya yang Dilakukan git status?

Untuk benar-benar menguasai Git, tinggalkan anggapan bahwa Git hanyalah alat untuk melacak diff file. Bayangkan Git sebagai pengelola tiga tree konten yang berbeda. Tree ini mewakili tahap berbeda dalam siklus hidup kode Anda:

  1. The Working Directory (or Working Tree): Sandbox di filesystem sistem operasi Anda. Saat mengedit file di VS Code atau Vim, Anda langsung mengubah Working Directory.
  2. The Index (or Staging Area): File cache biner yang disimpan di .git/index. File ini berfungsi sebagai manifes pra-commit—daftar datar yang memuat path file, permission, dan hash SHA-1 persis dari file untuk commit berikutnya.
  3. HEAD (The Commit Terakhir): Pointer ke commit object di ujung branch saat ini. HEAD mewakili checkpoint terbaru repository Anda.
graph LR
    subgraph "The Three Trees of Git"
        A[Working Directory<br>Local Files] -->|git add| B[Index / Staging Area<br>.git/index]
        B -->|git commit| C[HEAD<br>Last Commit]
    end
    style A fill:#f9f,stroke:#333,stroke-width:2px
    style B fill:#bbf,stroke:#333,stroke-width:2px
    style C fill:#bfb,stroke:#333,stroke-width:2px

Saat Anda menjalankan git status, Git tidak memindai seluruh riwayat commit. Sebaliknya, Git menjalankan diff tiga arah yang sangat dioptimalkan:

  • Perbandingan A: Index vs. HEAD. Git membandingkan pemetaan path dan hash di staging area (.git/index) dengan tree object yang ditunjuk oleh HEAD. Jika hash file di Index berbeda dari hash di HEAD, atau file ada di Index tetapi tidak ada di HEAD, file tersebut dikategorikan sebagai “Changes to be committed” (di-stage).
  • Perbandingan B: Working Directory vs. Index. Git membandingkan file saat ini di hard drive dengan pemetaan path dan hash yang tersimpan di Index. Jika keadaan file di working directory berbeda dari catatan staging-nya, file tersebut dikategorikan sebagai “Changes not staged for commit” (diubah).
  • Perbandingan C: Working Directory vs. Index (Pemeriksaan File Belum Dilacak). File apa pun yang ditemukan di working directory tetapi tidak memiliki entri yang sesuai di Index (dan tidak diabaikan oleh aturan .gitignore) dikategorikan sebagai “Untracked files”.

Cache Stat: Mengapa git status Terasa Instan

Dalam proyek besar dengan ratusan ribu file, melakukan hashing pada setiap file working directory untuk membandingkannya dengan Index akan membuat git status sangat lambat.

Untuk mencegahnya, Git menggunakan teknik Stat Caching. File .git/index berisi metadata setiap file yang dilacak, termasuk:

  • mtime: Stempel waktu modifikasi terakhir.
  • ctime: Stempel waktu perubahan metadata terakhir.
  • dev / ino: Nomor perangkat filesystem dan inode.
  • uid / gid: Pemilik pengguna dan grup.
  • file size: Ukuran file dalam byte.

Saat Anda menjalankan git status, Git meminta statistik filesystem file di working directory kepada sistem operasi (melalui system call lstat() yang sangat cepat). Jika ukuran file, inode, atau waktu modifikasi cocok dengan nilai yang di-cache di .git/index, Git menganggap konten file tidak berubah. Git melewati pembacaan konten file dan tidak menghitung ulang hash SHA-1. Hanya jika metadata stat berbeda Git akan membuka file, menghitung hash, lalu memeriksa perbedaannya.


Apa yang Terjadi di Dalam .git/ (Eksplorasi langsung)

Mari kita uraikan perilaku git status dengan membuat repository baru dan mengamati perubahan perbandingan file internalnya pada setiap tahap siklus hidup file.

Langkah 1: Inisialisasi Repository

Mari mulai dengan menginisialisasi repository bersih menggunakan git init.

$ mkdir git-status-demo && cd git-status-demo
$ git init
Initialized empty Git repository in /git-status-demo/.git/

Jika kita memeriksa keadaan direktori .git, terlihat bahwa belum ada file index dan HEAD menunjuk ke branch default yang belum memiliki commit.

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

$ ls -l .git/index
ls: cannot access '.git/index': No such file or directory

Jika sekarang kita menjalankan git status:

$ git status
On branch main

No commits yet

nothing to commit (create/copy files and use "git add" to track)

Di balik layar: Git memeriksa .git/index. Karena file itu tidak ditemukan, Git menyimpulkan bahwa belum ada file yang dilacak. Git membaca .git/HEAD untuk menemukan branch saat ini (main), menyelesaikan referensi branch tersebut (yang belum ada karena belum ada commit), lalu menyimpulkan bahwa belum ada commit.

Langkah 2: Menambahkan File yang Belum Dilacak

Mari buat file bernama README.md.

$ echo "# Git Status Demo" > README.md

Sekarang mari periksa git status:

$ git status
On branch main

No commits yet

Untracked files:
  (use "git add <file>..." to include in what will be committed)
	README.md

nothing added to commit but untracked files present (use "git add" to track)

Di balik layar:

  1. Git memindai working directory dan menemukan README.md.
  2. Git mencoba membaca .git/index. File index masih belum ada.
  3. Karena file ada di working directory tetapi tidak ada di index, Git menandainya sebagai belum dilacak.

Langkah 3: Melakukan Staging File

Mari lakukan staging file menggunakan git add.

$ git add README.md

Seketika, dua hal terjadi di dalam .git/:

  1. Git memampatkan isi README.md dan menulis blob object baru ke .git/objects/.
  2. Git membuat file .git/index dan menulis entri README.md, termasuk statistik file dan hash SHA-1 blob tersebut.

Mari verifikasi entri index menggunakan plumbing command git ls-files --stage:

$ git ls-files --stage
100644 c5d3bc8d139371ff4cf9e97623b2255fb722b2d9 0	README.md

Mari verifikasi bahwa blob ada di .git/objects/:

$ git cat-file -t c5d3bc8d139371ff4cf9e97623b2255fb722b2d9
blob

$ git cat-file -p c5d3bc8d139371ff4cf9e97623b2255fb722b2d9
# Git Status Demo

Now let’s run git status:

$ git status
On branch main

No commits yet

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)
	new file:   README.md

Di balik layar:

  1. Git membaca .git/HEAD -> refs/heads/main. Referensi refs/heads/main masih belum ada (belum ada commit).
  2. Git membaca .git/index dan menemukan satu entri: README.md yang menunjuk ke blob c5d3bc8d1393....
  3. Karena HEAD kosong dan index berisi README.md, index memiliki file yang tidak ada di HEAD. Karena itu, file dilaporkan sebagai di-stage untuk commit (file baru).
  4. Git memeriksa stat README.md di working directory terhadap stat yang di-cache di .git/index. Keduanya cocok, sehingga tidak ada perubahan yang belum di-stage.

Langkah 4: Membuat Commit

Mari commit perubahan menggunakan git commit.

$ git commit -m "Initial commit"
[main (root-commit) 55a420b] Initial commit
 1 file changed, 1 insertion(+)
 create mode 100644 README.md

Sekarang mari periksa git status:

$ git status
On branch main
nothing to commit, working tree clean

Di balik layar:

  1. Commit tersebut membuat commit object (hash: 55a420b...) dan tree object yang merepresentasikan keadaan repository.
  2. Git memperbarui .git/refs/heads/main agar berisi hash commit object baru ini.
  3. Saat git status berjalan, Git menyelesaikan HEAD -> refs/heads/main -> commit 55a420b.
  4. Git membandingkan tree di dalam commit 55a420b (yang mencantumkan README.md dengan blob c5d3bc8d1393...) dengan staging index .git/index (yang juga mencantumkan README.md dengan blob c5d3bc8d1393...). Hash-nya identik, artinya tidak ada perubahan yang di-stage.
  5. Git membandingkan stat index dengan stat filesystem. Keduanya cocok, artinya tidak ada perubahan yang dimodifikasi.

Langkah 5: Mengubah File

Mari ubah README.md di working directory:

$ echo "# Git Status Demo" > README.md
$ echo "Added a new line of text." >> README.md

Mari jalankan git status:

$ git status
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")

Di balik layar:

  1. Git memanggil lstat() pada README.md dan membaca metadatanya. Waktu modifikasi (mtime) dan ukuran file berubah dibandingkan dengan entri di .git/index.
  2. Git membuka README.md, menghitung hash SHA-1 konten yang diubah (menghasilkan hash baru: c7cb148f2e21f06939fe9ac90d42a302294f12dd).
  3. Karena hash hasil perhitungan berbeda dari yang tersimpan di .git/index (c5d3bc8d1393...), Git melaporkan file sebagai diubah tetapi belum di-stage.
  4. Git membandingkan entri index dengan entri tree milik HEAD. Keduanya memiliki c5d3bc8d1393.... Karena cocok, tidak ada perubahan yang di-stage.
graph TD
    subgraph "Three-Way Hash Comparison"
        HEAD["HEAD Commit Tree<br>Hash: c2ba505..."]
        Index["Staging Index<br>Hash: c2ba505..."]
        Work["Working Directory<br>Hash: d78be55..."]
    end
    HEAD ===|Staged: Match| Index
    Index---|Modified: Mismatch| Work

Opsi Perintah dan Penggunaan Lanjutan

Meskipun git status sederhana, beberapa opsi lanjutan membuatnya lebih berguna untuk scripting, debugging, dan melihat keadaan yang kompleks.

1. Format Singkat (--short atau -s)

Saat bekerja dengan banyak file yang diubah, output verbose default bisa terasa berlebihan. Format singkat menampilkan perubahan dalam dua kolom yang ringkas.

$ git status -s
 M README.md
?? new_script.js

Kolom mewakili Staging Area (kolom 1) dan Working Directory (kolom 2):

  • M (spasi di kolom 1, M di kolom 2): File diubah di working directory, tetapi perubahannya belum di-stage.
  • M (M di kolom 1, spasi di kolom 2): File diubah dan perubahannya di-stage di index.
  • MM (kedua kolom): File diubah, perubahannya di-stage, lalu file diubah lagi di working directory.
  • A : File baru ditambahkan ke staging area.
  • ??: File belum dilacak.

2. Menyertakan File yang Diabaikan (--ignored)

Secara default, file yang cocok dengan pola .gitignore disembunyikan dari status. Jika mencari tahu mengapa file tertentu tidak dilacak, gunakan flag --ignored.

$ echo "logs/" > .gitignore
$ mkdir logs && touch logs/debug.log
$ git status --ignored
On branch main
...
Ignored files:
  (use "git add -f <file>..." to include in what will be committed)
	logs/

3. Scripting dengan --porcelain

Jika Anda menulis shell script, alias git, atau script CI/CD untuk memeriksa perubahan yang belum di-commit, jangan pernah mem-parse output standar git status karena dapat berubah antarversi Git. Gunakan --porcelain sebagai gantinya.

$ git status --porcelain
 M README.md
?? new_script.js

Flag --porcelain menjamin format output tetap kompatibel dengan versi sebelumnya dan stabil pada versi Git mendatang. Flag ini mencetak output dalam format yang dapat dibaca mesin dan mudah diprediksi, tanpa warna atau teks bantuan.

Untuk memeriksa dengan cepat perubahan yang belum di-commit dalam bash script:

if [ -z "$(git status --porcelain)" ]; then
    echo "Working directory is clean. Proceeding..."
else
    echo "Error: You have uncommitted changes!" >&2
    exit 1
fi

Skenario Dunia Nyata: Permission File dan Akhir Baris

Terkadang git status menampilkan file sebagai diubah, tetapi saat menjalankan git diff, Anda sama sekali tidak melihat perubahan pada kode. Biasanya ini disebabkan oleh dua hal: akhir baris atau perubahan mode file.

Skenario A: Permission File (chmod)

Git melacak bit executable file (100755 untuk file executable, 100644 untuk file biasa). Jika Anda atau script mengubah permission file (misalnya, chmod +x script.sh), Git akan melaporkan file tersebut sebagai diubah.

Jika ini terjadi pada proyek yang tidak memedulikan permission file (misalnya, tim lintas platform Windows/macOS/Linux), Anda dapat mengonfigurasi Git agar mengabaikan perubahan permission:

$ git config core.filemode false

Skenario B: Ketidakkonsistenan Akhir Baris (LF vs CRLF)

Sistem Windows secara historis menggunakan Carriage Return + Line Feed (CRLF) sebagai akhir baris, sedangkan Linux dan macOS menggunakan Line Feed (LF). Jika editor teks mengubah akhir baris secara otomatis, Git akan menandai seluruh file sebagai diubah karena hash binernya berbeda.

Untuk memperbaiki ketidakcocokan akhir baris secara global, konfigurasikan pengaturan autocrlf Git:

# On Windows
$ git config --global core.autocrlf true

# On macOS/Linux
$ git config --global core.autocrlf input

Kesalahan dan Jebakan Umum

1. Menjalankan git status di Subdirektori

Jika Anda menjalankan git status dari subdirektori bertingkat, secara default Git menampilkan path relatif terhadap subdirektori tersebut, yang terkadang membuat path tampak membingungkan. Untuk melihat path relatif terhadap direktori root tempat pun Anda menjalankan perintah, jalankan:

$ git status --relative=false

2. File yang Di-stage Masih Ditampilkan di Bawah “Changes not staged for commit”

Ini sering membingungkan pemula. Jika Anda melakukan staging file dengan git add file.txt, lalu membuka editor dan menambahkan baris lain ke file.txt, git status akan mencantumkan file tersebut dua kali:

Changes to be committed:
	modified:   file.txt

Changes not staged for commit:
	modified:   file.txt

Ini terjadi karena Git melakukan staging snapshot persis file saat git add dijalankan. Edit setelahnya hanya ada di working directory dan harus di-stage lagi.

3. File di .gitignore Masih Muncul

Jika sebuah file sudah dilacak Git sebelum Anda menambahkannya ke .gitignore, file tersebut akan tetap muncul di git status saat diubah. .gitignore hanya mencegah file yang belum dilacak agar tidak mulai dilacak. Untuk berhenti melacak file tanpa menghapusnya dari komputer, Anda harus menghapusnya dari index:

$ git rm --cached path/to/file.txt

Referensi Cepat Perintah

PerintahDeskripsi
git statusMenampilkan status dalam format verbose lengkap (default).
git status -s / --shortMenampilkan status dalam format dua kolom ringkas.
git status -b / --branchMenampilkan detail branch dan tracking branch.
git status --ignoredMenampilkan file yang diabaikan oleh .gitignore.
git status --porcelainOutput yang dioptimalkan untuk penguraian oleh mesin dan scripting.
git status -uallMenampilkan setiap file dalam direktori yang belum dilacak, bukan hanya nama direktorinya.

FAQ (Pertanyaan yang Sering Diajukan)

Mengapa git status menampilkan “On branch main, nothing to commit, working tree clean”?

Pesan ini menunjukkan bahwa ketiga tree Git berada dalam keadaan sepenuhnya selaras. Hash SHA-1 semua file di Working Directory cocok dengan hash yang tercantum di Staging Index (.git/index), yang selanjutnya cocok dengan hash yang terdaftar di tree commit HEAD. Tidak ada perubahan yang perlu dibuat atau dicatat.

Bagaimana git status mengetahui bahwa file telah berganti nama?

Git sebenarnya tidak melacak rename secara eksplisit; Git mendeteksinya. Saat file dihapus dari satu path dan ditambahkan di path lain, git status membaca index dan membandingkan hash kontennya. Jika konten file yang dihapus dan file yang ditambahkan identik (atau sangat mirip), Git menghitung indeks kemiripan dan melaporkan file sebagai di-rename (misalnya, renamed: old_file.txt -> new_file.txt).

Apakah menjalankan git status dapat mengubah file saya?

Tidak. git status sepenuhnya hanya-baca terhadap working directory dan riwayat commit Anda. Perintah ini memeriksa file dan membandingkan metadata. Paling jauh, Git dapat memperbarui stat cache di .git/index agar cocok dengan waktu filesystem saat ini (untuk meningkatkan performa perintah berikutnya), tetapi tidak akan pernah mengubah source code atau membatalkan perubahan Anda.

Bagaimana menggunakan git status untuk memeriksa apakah saya tertinggal/lebih maju dari remote branch?

Jika branch lokal Anda melacak remote branch (misalnya, origin/main), git status akan membandingkan referensi HEAD branch lokal dengan referensi pelacakan remote yang di-cache (.git/refs/remotes/origin/main). Git akan menampilkan pesan seperti “Your branch is ahead of ‘origin/main’ by 2 commits” atau “Your branch is behind…”. Perhatikan bahwa informasi ini berdasarkan fetch terakhir; Git tidak meminta data ke server remote saat menjalankan git status, jadi jalankan git fetch terlebih dahulu untuk memperoleh informasi pelacakan terbaru yang akurat.


Uji Pengetahuan

Memuat kuis…