Siklus review menuntut dua kursi: kontributor yang menyiapkan perubahan, dan reviewer yang menimbangnya. Pada proyek ini kita menduduki keduanya bergantian — Siti Rahma sebagai kontributor luar, Budi Santoso sebagai pemilik proyek yang meninjau. Panggungnya meniru model fork dari chapter Fork dan Upstream : satu repository asal, satu salinan pribadi, dan satu clone di tiap meja. Bagian ini mendirikan seluruh panggung dari nol, lalu membuka branch review/pencarian tempat fitur pencarian catatan dikerjakan dalam tiga commit.

Dua Peran dan Empat Repositori #

Pembagian kerjanya dipetakan pada tabel berikut — simpan baik-baik karena empat bagian proyek ini terus berpindah antara dua barisnya:

PeranMeja kerjaRemote yang terdaftarTugas
Siti Rahma — kontributorclone siti/origin → fork, upstream → repository asalmengerjakan fitur, mengirim usulan, menindaklanjuti feedback
Budi Santoso — reviewerclone budi/origin → repository asal, fork → fork Sitimeninjau diff, mencatat temuan, memutuskan dan menggabungkan

Dua repositori bare berperan sebagai sisi server: upstream-catatan.git adalah repository asal milik Budi, sedangkan fork-siti.git salinan pribadi Siti. Aliran kerjanya tergambar pada diagram berikut:

Diagram tersebut membaca begini: pekerjaan Siti didorong ke fork-nya sendiri, diajukan ke upstream sebagai pull request, lalu Budi menarik branch kandidat dari fork untuk ditinjau dan akhirnya digabungkan ke upstream. Panah putus-putus adalah jalur pembaruan — Siti menarik perubahan upstream tanpa pernah mendorong ke sana. Inilah model yang dipakai proyek open source besar; Git murni sudah cukup untuk menjalankannya.

Menyiapkan Repository Upstream #

Budi memulai sebagai pemilik proyek. Dari folder sandbox yang kosong, buat repository kerja sekaligus pasang identitas lokal:

bash
mkdir budi && cd budi
git init -b main
git config user.name "Budi Santoso"
git config user.email "[email protected]"

Output yang Dihasilkan (perintah git init):

text
Initialized empty Git repository in /home/z/my-project/tutorial-extracted/work/sandbox/proyek-git/proyek-04/budi/.git/

Jalur pada keluaran menyesuaikan lokasi direktori di mesin kita. Selanjutnya tiga berkas rintisan: README.md yang menjelaskan proyek, docs/review-checklist.md berisi kriteria review yang ditetapkan pemilik proyek, dan kerangka src/feature.txt:

bash
cat > README.md <<'EOF'
# Proyek Catatan

Kumpulan catatan pribadi dengan fitur pencarian sederhana — proyek
latihan untuk Course Git: Proyek 04, simulasi siklus code review.

## Struktur

- `src/feature.txt` — implementasi fitur pencarian
- `docs/review-checklist.md` — kriteria review kontribusi

## Berkontribusi

Kirim usulan lewat fork dan pull request; setiap usulan ditinjau
dengan checklist pada `docs/review-checklist.md`.
EOF
mkdir -p docs src
cat > docs/review-checklist.md <<'EOF'
# Checklist Review

Lima pertanyaan yang diperiksa reviewer pada setiap pull request
proyek ini. Tandai jawaban tiap baris dan catat buktinya pada
komentar review.

| Aspek   | Pertanyaan kunci                          | Bukti yang dicari                       |
|---------|-------------------------------------------|-----------------------------------------|
| Benar    | Apakah hasil sesuai janji deskripsi PR?    | logika, kasus kosong, batas             |
| Terbaca  | Apakah niat tiap bagian langsung terbaca?  | penamaan, struktur seksi                |
| Aman     | Apakah ada input atau data yang rawan?     | input tidak tepercaya, data pribadi     |
| Teruji   | Apakah perilaku baru terbukti dijalankan?  | hasil uji untuk kata kunci berbeda      |
| Konsisten| Apakah pola berkas sekitarnya diikuti?     | konvensi nama dan format                |

Cara pakai: baca deskripsi PR, baca diff dari base ke compare,
lalu jawab kelima baris di atas sebelum menulis keputusan review.
EOF
printf 'Fitur Pencarian Catatan\n========================\n\n## Data Catatan\n\n- catatan 1: belajar Git setiap pagi\n- catatan 2: resep rendang keluarga\n- catatan 3: daftar belanja mingguan\n' > src/feature.txt

Checklist itu akan kita baca utuh dan pakai pada Bagian 3 — untuk sekarang cukup tahu bahwa pemilik proyek menetapkan kriteria reviewnya secara tertulis sejak rintisan. Periksa keadaan repository:

bash
git status

Output yang Dihasilkan:

text
On branch main

No commits yet

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

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

Ketiga berkas masih untracked. Angkat semuanya lalu commit rintisan:

bash
git add .
git commit -m "Rintis proyek catatan"

Output yang Dihasilkan:

text
[main (root-commit) e5c2aad] Rintis proyek catatan
 3 files changed, 38 insertions(+)
 create mode 100644 README.md
 create mode 100644 docs/review-checklist.md
 create mode 100644 src/feature.txt

Tanda (root-commit) menandai commit pertama tanpa parent; hash e5c2aad akan berbeda di mesin kita. Repositori asal kini berdiri — publikasikan sebagai repositori bare, lalu dorong main ke sana:

bash
git init --bare ../upstream-catatan.git
git remote add origin ../upstream-catatan.git
git push -u origin main

Output yang Dihasilkan (perintah git init --bare):

text
Initialized empty Git repository in /home/z/my-project/tutorial-extracted/work/sandbox/proyek-git/proyek-04/upstream-catatan.git/

Output yang Dihasilkan (perintah git push):

text
To ../upstream-catatan.git
 * [new branch]      main -> main
branch 'main' set up to track 'origin/main'.

Repositori bare berperan sebagai server: clone budi menjadi meja kerja Budi sekaligus tempatnya meninjau nanti — keduanya memang satu direktori yang sama.

Membuat Fork dan Clone Siti #

Di platform nyata, Siti menekan tombol Fork di halaman proyek Budi dan server menyalin seluruh riwayat ke ruang akunnya — persis alur dari Fork dan Pull Request . Sandbox meniru penyalinan sisi server itu dengan git clone --bare:

bash
cd ..
git clone --bare upstream-catatan.git fork-siti.git

Output yang Dihasilkan:

text
Cloning into bare repository 'fork-siti.git'...
done.

Fork Siti lahir sebagai bare kedua — salinan penuh yang siap menerima dorongan dari meja Siti. Sekarang meja Siti sendiri:

bash
git clone fork-siti.git siti
cd siti
git remote set-url origin ../fork-siti.git
git config user.name "Siti Rahma"
git config user.email "[email protected]"

Output yang Dihasilkan (perintah git clone):

text
Cloning into 'siti'...
done.

Perintah git remote set-url memerlukan satu penjelasan. Clone lokal menyimpan alamat sumbernya sebagai jalur absolut; kita rapikan menjadi jalur relatif ../fork-siti.git agar keluaran push dan fetch di seluruh proyek ini pendek dan mudah dibaca — bentuk buku alamat yang sama dipakai materi kolaborasi course ini sejak Menambahkan Remote . Identitas Siti dipasang lokal di clone ini, sehingga commit yang lahir di meja Siti tercatat atas namanya.

Menambahkan Remote upstream #

Clone Siti otomatis menamai sumbernya origin — yang menunjuk fork miliknya sendiri. Jendela ke repository asal belum ada; daftarkan dengan nama konvensi upstream:

bash
git remote add upstream ../upstream-catatan.git
git remote -v

Output yang Dihasilkan (perintah git remote -v):

text
origin	../fork-siti.git (fetch)
origin	../fork-siti.git (push)
upstream	../upstream-catatan.git (fetch)
upstream	../upstream-catatan.git (push)

Empat baris alamat, dua arah untuk tiap remote. Arah kerjanya berbeda: origin dipakai Siti mendorong pekerjaannya sendiri, upstream dipakai menarik pembaruan dari proyek asal — pembagian yang dibedah tuntas di Fork dan Upstream .

Membuka Branch review/pencarian #

Fitur pencarian tidak disentuhkan langsung ke main milik fork. Buat branch khusus:

bash
git switch -c review/pencarian

Output yang Dihasilkan:

text
Switched to a new branch 'review/pencarian'

Prefiks review/ menandai tujuan branch: kandidat yang akan dikirim untuk ditinjau, bukan pekerjaan pribadi. Konvensi penamaan branch dibahas lebih luas di Strategi Branching .

Tiga Commit Implementasi Awal #

Commit pertama memasang kerangka: dua seksi baru di akhir berkas, masing-masing berisi placeholder:

bash
printf '\n## Fungsi Pencarian\n\n(fungsi cari akan ditulis pada langkah berikutnya)\n\n## Hasil Uji\n\n(uji akan dicatat setelah fungsi selesai)\n' >> src/feature.txt
cat src/feature.txt

Output yang Dihasilkan (perintah cat):

text
Fitur Pencarian Catatan
========================

## Data Catatan

- catatan 1: belajar Git setiap pagi
- catatan 2: resep rendang keluarga
- catatan 3: daftar belanja mingguan

## Fungsi Pencarian

(fungsi cari akan ditulis pada langkah berikutnya)

## Hasil Uji

(uji akan dicatat setelah fungsi selesai)
bash
git add src/feature.txt
git commit -m "feat: tulis kerangka fitur pencarian"

Output yang Dihasilkan:

text
[review/pencarian 84f5f89] feat: tulis kerangka fitur pencarian
 1 file changed, 8 insertions(+)

Prefiks feat: menandai commit yang menambah kemampuan baru — gaya dari Conventional Commits . Commit kedua mengganti placeholder fungsi dengan implementasinya:

bash
printf 'Fitur Pencarian Catatan\n========================\n\n## Data Catatan\n\n- catatan 1: belajar Git setiap pagi\n- catatan 2: resep rendang keluarga\n- catatan 3: daftar belanja mingguan\n\n## Fungsi Pencarian\n\ncari(kata_kunci):\n    cocok = catatan yang memuat "belanja"\n    kembalikan cocok\n\n## Hasil Uji\n\n(uji akan dicatat setelah fungsi selesai)\n' > src/feature.txt
cat src/feature.txt

Output yang Dihasilkan (perintah cat):

text
Fitur Pencarian Catatan
========================

## Data Catatan

- catatan 1: belajar Git setiap pagi
- catatan 2: resep rendang keluarga
- catatan 3: daftar belanja mingguan

## Fungsi Pencarian

cari(kata_kunci):
    cocok = catatan yang memuat "belanja"
    kembalikan cocok

## Hasil Uji

(uji akan dicatat setelah fungsi selesai)

Fungsi cari menerima kata_kunci lalu mengembalikan catatan yang cocok — begitulah cara bacanya saat ini. Simpan sebagai satu commit:

bash
git add src/feature.txt
git commit -m "feat: terapkan fungsi pencarian"

Output yang Dihasilkan:

text
[review/pencarian c631b60] feat: terapkan fungsi pencarian
 1 file changed, 3 insertions(+), 1 deletion(-)

Commit ketiga mengisi seksi hasil uji. Siti menguji dengan kata kunci belanja — hasilnya cocok dengan catatan 3, lalu hasil uji itu dicatat:

bash
printf 'Fitur Pencarian Catatan\n========================\n\n## Data Catatan\n\n- catatan 1: belajar Git setiap pagi\n- catatan 2: resep rendang keluarga\n- catatan 3: daftar belanja mingguan\n\n## Fungsi Pencarian\n\ncari(kata_kunci):\n    cocok = catatan yang memuat "belanja"\n    kembalikan cocok\n\n## Hasil Uji\n\ncari("belanja") → catatan 3: daftar belanja mingguan\n' > src/feature.txt
git diff

Output yang Dihasilkan (perintah git diff):

text
diff --git a/src/feature.txt b/src/feature.txt
index a5a17e2..3c16aef 100644
--- a/src/feature.txt
+++ b/src/feature.txt
@@ -15,4 +15,4 @@ cari(kata_kunci):
 
 ## Hasil Uji
 
-(uji akan dicatat setelah fungsi selesai)
+cari("belanja") → catatan 3: daftar belanja mingguan

Perubahan ketiga ini benar-benar kecil: satu baris placeholder ditukar satu baris hasil uji. Pesan commitnya sementara ditulis apa adanya:

bash
git add src/feature.txt
git commit -m "wip: tambah hasil uji"

Output yang Dihasilkan:

text
[review/pencarian c12f4c4] wip: tambah hasil uji
 1 file changed, 1 insertion(+), 1 deletion(-)

Keadaan akhir bagian ini — diukur dengan rentang main..review/pencarian yang hanya menghitung commit milik branch:

bash
git log --oneline main..review/pencarian
git status

Output yang Dihasilkan (perintah git log):

text
c12f4c4 wip: tambah hasil uji
c631b60 feat: terapkan fungsi pencarian
84f5f89 feat: tulis kerangka fitur pencarian

Output yang Dihasilkan (perintah git status):

text
On branch review/pencarian
nothing to commit, working tree clean

Tiga commit tertib di branch: kerangka, fungsi, hasil uji — dan main belum tersentuh sedikit pun. Namun bentuk ini belum siap dikirim: satu commit berlabel wip dan satu langkah uji yang sejatinya bagian dari implementasi. Bagian berikutnya merapikan keduanya menjadi dua commit bersih, lalu membungkusnya sebagai pull request: Bagian 2: Menyiapkan Pull Request .