Kamu solo developer, kerja sendiri, nggak ada code review, nggak ada PR yang nunggu approval dua hari. Terus ngapain repot-repot bikin git workflow yang proper?
Jawaban pendeknya: karena dua minggu lagi kamu bakal lupa kenapa kamu nulis kode itu, dan git log kamu isinya cuma fix, fix2, fix final, fix final beneran. Itu bukan version control — itu chaos dengan timestamp.
Artikel ini tentang git workflow untuk solo developer yang realistis: nggak over-engineered kayak workflow tim 20 orang, tapi cukup terstruktur biar kamu nggak nangis waktu harus rollback ke versi tiga minggu lalu.
Masalah Nyata: Git Log yang Nggak Bisa Dibaca
Ini contoh git log --oneline yang sering gue lihat di repo solo developer:
a3f1c2e fix
9b2d4f1 update
3e8a7c0 wip
d1f5b2a fix lagi
7c3e9d1 coba
2a8f4e3 final
1b9c5d2 final2
Sekarang coba jawab: commit mana yang ngebreak endpoint /api/users? Kamu nggak bisa jawab tanpa git diff satu-satu.
Bandingkan dengan ini:
a3f1c2e feat(auth): add JWT refresh token endpoint
9b2d4f1 fix(api): handle null user on /api/users response
3e8a7c0 chore: update dependencies, bump express 4.18→4.19
d1f5b2a feat(db): add index on users.email column
7c3e9d1 fix(auth): correct token expiry calculation
Langsung keliatan strukturnya. Ini yang mau kita capai.
Branching Strategy untuk Solo Developer
Kalau kamu kerja sendiri, kamu nggak perlu GitFlow yang ada develop, release, hotfix, feature branch semuanya. Itu overhead yang nggak worth it.
Gue pakai model yang lebih simpel: trunk-based dengan feature branch pendek.
Strukturnya:
main— production-ready, selalu bisa di-deployfeat/nama-fitur— branch untuk fitur baru, umurnya maksimal 2–3 harifix/nama-bug— branch untuk bugfix
Contoh praktisnya:
# Mulai fitur baru
git checkout -b feat/user-authentication
# Kerja, commit, kerja, commit...
# Selesai, merge ke main
git checkout main
git merge --no-ff feat/user-authentication
git branch -d feat/user-authentication
Flag --no-ff itu penting. Tanpanya, git bakal fast-forward dan kamu kehilangan konteks bahwa sekumpulan commit itu bagian dari satu fitur. Dengan --no-ff, ada merge commit yang jelas: "ini satu unit kerja selesai."
Gotcha yang pernah gue kena: jangan biarin feature branch hidup lebih dari 3 hari. Makin lama, makin susah merge-nya karena main udah jalan duluan. Kalau fitur kamu butuh waktu lebih dari itu, pecah jadi sub-fitur yang lebih kecil.
Commit Convention: Pakai Conventional Commits
Ini standar yang worth it buat dipelajari: Conventional Commits. Formatnya:
<type>(<scope>): <description>
[optional body]
[optional footer]
Type yang paling sering dipakai:
feat— fitur barufix— bugfixchore— maintenance, update deps, configdocs— perubahan dokumentasirefactor— refactor tanpa perubahan behaviortest— tambah atau update testperf— performance improvement
Contoh commit yang bener:
git commit -m "feat(payment): integrate Midtrans payment gateway"
git commit -m "fix(auth): prevent token reuse after logout"
git commit -m "chore: add .env.example for new contributors"
git commit -m "refactor(db): extract query builder to separate module"
Kenapa ini worth it buat solo developer? Karena:
git logkamu jadi dokumentasi otomatis- Kamu bisa generate CHANGELOG otomatis (lebih lanjut di bawah)
- Waktu debugging, kamu bisa filter:
git log --grep="fix(auth)"langsung ketemu semua commit yang relate ke auth
Setup Commitlint Biar Nggak Lupa Convention
Masalahnya, waktu lagi buru-buru, kamu bakal nulis git commit -m "fix" lagi. Solusinya: enforce convention dengan commitlint + husky.
Install dulu:
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
Buat config commitlint:
# commitlint.config.js
echo "module.exports = { extends: ['@commitlint/config-conventional'] }" > commitlint.config.js
Setup husky:
npx husky init
echo "npx --no -- commitlint --edit \$1" > .husky/commit-msg
Sekarang kalau kamu coba commit dengan pesan yang nggak sesuai format:
git commit -m "fix aja dulu"
# ⧗ input: fix aja dulu
# ✖ subject may not be empty [subject-empty]
# ✖ type may not be empty [type-empty]
# ✖ found 1 problems, 0 warnings
Git bakal nolak commit-nya. Ini annoying di awal, tapi dua minggu kemudian kamu bakal berterima kasih.
Gotcha: kalau kamu pakai monorepo atau project yang bukan Node.js, kamu perlu workaround lain. Untuk Python project misalnya, kamu bisa pakai pre-commit framework dengan hook conventional-pre-commit.
# .pre-commit-config.yaml
repos:
- repo: https://github.com/compilerla/conventional-pre-commit
rev: v3.4.0
hooks:
- id: conventional-pre-commit
stages: [commit-msg]
args: [feat, fix, chore, docs, refactor, test, perf]
Tagging dan Versioning yang Benar
Solo developer sering skip tagging. Padahal tag itu yang bikin kamu bisa bilang "deploy yang kemarin" dengan tepat, bukan nebak-nebak berdasarkan tanggal.
Pakai semantic versioning: MAJOR.MINOR.PATCH
MAJOR— breaking changeMINOR— fitur baru, backward compatiblePATCH— bugfix
# Tag versi baru
git tag -a v1.2.0 -m "Release v1.2.0: add payment integration"
git push origin v1.2.0
# Lihat semua tag
git tag -l
# Checkout ke versi tertentu
git checkout v1.1.0
Kalau kamu udah pakai Conventional Commits, kamu bisa generate CHANGELOG dan bump version otomatis pakai standard-version atau release-it:
npm install --save-dev release-it
# Tambah ke package.json scripts:
# "release": "release-it"
npm run release
# Tool ini bakal:
# 1. Bump version di package.json
# 2. Generate CHANGELOG.md dari commit history
# 3. Buat git tag
# 4. Push ke remote
Git Alias untuk Workflow Sehari-hari
Ini yang sering dilewatin tapi bikin produktivitas naik lumayan. Setup alias di ~/.gitconfig:
[alias]
# Log yang enak dibaca
lg = log --oneline --graph --decorate --all
# Status pendek
st = status -s
# Lihat diff yang belum di-stage
d = diff
# Lihat diff yang sudah di-stage
dc = diff --cached
# Undo commit terakhir tapi keep changes
undo = reset HEAD~1 --mixed
# Amend commit terakhir tanpa ganti pesan
oops = commit --amend --no-edit
# Branch cleanup: hapus branch yang sudah di-merge
cleanup = !git branch --merged | grep -v '\*\|main\|master' | xargs -n 1 git branch -d
Contoh penggunaan:
# Lihat history dengan visual graph
git lg
# Typo di commit terakhir? Tambah file yang ketinggalan?
git add file-yang-ketinggalan.js
git oops # amend tanpa ganti pesan
# Bersihkan branch yang udah di-merge
git cleanup
Gotcha dengan git oops: jangan pakai ini kalau commit yang mau kamu amend udah di-push ke remote. Itu bakal rewrite history dan bikin masalah. Kalau udah push, buat commit baru aja.
Stash yang Bener: Jangan Cuma git stash
Kamu pasti pernah punya multiple stash dan bingung isinya apa:
git stash list
# stash@{0}: WIP on feat/payment: a3f1c2e feat(auth): ...
# stash@{1}: WIP on main: 9b2d4f1 fix(api): ...
# stash@{2}: WIP on main: 3e8a7c0 chore: ...
Pakai git stash push -m dengan nama yang deskriptif:
# Stash dengan nama
git stash push -m "wip: midtrans webhook handler, belum handle refund case"
# Pop stash spesifik berdasarkan nama
git stash list # cari index-nya
git stash pop stash@{0}
Kalau kamu mau stash hanya file tertentu:
git stash push -m "wip: experiment dengan redis cache" -- src/cache.js src/config/redis.js
.gitignore yang Sering Kelupaan
Ini bukan tentang .env yang semua orang udah tau. Yang sering kelupaan:
# Editor artifacts
.vscode/settings.json # keep .vscode/extensions.json kalau mau share recommendations
.idea/
*.swp
*.swo
# OS files
.DS_Store
Thumbs.db
# Debug logs
npm-debug.log*
yarn-debug.log*
# Test coverage
coverage/
.nyc_output/
# Build artifacts yang sering ke-commit nggak sengaja
dist/
build/
*.min.js # kalau ini generated
# Local override files
docker-compose.override.yml
.env.local
Kalau kamu udah terlanjur commit file yang harusnya di-ignore:
# Hapus dari tracking tapi keep di local
git rm --cached .env
git rm --cached -r dist/
# Commit perubahannya
git commit -m "chore: remove accidentally tracked files from repo"
Yang Gue Lakuin Sekarang
Setup gue saat ini untuk setiap project baru:
-
Init dengan template — gue punya shell script yang langsung setup
commitlint,husky,.gitignorestandar, danrelease-itconfig dalam satu command. -
Branch protection lokal — walaupun repo pribadi, gue set reminder di calendar tiap Jumat untuk merge semua feature branch yang udah selesai dan cleanup branch yang stale.
-
Weekly tag — kalau ada progress signifikan minggu itu, gue tag dengan format
v0.x.0-alpha.YYYYMMDD. Ini overkill buat beberapa orang, tapi gue pernah kehilangan satu minggu kerja karena nggak bisa identify "versi yang jalan kemarin" dengan tepat. -
Git log sebagai standup — karena solo, gue pakai
git lg --since="1 week ago" --author="Marcus"sebagai weekly review: ngapain aja minggu ini, apakah fokus atau scatter.
Kalau kamu baru mulai, jangan implement semua sekaligus. Mulai dari Conventional Commits dulu — itu yang paling besar impact-nya. Setelah itu baru tambah commitlint biar enforce otomatis, kemudian tagging, kemudian alias.
Git workflow yang bagus buat solo developer bukan tentang ikutin semua best practice tim enterprise. Ini tentang bikin future-you bisa kerja efisien tanpa harus reverse-engineer keputusan past-you.