Branching Git Alternatif dengan Worktree

Tentu kita udah nggak asing lagi dengan branch, merge, stash, dan istilah Git yang lain. Dalam artikel ini saya ingin bahas satu fitur Git yang jarang atau mungkin nggak pernah kita dengar sebelumnya, yaitu worktree.

Branch bisa dibilang seperti virtual-directory. Setiap branch isinya boleh beda, tapi lokasi fisiknya masih sama dalam satu direktori root. Waktu kita checkout sebuah branch, isi direktori root ini diganti file yang ada di branch itu. Ini bisa dianggap fitur Git atau kelemahan (liability), tergantung situasi.

Sejak versi 2.5 Git punya fitur namanya worktree yang memungkinkan kita bikin branch di direktori di luar root.

Terus apa bedanya dengan bikin klon di direktori lain?

Misalnya kita punya 2 repositori lokal hasil klon remote yang sama, masing-masing klon nggak punya hubungan langsung dengan yang lain. Klon di direktori dir_1/, nggak tau apa2 tentang klon di dir_2/.

Nah kalo worktree, semua masih berhubungan seperti branch biarpun lokasinya beda.

Bedanya antara klon dengan worktree kurang lebih kayak begini:

Git Clone

Git Worktree

Jadi worktree, biarpun lokasi fisiknya beda direktori tetap terhubung dengan database Git (HEAD, refs, dll) yang sama.

Awalnya, setiap repo punya satu worktree yang bisa disebut main tree.

~/myproject (master)
$ git log --oneline
f9cd710 initial

$ git worktree list
~/myproject  f9cd710 [master]

Misalnya kita terus bikin branch namanya docs:

~/myproject (master)
$ git checkout -b docs

~/myproject (docs)
$ touch readme.md
$ git commit -m 'add readme'
[docs bf3ce3a] readme
 1 file changed, 1 insertion(+)
 create mode 100644 docs/readme.md

Karena sesuatu hal, misalnya ada conflict atau kita perlu updet branch lain yang lebih penting, kita mau pindahin docs ke direktori, docs_temp. Di sini kita bisa bikin worktree.

~/myproject (docs)
$ git worktree add ../docs_temp
Preparing ../docs_temp (identifier add_styles)
HEAD is now at bf3ce3a add readme

~/myproject (docs)
$ git worktree list
~/myproject  f9cd710 [master]
~/docs_temp  bf3ce3a [docs]

Branch yang udah dibikinin worktree, nggak bisa lagi di-checkout.

~/myproject (master)
$ git checkout docs
fatal: 'docs' is already checked out at '~/docs_temp'

Kalo mau pindah dari master ke branch docs, kita harus pindah direktori. Karena beda direktori, kita nggak perlu commit / stash dulu kerjaan di master, langsung aja pindah.

~/myproject (master)
$ cd ../docs_temp

~/docs_temp (docs)
$ git status
On branch docs
nothing to commit, working tree clean

$ git log --oneline
bf3ce3a add readme
f9cd710 initial

Karena masing-masing worktree isinya branch, merge & rebase ya kayak biasanya, ga ada yang spesial.

Misalnya kita punya worktree styles.

~/myproject (master)
$ git worktree add ../styles
Preparing ../styles (identifier styles)
HEAD is now at bf3ce3a readme

Masing-masing branch ada commit. Jadi master & styles kondisinya udah diverge.

~/styles (styles)
$ touch main.css
$ git add .
$ git commit -m 'add main.css'
[styles 6f980e1] add main.css
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 main.css

~/myproject (master)
$ touch index.js
$ git add .
$ git commit -m 'add index.js'
[master c7cc6af] add index.js
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 index.js

Kalo kita mau rebase styles dengan master:

~/styles (styles)
$ git rebase master
First, rewinding head to replay your work on top of it...
Fast-forwarded styles to master.

Sebaliknya kalo mau merge styles ke master:

~/myproject (master)
$ git merge styles
Updating 6cf8ae8..6f980e1
Fast-forward
 main.css | 0
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 main.css

Merge / rebase pake nama branch, bukan nama direktori.

Menghapus Worktree

Caranya:
1. Hapus direktorinya
2. Jalanin perintah git worktree prune

Biarpun direktorinya udah dihapus, masih ada referensi ke worktree styles:

~/myproject (master)
$ rm -rf ../styles 
$ git worktree list
~/myproject   c7cc6af [master]
~/styles      6f980e1 [styles]

Jadi harus diikuti perintah prune:

~/myproject (master)
$ git worktree prune 
$ git worktree list
~/myproject   c7cc6af [master]

Dokumentasi tentang worktree bisa dibaca di sini: git-worktree

Sekian. Mudah-mudahan bermanfaat.

Also in this category ...


Leave a Reply

Your email address will not be published. Required fields are marked *