Autentikasi tuntas: kunci SSH dan token sudah mampu membawa kita masuk ke platform. Motivasi berikutnya biasanya bukan sekadar masuk, melainkan ikut serta — memperbaiki bug di pustaka favorit, menambah dokumentasi, atau menyumbang fitur ke proyek open source. Hambatannya struktural: kita tidak punya akses tulis ke repository asal, dan memintanya ke tiap kontributor mustahil dikelola. Platform menyelesaikannya dengan kombinasi fork dan pull request: salinan pribadi tempat kita bebas mendorong, dan usulan resmi tempat pemilik menimbangnya. Chapter ini menjalankan alur lengkapnya — dari tombol Fork sampai fork kembali sinkron — dengan demo Git nyata bertiga repository.

Alur Kontributor Open Source #

Model fork sudah kita bangun dengan Git murni di Fork dan Upstream ; chapter ini menuntaskan sisi platformnya — bagaimana usulan diajukan dan bagaimana keputusan maintainer dieksekusi. Urutannya dari atas ke bawah:

LangkahAlatTempat terjadinya
1. Fork repository asaltombol Forkweb platform
2. Clone fork milik sendirigit cloneterminal
3. Buat branch fitur dan commitgit switch -c, git committerminal
4. Dorong branch ke forkgit push originterminal
5. Ajukan pull requesttombol pull requestweb platform
6. Maintainer me-mergetombol mergeweb platform
7. Sinkronkan fork dengan upstreamgit fetch, git merge, git pushterminal

Diagram tersebut memetakan pembagian kerjanya: langkah bernomor ganjil hidup di web platform, langkah bernomor genap adalah perintah Git di terminal. Pull request sendiri bukan perintah Git — statusnya sudah dibedah di Pull Request , dan perilaku fork di sisi GitHub terdokumentasi di dokumentasi GitHub tentang fork .

Panggung Sandbox: Upstream, Fork, dan Clone #

Demo memakai tiga repository yang memainkan tiga peran: upstream-toko.git (bare — meniru sisi server platform) milik maintainer Siti sudah berisi dua commit kerangka. Tombol Fork di web diterjemahkan menjadi penyalinan sisi server — platform menyalin seluruh riwayat ke akun kontributor:

bash
git clone --bare upstream-toko.git fork-budi.git

Output yang Dihasilkan:

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

Salinan bernama fork-budi.git kini berdiri sebagai milik Budi — isi riwayatnya identik dengan upstream, tetapi kepemilikannya terpisah. Langkah pertama Budi adalah meng-clone fork miliknya sendiri, lalu mendaftarkan jendela ke repository asal:

bash
git clone fork-budi.git toko-budi
cd toko-budi
git remote add upstream ../upstream-toko.git
git remote -v

Output yang Dihasilkan (perintah terakhir):

text
origin  /home/z/my-project/tutorial-extracted/work/sandbox/git-hosting-platforms/part-b/latihan-fork/fork-budi.git (fetch)
origin  /home/z/my-project/tutorial-extracted/work/sandbox/git-hosting-platforms/part-b/latihan-fork/fork-budi.git (push)
upstream        ../upstream-toko.git (fetch)
upstream        ../upstream-toko.git (push)

Jalur pada keluaran menyesuaikan lokasi direktori. Buku alamat kini berisi dua entri: origin menunjuk fork milik Budi, upstream menunjuk repository asal Siti — struktur dua remote yang dibedah lengkap di Fork dan Upstream . Penarikannya membuktikan keduanya hidup:

bash
git fetch upstream

Output yang Dihasilkan:

text
From ../upstream-toko
 * [new branch]      main       -> upstream/main

Kontributor: Branch, Commit, Push #

Pekerjaan kontribusi tidak boleh menyentuh main — pekerjaan hidup di branch fitur sendiri, supaya usulan kita berangkat dari dasar yang bersih dan mudah ditimbang (kebiasaan yang dilatih di Pull Request ):

bash
git switch -c fitur/rating

Output yang Dihasilkan:

text
Switched to a new branch 'fitur/rating'
bash
printf 'kopi 4.5\ngula 4.0\n' > rating.md
git add rating.md
git commit -m "Tambah rating produk"

Output yang Dihasilkan (perintah terakhir):

text
[fitur/rating 7b6861c] Tambah rating produk
 1 file changed, 2 insertions(+)
 create mode 100644 rating.md

Pengirimannya tetap satu dorong — ke origin, fork milik sendiri, tempat kita berkuasa penuh:

bash
git push -u origin fitur/rating

Output yang Dihasilkan:

text
To /home/z/my-project/tutorial-extracted/work/sandbox/git-hosting-platforms/part-b/latihan-fork/fork-budi.git
 * [new branch]      fitur/rating -> fitur/rating
branch 'fitur/rating' set up to track 'origin/fitur/rating'.

Branch fitur/rating lahir di fork, terikat pelacakan ke origin/fitur/rating, dan repository asal tidak tersentuh sedikit pun. Hash di mesin pembaca berbeda; pola [new branch] yang penting.

Pull Request di Web #

Dari titik ini panggungnya berpindah ke peramban. Platform seperti GitHub mendeteksi branch yang baru terdorong dan menampilkan tombol pembandingan di halaman fork — kurang-lebih “Compare & pull request”. Formulirnya meminta base dan compare: base adalah main milik upstream (lintas repository — bedanya dari pull request antar branch satu repo), compare adalah fitur/rating milik fork. Platform tidak menyalin kode apa pun: halaman pull request membaca dua branch yang sudah ada di server, menghitung selisihnya, dan membuka ruang diskusi — lengkap dengan status “able to merge” bila kedua riwayat masih sejalan.

Judul dan deskripsinya diisi seperti commit yang baik: apa yang berubah, mengapa, dan bagaimana mengujinya. Nomor #7 diberikan platform dari urutannya sendiri — di GitHub, issues dan pull request berbagi satu urutan penomoran, kebiasaan yang kita manfaatkan di Issues dan Discussions . GitLab menyebutnya merge request, Bitbucket pull request; mekanismenya satu konsep.

Maintainer: Merge di Upstream #

Sisi kanan meja adalah Siti. Tombol Merge pull request yang ia tekan dijalankan platform di sisi server: branch dari fork digabungkan ke main upstream dan sebuah commit merge dilahirkan. Sandbox meniru persis urutan itu — pertama menarik branch dari fork Budi:

bash
cd ../proyek-siti
git fetch ../fork-budi.git fitur/rating

Output yang Dihasilkan:

text
From ../fork-budi
 * branch            fitur/rating -> FETCH_HEAD

Lalu menggabungkannya. Opsi --no-ff dipilih agar Git melahirkan commit merge tersendiri — bentuk yang sama dengan tombol merge platform — dan pesannya meniru format yang dibuat GitHub:

bash
git merge --no-ff FETCH_HEAD \
  -m "Merge pull request #7 from budi/fitur/rating" \
  -m "Tambah rating produk"

Output yang Dihasilkan:

text
Merge made by the 'ort' strategy.
 rating.md | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 rating.md
bash
git push origin main

Output yang Dihasilkan:

text
To ../upstream-toko.git
   5c9dd81..ab105a7  main -> main

Sesudah merge sungguhan, platform menutup pull request secara otomatis, menawarkan menghapus branch compare, dan menautkan commit merge kembali ke halaman diskusinya. Platform juga menyediakan pilihan strategi lain — squash dan rebase — dengan jejak riwayat berbeda; ketiganya sudah dibandingkan di Pull Request .

Sinkronisasi Fork Pasca-Merge #

Merge di upstream tidak menyentuh fork Budi sama sekali — fork tetap berhenti di 5c9dd81 sampai Budi sendiri yang menariknya. Sinkronisasi kembali ke meja Budi:

bash
cd ../toko-budi
git fetch upstream

Output yang Dihasilkan:

text
From ../upstream-toko
   5c9dd81..ab105a7  main       -> upstream/main
bash
git switch main

Output yang Dihasilkan:

text
Switched to branch 'main'
Your branch is up to date with 'origin/main'.
bash
git merge --ff-only upstream/main

Output yang Dihasilkan:

text
Updating 5c9dd81..ab105a7
Fast-forward
 rating.md | 2 ++
 1 file changed, 2 insertions(+)
 create mode 100644 rating.md
bash
git push origin main

Output yang Dihasilkan:

text
To /home/z/my-project/tutorial-extracted/work/sandbox/git-hosting-platforms/part-b/latihan-fork/fork-budi.git
   5c9dd81..ab105a7  main -> main

Rantai empat perintah itu terbaca alami dari atas ke bawah: tarik pembaruan ke upstream/main, berpindah ke main, majukan main lokal sampai sama dengan upstream, lalu teruskan hasilnya ke fork. Opsi --ff-only adalah penjaganya: main fork memang tidak boleh punya commit sendiri, jadi bila fast-forward ternyata tak mungkin, Git berhenti dan memberi tahu — bukan diam-diam melahirkan merge yang menandakan asumsi itu salah. Terakhir, branch fitur yang sudah selesai dibersihkan:

bash
git branch -d fitur/rating

Output yang Dihasilkan:

text
Deleted branch fitur/rating (was 7b6861c).

Salinannya di fork masih tersimpan sebagai origin/fitur/rating; bila ingin dibersihkan juga, git push origin --delete fitur/rating menghapusnya — mekanisme yang dibedah di Menghapus Remote Branch .

Keadaan Akhir: Empat Penunjuk Satu Titik #

Bukti terakhir bahwa seluruh lingkaran tertutup terbaca dari daftar branch:

bash
git branch -avv

Output yang Dihasilkan:

text
* main                        ab105a7 [origin/main] Merge pull request #7 from budi/fitur/rating
  remotes/origin/HEAD         -> origin/main
  remotes/origin/fitur/rating 7b6861c Tambah rating produk
  remotes/origin/main         ab105a7 Merge pull request #7 from budi/fitur/rating
  remotes/upstream/main       ab105a7 Merge pull request #7 from budi/fitur/rating
bash
git log --oneline --graph --all

Output yang Dihasilkan:

text
*   ab105a7 Merge pull request #7 from budi/fitur/rating
|\  
| * 7b6861c Tambah rating produk
|/  
* 5c9dd81 Tambah daftar produk
* b60bd3a Buat kerangka toko

Empat baris pertama daftar branch memuat empat penunjuk yang kini sejajar di ab105a7: main lokal, origin/main (fork), upstream/main (repository asal), dan salinan main di bare upstream. Graf menutup cerita dari sisi bentuknya: satu commit fitur bertemu main di commit merge bergaya platform — persis geometri yang dihasilkan tombol merge sungguhan. Hash di mesin pembaca berbeda; komposisinya tidak.

Alur kontribusi kode kini utuh dari ujung ke ujung. Tetapi proyek open source bergerak lebih dulu lewat percakapan: bug dilaporkan, usulan ditimbang, pertanyaan dijawab — semuanya sebelum satu baris pun ditulis. Wadah percakapan itu adalah issues dan discussions, pokok bahasan berikutnya.