Apa Itu Git Pull Request? Panduan Praktis Code Review untuk Tim
Pendahuluan
Pernah ngerasa fiturmu sebenarnya sudah jadi, tapi pas di-merge malah bikin bug di tempat lain? Nah, di sinilah pull request jadi penting. PR bukan cuma langkah administratif sebelum merge, tapi checkpoint kualitas supaya perubahanmu aman masuk ke branch utama.
Di GitHub namanya pull request (PR), di GitLab disebut merge request (MR). Istilahnya beda, alurnya hampir sama: kamu kirim perubahan, tim review, lalu kode baru di-merge kalau sudah lolos cek.
Di artikel ini, kamu bakal belajar dari dasar sampai praktik: apa itu pull request, cara bikin PR yang enak direview, cara kasih feedback yang efektif, sampai cara otomatisasi check lewat CI/CD.
Daftar Isi
- Apa Itu Pull Request?
- Siklus Hidup Pull Request
- Cara Membuat Pull Request
- Menulis Deskripsi PR yang Efektif
- Menggunakan PR Template
- Best Practice Code Review
- Menjaga PR Tetap Bersih
- Otomasi PR dengan CI/CD
- Anti-Pattern PR yang Harus Dihindari
- Strategi PR: Draft, Stacked, dan Pair PR
- Kesimpulan
Apa Itu Pull Request?
Pull request adalah permintaan untuk menggabungkan perubahan dari branch kamu ke branch target (biasanya main atau develop).
Contoh simpel: kamu bikin fitur login di branch feature/login, lalu buka PR ke main. Sebelum di-merge, reviewer cek dulu logika, test, dan dampaknya ke modul lain.
Jadi, PR bukan cuma tampilan diff. PR adalah halaman kerja kolaboratif tempat:
- Setiap perubahan bisa ditinjau baris per baris
- Komentar, diskusi, dan saran tercatat secara permanen
- Automated checks (unit test, linter, security scan) berjalan otomatis
- Alasan kenapa kode diterima atau ditolak terdokumentasi rapi
- Persetujuan dari reviewer yang relevan tercatat secara formal
Makanya, di banyak tim modern, kualitas kolaborasi engineering sangat ditentukan oleh kualitas proses PR mereka.
PR vs. Commit Langsung ke Main
| Aspek | Commit Langsung ke Main | Pull Request |
|---|---|---|
| Code review | Tidak ada | Terstruktur sebelum merge |
| Deteksi bug | Setelah kode masuk | Sebelum kode masuk |
| Berbagi pengetahuan | Minimal | Ada dalam proses review |
| Kompleksitas rollback | Lebih rumit | Lebih mudah (branch terisolasi) |
| Jejak audit | Hanya git log | Diskusi lengkap + riwayat approval |
Siklus Hidup Pull Request
Memahami siklus hidup PR secara menyeluruh membantu kamu melihat bagaimana setiap langkah saling terhubung.
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Branch │ │ Buka PR │ │ CI Checks │
│ Dibuat │────▶│ (Deskripsi, │────▶│ Berjalan │
│ │ │ assign) │ │ │
└─────────────┘ └──────────────┘ └──────┬──────┘
│
┌──────────────┐ ▼
│ Merge / │ ┌─────────────────┐
│ Ditutup │◀────│ Review & │
│ │ │ Iterasi │
└─────────────┘ └─────────────────┘
- Buat feature branch — isolasi perubahanmu dari branch utama
- Commit dan push — bangun fiturmu dengan commit yang fokus
- Buka pull request — berikan konteks, referensikan issue, assign reviewer
- CI/CD berjalan — unit test, lint, coverage, security check dijalankan otomatis
- Review & iterasi — reviewer memberi komentar, author menangani feedback
- Approval — reviewer yang diperlukan menyetujui perubahan
- Merge — kode digabungkan ke branch target
- Bersihkan branch — feature branch dihapus agar repository tetap rapi
Cara Membuat Pull Request
1. Mulai dengan Branch yang Dinamai dengan Baik
Konvensi penamaan branch memudahkan semua orang langsung mengerti isi PR:
# Branch fitur baru
git checkout -b feature/add-user-authentication
# Branch perbaikan bug
git checkout -b fix/resolve-login-redirect
# Branch refactoring
git checkout -b refactor/extract-payment-service
# Branch hotfix
git checkout -b hotfix/patch-xss-vulnerability
Penamaan yang konsisten juga memungkinkan pembuatan label PR otomatis dan aturan routing.
2. Buat Commit yang Fokus dan Atomic
Setiap commit idealnya merepresentasikan satu perubahan logis. Ini membuat riwayat review lebih mudah dipahami dan menyederhanakan rollback jika diperlukan:
# Buruk: semua perubahan dalam satu commit
git commit -m "perubahan"
# Baik: commit fokus dengan konteks yang jelas
git commit -m "feat(auth): tambah middleware validasi JWT"
git commit -m "test(auth): tambah unit test untuk validasi JWT"
git commit -m "docs(auth): perbarui dokumentasi API untuk protected routes"
Ikuti format Conventional Commits (feat, fix, docs, refactor, test, chore) untuk struktur yang konsisten dan mendukung pembuatan changelog otomatis.
3. Push Branch ke Remote
git push origin feature/add-user-authentication
Untuk push setelah force-rebase atau amend:
git push --force-with-lease origin feature/add-user-authentication
Gunakan --force-with-lease daripada --force — perintah ini akan menolak overwrite jika ada orang lain yang sudah push ke branch tersebut sejak fetch terakhirmu.
4. Buka Pull Request
Di GitHub, pergi ke halaman repository dan klik “Compare & pull request”, atau akses langsung: https://github.com/owner/repo/compare/main...feature/add-user-authentication.
Isi field berikut:
- Title: Ringkasan singkat dan imperatif tentang perubahan
- Description: Penjelasan detail (lebih lanjut di bagian berikutnya)
- Reviewers: Assign orang yang perlu memberi approval
- Labels: Kategorikan PR (
enhancement,bug,breaking-change) - Milestone / Project: Hubungkan ke sprint atau project board jika ada
- Linked Issues: Gunakan kata kunci seperti
Closes #42untuk menutup issue secara otomatis saat merge
Menulis Deskripsi PR yang Efektif
Deskripsi PR yang bagus bikin reviewer cepat paham konteks, jadi review lebih cepat selesai. Prinsip sederhananya: jangan bikin reviewer nebak-nebak.
Kerangka APA-MENGAPA-BAGAIMANA
## Apa yang dilakukan PR ini?
Menambahkan middleware autentikasi berbasis JWT untuk melindungi API endpoint.
Sebelumnya, semua route API bisa diakses secara publik tanpa autentikasi.
## Mengapa perubahan ini diperlukan?
Bagian dari inisiatif security hardening (lihat tiket #AUTH-102).
Akses anonim ke endpoint data pengguna diidentifikasi sebagai kerentanan
kritis dalam audit keamanan terakhir.
## Bagaimana implementasinya?
- Menambahkan middleware `validateJWT` menggunakan library `jsonwebtoken`
- Middleware diterapkan pada semua route `/api/v1/users/*`
- Memperluas model User dengan timestamp `lastLoginAt`
- Token expiry diset 15 menit dengan dukungan refresh token
## Testing
- [ ] Unit test berhasil (`npm test`)
- [ ] Integration test diperbarui
- [ ] Diuji manual dengan Postman (koleksi diekspor di `/docs`)
## Catatan untuk reviewer
Logic refresh token di `src/auth/refresh.ts` adalah bagian yang paling rumit —
mohon perhatian ekstra pada penanganan race condition di baris 84.
Dengan format seperti ini, reviewer bisa skim cepat dan langsung fokus ke bagian paling krusial.
Menggunakan PR Template
Daripada mengandalkan setiap developer untuk ingat menulis deskripsi yang baik, enkode ekspektasi timmu ke dalam sebuah PR template. GitHub, GitLab, dan Bitbucket semuanya mendukung fitur ini.
Buat file .github/PULL_REQUEST_TEMPLATE.md di repository kamu:
## Ringkasan
<!-- Masalah apa yang dipecahkan PR ini? Sertakan link ke issue terkait. -->
## Perubahan
<!-- Daftar perubahan utama dalam PR ini -->
-
-
## Jenis perubahan
- [ ] Bug fix (non-breaking change)
- [ ] Fitur baru (non-breaking change)
- [ ] Breaking change (mengubah fungsionalitas yang sudah ada)
- [ ] Update dokumentasi
## Testing yang dilakukan
- [ ] Unit test ditambahkan/diperbarui
- [ ] Integration test ditambahkan/diperbarui
- [ ] Testing manual selesai
## Checklist
- [ ] Kode mengikuti panduan gaya project
- [ ] Self-review sudah dilakukan
- [ ] Tidak ada debug/console log yang tertinggal
- [ ] Dokumentasi diperbarui jika diperlukan
- [ ] Tidak ada kerentanan keamanan baru
Untuk mendukung multi-template (misalnya template berbeda untuk fitur vs. bug fix), buat direktori:
.github/
PULL_REQUEST_TEMPLATE/
feature.md
bug_fix.md
hotfix.md
Best Practice Code Review
Code review itu skill kolaborasi, bukan sekadar cari salah. Tujuannya: bikin kualitas kode naik tanpa bikin komunikasi tim jadi tegang.
Untuk Reviewer
Baca deskripsi terlebih dahulu. Sebelum membaca satu baris kode, pahami apa dan mengapa. Konteks secara dramatis mengubah cara kamu menginterpretasikan kode.
Gunakan kategori dalam komentar. Tidak setiap komentar memerlukan tindakan. Nyatakan maksudmu:
// nit: preferensi gaya kecil, boleh diabaikan
// suggestion: mungkin lebih bersih, tapi tidak blocking
// question: aku tidak paham ini — bisa jelaskan?
// blocking: ini harus diselesaikan sebelum merge
// praise: pendekatan yang bagus!
Fokus pada hal yang tepat. Prioritaskan:
- Kebenaran logika bisnis
- Kerentanan keamanan
- Implikasi performa
- Maintainability dan keterbacaan
- Coverage test
Soal style sebaiknya diserahkan ke linter/formatter. Kalau tim masih debat indentasi di PR, biasanya problemnya ada di tooling, bukan di orangnya.
Sarankan, jangan dikte. Lebih baik:
“Pernah coba pakai
Array.prototype.reducedi sini? Mungkin lebih readable karena…”
Daripada:
“Kamu harus pakai reduce di sini.”
Batasi waktu reviewmu. Kalau PR terlalu besar untuk ditelaah sekali duduk, minta author memecahnya jadi beberapa PR kecil.
Untuk Author
Review PRmu sendiri dulu. Sebelum meminta review, lihat diff-nya sendiri. Kamu akan menemukan masalah yang jelas dan menghemat waktu reviewer.
Balas setiap komentar. Meski kamu tidak melakukan perubahan, akui komentar tersebut dengan penjelasan singkat. Ini menutup feedback loop dan membangun kepercayaan.
Jangan baper dengan komentar. Review itu soal kualitas kode, bukan serangan personal.
Resolve komentar dengan penjelasan. Saat kamu menangani komentar, tambahkan balasan yang menjelaskan apa yang kamu ubah atau mengapa kamu tidak mengubahnya. Ini menciptakan jejak audit yang berguna.
Menjaga PR Tetap Bersih
Sinkronisasi dengan Base Branch
Seiring base branch (misalnya main) terus berkembang, feature branch-mu bisa ketinggalan dan menyebabkan konflik. Tetap update:
# Opsi 1: Merge base branch ke feature branch
git checkout feature/add-user-authentication
git fetch origin
git merge origin/main
# Opsi 2: Rebase ke atas base branch terbaru (histori lebih bersih)
git rebase origin/main
Rebase memang bikin histori lebih rapi, tapi menulis ulang commit. Pastikan timmu sepakat kapan pakai merge biasa dan kapan pakai rebase.
Squash Commit Sebelum Merge
Serangkaian panjang commit “fix tests”, “hapus debug”, “address review comments” mengotori histori main branch. Squash mereka:
# Interactive rebase untuk squash N commit terakhir
git rebase -i HEAD~5
Di editor, tandai commit perantara sebagai squash atau fixup. Sebagai alternatif, tombol “Squash and merge” di GitHub melakukan ini secara otomatis saat merge.
Kelola Branch yang Sudah Tidak Aktif
Konfigurasi repository untuk otomatis menghapus branch setelah merge. Di GitHub: Settings → General → Automatically delete head branches.
Otomasi PR dengan CI/CD
Review manual tetap penting, tapi banyak pengecekan bisa dan sebaiknya diotomasi supaya reviewer fokus ke logic, bukan hal-hal mekanis.
Contoh GitHub Actions
# .github/workflows/pr-checks.yml
name: PR Checks
on:
pull_request:
branches: [main, develop]
jobs:
quality:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name: Install dependencies
run: npm ci
- name: Jalankan linter
run: npm run lint
- name: Cek tipe data
run: npm run type-check
- name: Jalankan unit test
run: npm test -- --coverage
- name: Upload laporan coverage
uses: codecov/codecov-action@v4
- name: Audit keamanan
run: npm audit --audit-level=moderate
Status Checks sebagai Merge Gate
Konfigurasi required status checks agar PR tidak bisa di-merge jika CI gagal. Di GitHub: Settings → Branches → Branch protection rules → Require status checks to pass before merging.
Pengecekan yang umum dijadikan gate:
- ✅ Unit test lulus
- ✅ Threshold code coverage terpenuhi (misalnya ≥ 80%)
- ✅ Tidak ada error linting
- ✅ Tidak ada kerentanan keamanan high/critical
- ✅ Build berhasil
Komentar PR Otomatis
Tool seperti DangerJS bisa memposting ringkasan otomatis langsung di PR:
// dangerfile.js
import { danger, warn, fail } from 'danger';
const bigPRThreshold = 500;
if (danger.github.pr.additions + danger.github.pr.deletions > bigPRThreshold) {
warn(`PR ini cukup besar (${danger.github.pr.additions + danger.github.pr.deletions} baris berubah). Pertimbangkan untuk memecahnya menjadi PR yang lebih kecil.`);
}
if (!danger.github.pr.body || danger.github.pr.body.length < 50) {
fail('Deskripsi PR terlalu singkat. Tolong jelaskan apa yang dilakukan PR ini.');
}
Anti-Pattern PR yang Harus Dihindari
1. PR Monolith
PR dengan ribuan baris perubahan di banyak file. Secara realistis, reviewer bakal kesulitan ngasih feedback berkualitas, akhirnya bug gampang lolos.
Solusi: Terapkan single-responsibility principle pada PR. Satu PR = satu perubahan logis. Jika fitur terlalu besar, pecah menjadi serangkaian PR kecil yang saling bergantung.
2. PR Misterius
PR dengan judul “update” dan tanpa deskripsi. Reviewer tidak punya konteks dan harus menghabiskan waktu mereka sendiri untuk menebak apa yang dilakukan kode tersebut.
Solusi: Gunakan PR template. Jadikan deskripsi yang baik sebagai jalur yang paling mudah.
3. PR Kadaluarsa
PR yang terbuka berminggu-minggu tanpa update dari author maupun reviewer. Semakin lama dibiarkan, konflik merge makin banyak dan konteks makin basi.
Solusi: Tetapkan batas usia PR (misalnya 7 hari). Gunakan otomasi (misalnya stale bot) untuk menandai dan menutup PR yang tidak aktif.
4. Review Tanpa Menjalankan Kode
Meng-approve kode yang belum pernah kamu jalankan secara lokal (atau diverifikasi melalui CI). Kamu mungkin melewatkan runtime error yang tidak tertangkap oleh analisis statis.
Solusi: Untuk perubahan sensitif, selalu jalankan kode secara lokal. Pastikan CI mencakup happy path dan edge case.
5. Approval Anchoring
Reviewer pertama memberikan review positif, dan reviewer berikutnya mengikuti tanpa analisis independen. Ini adalah bias kognitif yang menurunkan kualitas review dari waktu ke waktu.
Solusi: Minta review independen. Sebisa mungkin, minta reviewer mengirimkan feedback sebelum membaca komentar orang lain.
Strategi PR: Draft, Stacked, dan Pair PR
Draft Pull Request
Tidak semua PR siap di-review begitu dibuka. Draft PR (GitHub) / Draft MR (GitLab) memberi sinyal bahwa pekerjaan masih berlangsung:
# Menggunakan GitHub CLI
gh pr create --draft --title "WIP: tambah autentikasi pengguna"
Gunakan draft PR untuk:
- Berbagi pekerjaan awal untuk mendapat feedback high-level
- Menjalankan CI tanpa meminta review
- Memesan judul/deskripsi PR selagi pekerjaan berlanjut
Stacked Pull Request
Ketika sebuah fitur mencakup beberapa lapisan logis (misalnya endpoint API baru membutuhkan perubahan skema database → service layer baru → controller baru), stacking sangat membantu:
PR-1: Tambah migrasi tabel users
└── PR-2: Tambah UserService
└── PR-3: Tambah UserController (routes)
└── PR-4: Tambah integrasi frontend
Setiap PR kecil, bisa di-review secara independen, dan membangun di atas yang sebelumnya. Tool seperti Graphite dan ghstack mengotomasi manajemen stacked PR di GitHub.
Pair PR
Untuk perubahan yang sangat kompleks atau berisiko tinggi, libatkan engineer kedua sebagai co-author:
git commit --author="Co-Author Name <[email protected]>" -m "feat: implementasi integrasi payment gateway
Co-authored-by: Jane Doe <[email protected]>"
GitHub menampilkan co-author di PR, memberikan kepemilikan dan akuntabilitas bersama.
Kesimpulan
Pull request adalah salah satu kebiasaan kecil yang dampaknya besar banget ke kualitas produk. PR yang sehat bikin bug ketahan sebelum production, bikin knowledge sharing jalan, dan menjaga komunikasi tim tetap rapi.
Poin kunci yang perlu kamu bawa pulang:
- Buat PR kecil dan fokus — satu perubahan logis per PR
- Tulis deskripsi yang jelas — berikan konteks yang dibutuhkan reviewer
- Gunakan template — enkode ekspektasi timmu
- Otomasi semua yang bisa diotomasi — biarkan CI/CD menangani style, test, dan keamanan
- Review dengan seksama — prioritaskan kebenaran logika dan keamanan di atas style
- Iterasi dengan cepat — tangani feedback segera, tutup loop untuk setiap komentar
Tim yang kuat biasanya memperlakukan PR bukan sebagai birokrasi, tapi sebagai ruang diskusi teknis yang produktif. Kalau workflow PR timmu rapi, efeknya terasa ke kecepatan delivery, stabilitas fitur, dan kualitas codebase dalam jangka panjang.
FAQ Singkat seputar Pull Request
Berapa ukuran ideal satu PR?
Tidak ada angka baku, tapi secara praktik usahakan tetap kecil dan fokus pada satu tujuan. Semakin kecil PR, semakin cepat direview dan semakin kecil risiko bug tersembunyi.
Kapan pakai draft PR?
Pakai draft PR saat kamu butuh feedback awal tapi implementasi belum final. Misalnya arsitektur sudah jadi, tapi test atau dokumentasi masih dikerjakan.
Lebih baik merge commit, squash, atau rebase?
Tergantung aturan tim. Kalau ingin histori ringkas, squash merge biasanya paling aman untuk banyak kasus. Kalau tim butuh histori commit detail, merge commit bisa dipertahankan.
Apa PR wajib untuk project kecil?
Kalau solo project, opsional. Tapi begitu mulai kolaborasi dengan orang lain, PR hampir selalu worth it karena mengurangi miskomunikasi dan bug saat integrasi.