Di akhir chapter git fetch , posisi Budi seperti orang yang sudah membaca surat kabar pagi: tahu persis Siti satu commit di depan, tetapi branch main miliknya masih tertinggal. Menggabungkannya secara manual berarti dua langkah — git fetch lalu git merge origin/main — dan alur dua langkah itu begitu umum sehingga Git menyatukannya menjadi satu perintah: git pull. Kenyataannya pull membawa tiga wajah berbeda tergantung keadaan branch lokal: fast-forward yang mulus, penggabungan dua riwayat yang menyimpang, atau penyusunan ulang dengan --rebase. Chapter ini menguji ketiganya pada kondisi nyata, termasuk penolakan tegas Git saat diminta menebak sendiri.

Pull adalah fetch yang langsung menggabungkan #

Secara perilaku, git pull menjalankan git fetch lalu git merge — mengambil perkembangan remote dan segera menggabungkannya ke branch aktif. Dunia latihan masih sama: proyek-utama.git di tengah, clone Budi dan clone Siti di sisi lain, keduanya berangkat dari commit Buat README toko. Siti lebih dulu menambahkan daftar produk dan mengirimkannya ke remote. Saat Budi hendak menariknya, mari kita perhatikan dulu statusnya:

bash
git status

Output yang Dihasilkan:

text
On branch main
Your branch is up to date with 'origin/main'.

nothing to commit, working tree clean

Laporan up to date ini menyesatkan kalau dibaca cepat — status hanya membandingkan main dengan salinan penunjuk origin/main sebagaimana terakhir diketahui, dan salinan itu memang belum diperbarui. Barulah pull bekerja:

bash
git pull

Output yang Dihasilkan:

text
From /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-pull/proyek-utama
   2bd3e21..0c691c3  main       -> origin/main
Updating 2bd3e21..0c691c3
Fast-forward
 README.md | 4 ++++
 1 file changed, 4 insertions(+)

Keluarannya gabungan dua babak: bagian From ... hingga main -> origin/main adalah babak fetch yang sudah kita kenal, lalu babak Updating 2bd3e21..0c691c3 dengan Fast-forward adalah git merge yang menggeser main lokal maju tanpa commit baru — bentuk perpindahan yang sudah dikenal di chapter Fast-Forward Merge . Riwayat Budi kini sejajar dengan Siti:

bash
git log --oneline

Output yang Dihasilkan:

text
0c691c3 Tambah daftar produk
2bd3e21 Buat README toko

Menyebut Remote dan Branch secara Eksplisit #

Bentuk lengkap perintahnya adalah git pull <remote> <branch>. Dalam clone kedua penulis kita bentuk ini jarang diperlukan karena upstream sudah terpasang, tetapi menyebutnya eksplisit membuat kita memahami apa yang sebenarnya terjadi — Siti menambahkan jam buka ke README.md dan mengirimkannya, lalu Budi menariknya tanpa bergantung pada pengaturan:

bash
git pull origin main

Output yang Dihasilkan:

text
From /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-pull/proyek-utama
 * branch            main       -> FETCH_HEAD
   0c691c3..e55f05d  main       -> origin/main
Updating 0c691c3..e55f05d
Fast-forward
 README.md | 3 +++
 1 file changed, 3 insertions(+)

Babak fetch kini memuat baris * branch main -> FETCH_HEAD karena yang ditarik adalah snapshot main yang ditampung ke penunjuk sementara — bentuk yang sudah dibedah pada chapter git fetch . Setelah itu alurnya sama: Fast-forward menggeser main lokal maju. Satu peringatan untuk bentuk eksplisit ini: yang digabungkan tetap cabang aktif kita, apa pun namanya — git pull origin main di branch lain tetap menggabungkan origin/main ke branch tersebut.

Saat Riwayat Menyimpang, Pull Menolak Menebak #

Selama branch lokal cukup diam di belakang remote, fast-forward selalu bisa terjadi. Persoalan lahir ketika kedua sisi sama-sama maju: Budi menambahkan berkas catatan.md (commit “Tambah catatan internal”), sementara Siti menambahkan kontak.md dan mengirimkannya ke remote. Kedua riwayat kini menyimpang dari titik yang sama, dan menggabungkannya bukan lagi sekadar menggeser penunjuk — ada keputusan yang harus diambil. Pada Git 2.47, git pull menolak memutuskan sendiri:

bash
git pull

Output yang Dihasilkan:

text
From /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-pull/proyek-utama
   e55f05d..c370d09  main       -> origin/main
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint:   git config pull.rebase false  # merge
hint:   git config pull.rebase true   # rebase
hint:   git config pull.ff only       # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
fatal: Need to specify how to reconcile divergent branches.

Perhatikan bahwa babak fetch tetap berjalan sukses — salinan origin/main sudah maju — sebelum fatal: Need to specify how to reconcile divergent branches. menghentikan langkah penggabungan. Hints di atasnya memetakan tiga pilihan: konfigurasi pull.rebase false berarti gabungkan dengan merge, pull.rebase true berarti susun ulang dengan rebase, dan pull.ff only berarti hanya mau fast-forward. Ketiganya juga tersedia sebagai flag per-perintah: --no-rebase, --rebase, dan --ff-only — rincian tiap pilihan terdokumentasi di dokumentasi git pull . Karena penolakan ini, tidak pernah ada penggabungan diam-diam yang tidak kita pilih.

Menyusun Ulang dengan pull –rebase #

Pilihan pertama kita: git pull --rebase. Alih-alih melahirkan commit merge, rebase memutar ulang commit lokal Budi seolah-olah dibuat di atas commit Siti — persis mekanisme chapter Konsep Rebase :

bash
git pull --rebase

Output yang Dihasilkan:

text
Rebasing (1/1)
Successfully rebased and updated refs/heads/main.

Babak fetch tidak lagi tampil karena percobaan pull sebelumnya sudah memutakhirkan salinan origin/main — langsung ke babak rebase. Baris Rebasing (1/1) adalah progres singkat yang di terminal ditimpa baris berikutnya (Git memakai carriage-return untuk menimpanya; pada keluaran yang ditangkap keduanya terekam berurutan), dan Successfully rebased and updated refs/heads/main. menutup proses. Hasil akhirnya terbaca dari bentuk riwayatnya:

bash
git log --oneline --graph -4

Output yang Dihasilkan:

text
* 93628fe Tambah catatan internal
* c370d09 Tambah halaman kontak
* e55f05d Tambah jam buka
* 0c691c3 Tambah daftar produk

Empat commit tersusun lurus: commit Budi kini duduk di atas commit Siti tanpa commit penggabung — riwayat linear, enak dibaca, enak dilacak.

Menggabungkan dengan pull –no-rebase #

Pilihan kedua: git pull --no-rebase, perilaku merge klasik. Keduanya kembali menyimpang — Budi melengkapi catatan stoknya, Siti melengkapi halaman kontaknya dan mengirimkannya — lalu Budi langsung memilih jalur merge (pull polosnya lagi-lagi menolak, dan babak fetch-nya sudah selesai):

bash
git pull --no-rebase

Output yang Dihasilkan:

text
Merge made by the 'ort' strategy.
 kontak.md | 1 +
 1 file changed, 1 insertion(+)

Satu baris Merge made by the 'ort' strategy. mengabarkan bahwa strategi penggabungan ort (penerus recursive sebagai default sejak Git 2.34) berhasil menyatukan kedua sisi tanpa konflik, lalu diffstat merinci perubahan yang masuk. Commit penggabung lahir di riwayat — bedanya dengan rebase terlihat pada bentuk graf:

bash
git log --oneline --graph -6

Output yang Dihasilkan:

text
*   1ffe185 Merge branch 'main' of /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-pull/proyek-utama
|\  
| * 50b8f6f Lengkapi kontak
* | 35f28c7 Lengkapi catatan stok
* | 93628fe Tambah catatan internal
|/  
* c370d09 Tambah halaman kontak
* e55f05d Tambah jam buka

Commit Merge branch 'main' of ... memiliki dua induk: sisi Budi (* | di kanan) dan sisi Siti (| * di kiri), keduanya bertemu di titik percabangan. Riwayat tetap benar dan semua perubahan utuh — hanya bentuknya yang bercerita tentang pertemuan dua jalur. Bila kedua sisi menyunting bagian yang sama, merge akan berhenti pada konflik yang harus kita selesaikan — alur lengkapnya dibahas pada chapter Menyelesaikan Merge Conflicts .

Fetch atau pull? #

Aspekgit fetchgit pull
Mengunduh perkembangan remoteyaya (babak pertama)
Menyentuh branch lokaltidakya — menggabungkan ke branch aktif
Aman saat sedang kerja setengah jadiyasebaiknya commit dulu
Memberi kesempatan inspeksi duluyatidak — langsung menggabungkan
Bentuk perintahgit fetchgit pull, git pull --rebase, git pull origin main

Pull telah menempatkan pekerjaan Siti di meja Budi; arah baliknya — mengirim commit Budi ke titik temu — adalah pekerjaan git push, chapter berikutnya.