Laporan bug darurat masuk tepat ketika setengah refactor belum selesai di branch fitur. Opsi klasiknya mahal: git stash, pindah branch, perbaiki, kembali, git stash pop, dan berdoa konflik tidak muncul — atau meng-clone ulang seluruh repository hanya untuk satu berkas. git worktree menawari jalan ketiga: satu repository, banyak direktori kerja, masing-masing berdiri di branch sendiri, dan semuanya berbagi object database yang sama. Bab ini membongkar cara kerjanya, membuktikan bahwa satu branch tidak boleh di dua tempat sekaligus, mengukur penghematannya dibanding clone, lalu merapikan worktree yang tak terpakai.

Menambah Worktree #

Repository latihan menampung dua branch — main yang stabil dan fitur-desain yang sedang dikerjakan:

bash
mkdir latihan-worktree && cd latihan-worktree
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"
printf 'beranda v1\n' > beranda.md
git add beranda.md
git commit -m "Tambah beranda"
git switch -c fitur-desain
printf 'mockup desain\n' > mockup.md
git add mockup.md
git commit -m "Tambah mockup"
git switch main

Hotfix menuntut branch baru sementara diskusi desain menyambung branch yang ada — dua bentuk git worktree add:

bash
git worktree add -b hotfix ../kerja-hotfix
git worktree add ../kerja-fitur fitur-desain

Output yang Dihasilkan (add -b):

text
Preparing worktree (new branch 'hotfix')
HEAD is now at f6e6082 Tambah beranda

Output yang Dihasilkan (add):

text
Preparing worktree (checking out 'fitur-desain')
HEAD is now at db8a9d4 Tambah mockup

Dua keluaran ini layak dibedah per baris. Preparing worktree mengumumkan direktori kerja baru sedang disiapkan; teks dalam kurung menyebut bentuknya — (new branch 'hotfix') berarti worktree sekaligus melahirkan branch hotfix yang menunjuk commit main saat itu, sedangkan (checking out 'fitur-desain') berarti worktree meng-checkout branch yang sudah ada. Baris kedua, HEAD is now at, adalah hasil git switch yang dijalankan di dalam direktori baru tersebut — hash akan berbeda di mesin pembaca, dan db8a9d4 menegaskan bahwa kerja-fitur tidak menyalin kondisi main, melainkan kondisi ujung fitur-desain.

Daftar seluruh direktori kerja aktif dilihat dengan satu perintah:

bash
git worktree list

Output yang Dihasilkan:

text
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/latihan-worktree  f6e6082 [main]
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-fitur       db8a9d4 [fitur-desain]
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-hotfix      f6e6082 [hotfix]

Jalur pada keluaran menyesuaikan lokasi sandbox di mesin masing-masing. Tiga baris, tiga direktori kerja, tiga branch: baris pertama adalah repository utama di latihan-worktree yang berdiri di main, disusul dua worktree tambahan. Kolom hash menunjukkan bahwa kerja-hotfix memang berangkat dari titik yang sama dengan main (f6e6082), sementara kerja-fitur berdiri lebih maju (db8a9d4).

Satu Branch Hanya di Satu Worktree #

Coba pikirkan percobaan nakal: meng-checkout hotfix sekali lagi di worktree ketiga.

bash
git worktree add ../kerja-lain hotfix

Output yang Dihasilkan:

text
Preparing worktree (checking out 'hotfix')
fatal: 'hotfix' is already used by worktree at '/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-hotfix'

Git menolak dengan tegas. Alasannya struktural, bukan semata aturan: branch adalah berkas referensi tunggal (refs/heads/hotfix), sementara setiap worktree memiliki HEAD dan index sendiri — dua direktori yang sama-sama “berdiri di hotfix” akan saling menimpa isi berkas dan status staging satu sama lain setiap kali keduanya bercommit. Larangan ini menjaga kekonsistenan; kebutuhan menginginkan branch yang sama di dua tempat dijawab dengan branch baru, atau flag --detach untuk worktree yang berdiri lepas dari branch mana pun.

Anatomi: Berbagi Object Database #

Mesin di balik worktree adalah berkas penunjuk, bukan salinan repository:

bash
cat ../kerja-hotfix/.git
ls .git/worktrees

Output yang Dihasilkan (cat .git):

text
gitdir: /home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/latihan-worktree/.git/worktrees/kerja-hotfix

Output yang Dihasilkan (ls .git/worktrees):

text
kerja-fitur
kerja-hotfix

Berkas .git di dalam worktree hanyalah satu baris teks yang menunjuk balik ke .git/worktrees/kerja-hotfix milik repository utama — pola yang persis sama dengan .git milik submodule . Direktori .git/worktrees/ menampung HEAD, index, dan berkas-berkas kecil milik tiap worktree; seluruh object database, refs, dan konfigurasi tetap tunggal. Ukuran memperlihatkan penghematannya:

bash
du -sh .git ../kerja-hotfix
cd ..
git clone latihan-worktree klon-wt
du -sh klon-wt/.git

Output yang Dihasilkan (du di worktree):

text
292K    .git
12K    ../kerja-hotfix

Output yang Dihasilkan (du di klon):

text
224K    klon-wt/.git

Angka pastinya mengikuti ukuran blok filesystem, tetapi polanya stabil: repository utama menampung seluruh objek (292K), worktree tambahan hanya membayar isi working directory plus metadata kecil (12K), sementara clone membeli object database sendiri yang lengkap (224K). Repository contoh ini kecil sehingga selisihnya terasa biasa — pada repository ratusan megabyte, satu worktree tetap 12K-an sementara setiap clone menggandakan ratusan megabyte itu. Isi kedua worktree pun berbeda sesuai branch-nya:

text
kerja-hotfix:
beranda.md
kerja-fitur:
beranda.md
mockup.md

kerja-hotfix hanya berisi berkas dari main, sedangkan kerja-fitur menambah mockup.md milik fitur-desain.

Bekerja Paralel lalu Merapikan #

Sekarang bukti bahwa pekerjaan benar-benar paralel. Dari dalam kerja-hotfix, commit perbaikan dibuat seperti biasa:

bash
cd ../kerja-hotfix
printf 'perbaikan cepat\n' > tambalan.md
git add tambalan.md
git commit -m "Perbaikan cepat di hotfix"
cd ../latihan-worktree
git worktree list

Output yang Dihasilkan:

text
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/latihan-worktree  f6e6082 [main]
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-fitur       db8a9d4 [fitur-desain]
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-hotfix      35bc27f [hotfix]

Hanya baris kerja-hotfix yang bergerak ke 35bc27f; main tetap di f6e6082 dan fitur-desain tetap di db8a9d4 — direktori kerja yang lain tidak tersentuh sama sekali. Setelah pekerjaan selesai, worktree dirapikan tanpa sisa:

bash
git worktree remove ../kerja-fitur
git worktree list

Output yang Dihasilkan:

text
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/latihan-worktree  f6e6082 [main]
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-hotfix      35bc27f [hotfix]

Perintah git worktree remove sendiri selesai tanpa keluaran; kerja-fitur lenyap dari daftar beserta direktorinya, sementara branch fitur-desain tetap tersimpan. Bila direktori worktree justru dihapus manual dengan rm -rf, Git tetap menjalankan janjinya:

bash
rm -rf ../kerja-hotfix
git worktree list

Output yang Dihasilkan:

text
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/latihan-worktree  f6e6082 [main]
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/kerja-hotfix      35bc27f [hotfix] prunable

Tanda prunable menandai entri worktree yang direktorinya sudah tidak ada — Git tidak menghapus catatannya diam-diam, tetapi menandainya siap dirapikan:

bash
git worktree prune
git worktree list

Output yang Dihasilkan:

text
/home/z/my-project/tutorial-extracted/work/sandbox/mengelola-file-dan-repository/part-b/latihan-worktree  f6e6082 [main]

git worktree prune membersihkan seluruh entri prunable sekaligus; branch hotfix sendiri tetap hidup dan bisa di-merge ke main kapan saja. Daftar lengkap opsi — termasuk lock untuk worktree di removable media — tersedia di dokumentasi git worktree .

Kapan Worktree, Kapan Clone #

Aspekgit worktreegit clone
Object databaseDibagi — satu salinanDigandakan penuh
Branch sama sekaligusDilarangBoleh (dengan tiap salinannya)
Remote dan konfigurasiSama untuk semua worktreeKonfigurasi terpisah per clone
Ukuran tambahanMetadata + isi working directorySeluruh repository
Isolasi perubahan konfigurasiTidak adaPenuh

Pola pemakaian paling umum: hotfix mendesak saat refactor berjalan, atau menaruh versi rilis lama bersebelahan dengan main untuk perbandingan perilaku. Kebalikannya, clone lebih tepat bila tiap salinan butuh remote, identitas, atau konfigurasi berbeda — misalnya dua akun berbeda pada satu host.

Banyak direktori kerja berarti banyak pula berkas sementara yang menumpuk: hasil build di satu worktree, draf di yang lain, sampah di mana-mana. Chapter penutup section ini menyediakan alat sapunya, mulai dari prinsip dry-run hingga kombinasi reset dan clean: Membersihkan Repository .