Kata upstream sudah berkali-kali lewat di depan kita: branch 'main' set up to track 'origin/main', fatal: The current branch ... has no upstream branch, flag -u, --set-upstream. Semua keluaran itu berputar pada satu hubungan yang selama ini kita pakai tanpa nama: ikatan antara sebuah branch lokal dan cabang remote yang menjadi mitra default-nya. Hubungan itulah upstream branch — dan memahaminya menjelaskan sekaligus mengapa git status tahu kita di depan atau di belakang, mengapa git pull dan git push bisa hidup tanpa argumen, serta di mana Git menyimpan ikatannya. Chapter ini membedahnya pada satu repository nyata.

Apa Itu Upstream Branch #

Upstream branch adalah cabang remote yang ditunjuk sebagai mitra default sebuah branch lokal. Ikatan ini bersifat opsional — branch lokal boleh hidup tanpa upstream — tetapi begitu terpasang, Git memakainya untuk tiga hal: membandingkan posisi di git status, menentukan sumber penggabungan git pull polos, dan menentukan tujuan pengiriman git push polos. Konvensi umumnya: main lokal bermitra dengan origin/main.

Ikatan ini terpasang lewat tiga pintu yang semuanya sudah kita lewati: git clone memasangnya untuk branch awal secara otomatis, git push -u memasangnya saat push pertama, dan git remote add justru tidak memasangnya sama sekali (buktinya di chapter Menambahkan Remote ). Lab kita memakai pintu pertama: Budi bergabung ke proyek berjalan — proyek-utama.git sudah memuat dua commit, di sandbox disemai clone sementara yang kemudian dihapus — sehingga Budi cukup meng-clone:

bash
git clone proyek-utama.git budi
cd budi
git config user.name "Budi Santoso"
git config user.email "[email protected]"

Melihat Ikatan dengan branch -vv #

Perintah penampil ikatan paling ringkas: git branch -vv — dua kali -v membuat tiap baris branch memuat hash, upstream, dan subjek commit:

bash
git branch -vv

Output yang Dihasilkan:

text
* main 77fa258 [origin/main] Tambah daftar produk

Empat kolom berjejer pada satu baris: tanda * menandai branch aktif, main namanya, 77fa258 hash commit yang ditunjuk, lalu [origin/main] — inilah upstream-nya — dan subjek commit. Bandingkan dengan chapter git push : fitur-pengiriman yang di-push eksplisit tanpa -u sama sekali tidak memuat tanda kurung siku semacam ini. Kolom [...] hadir hanya bagi branch yang berupstream.

Menanyakan Upstream Secara Langsung #

Untuk skrip atau sekadar memastikan, Git menyediakan tanya-jawab langsung lewat notasi <branch>@{upstream}:

bash
git rev-parse --abbrev-ref main@{upstream}

Output yang Dihasilkan:

text
origin/main

Git menjawab nama lengkap cabang mitranya: origin/main. Notasi yang sama punya bentuk singkat @{u}:

bash
git rev-parse --abbrev-ref main@{u}

Output yang Dihasilkan:

text
origin/main

Notasi @{upstream} ini lebih dari sekadar tampilan — ia adalah alamat yang bisa dipakai di perintah lain, misalnya git log main..main@{u} untuk melihat apa yang belum kita kirim, persis pola rentang main..origin/main di chapter git fetch .

Status Membaca Ikatan: ahead dan behind #

Manfaat paling setia upstream terasa pada perintah yang paling sering diketik: git status. Budi menambahkan satu commit persiapan, lalu memeriksa keadaan:

bash
printf 'Daftar persiapan stok\n' > persiapan.md
git add persiapan.md
git commit -m "Tambah catatan persiapan"
git status

Output yang Dihasilkan:

text
On branch main
Your branch is ahead of 'origin/main' by 1 commit.
  (use "git push" to publish your local commits)

nothing to commit, working tree clean

Baris Your branch is ahead of 'origin/main' by 1 commit. hanya bisa ditulis karena git status tahu harus membandingkan main dengan siapa — upstream-nya, lengkap dengan petunjuk (use "git push" to publish your local commits). Kebalikannya pernah kita lihat di chapter git fetch : behind 'origin/main' by 1 commit. Anotasi yang sama menempel pada git branch -vv:

bash
git branch -vv

Output yang Dihasilkan:

text
* main 676b61a [origin/main: ahead 1] Tambah catatan persiapan

Kurung siku kini memuat [origin/main: ahead 1] — ikatan plus hitungan selisihnya. Inilah mesin di balik keajaiban chapter sebelumnya: git pull polos bekerja karena Git tinggal membaca upstream branch aktif, dan git push polos ditolak di fitur-pengiriman justru karena bacaan itu kosong.

Memutus Ikatan dengan –unset-upstream #

Apa yang terjadi bila ikatan diputus? Perintahnya git branch --unset-upstream:

bash
git branch --unset-upstream

Output yang Dihasilkan:

text

Perintah ini tidak mencetak apa pun — dan bukti putusnya justru terlihat dari keluaran perintah lain:

bash
git branch -vv

Output yang Dihasilkan:

text
* main 676b61a Tambah catatan persiapan

Tanda kurung siku beserta [origin/main: ahead 1] lenyap: main kini berdiri tanpa mitra. Salinan penunjuk origin/main tidak ikut hilang — keduanya barang berbeda, dibedah pada chapter Remote-Tracking Branch . Yang hilang hanyalah alamat mitra default, dan konsekuensinya persis cermin penolakan push di chapter git push :

bash
git pull

Output yang Dihasilkan:

text
There is no tracking information for the current branch.
Please specify which branch you want to merge with.
See git-pull(1) for details.

    git pull <remote> <branch>

If you wish to set tracking information for this branch you can do so with:

    git branch --set-upstream-to=origin/<branch> main

git pull polos menolak menebak: tanpa informasi tracking, Git tidak tahu dari mana mengambil dan ke apa menggabungkan. Hint-nya menyediakan dua jalan — menyebut remote dan branch secara eksplisit, atau memasangnya kembali.

Memasang Kembali dengan –set-upstream-to #

Pemasangan ulang tidak menunggu push berikutnya — cukup satu perintah: git branch --set-upstream-to=<cabang-remote>:

bash
git branch --set-upstream-to=origin/main main

Output yang Dihasilkan:

text
branch 'main' set up to track 'origin/main'.

Baris branch 'main' set up to track 'origin/main'. — persis kalimat yang dulu dicetak git push -u di chapter git push dan oleh git push --set-upstream. Nama branch di akhir boleh dilewatkan; tanpa nama, Git memasang ikatan untuk branch aktif. Bukti pemulihannya:

bash
git branch -vv

Output yang Dihasilkan:

text
* main 676b61a [origin/main: ahead 1] Tambah catatan persiapan

Tempat Ikatan Tersimpan #

Seluruh pembicaraan di atas ternyata tersimpan sederhana dalam satu berkas — empat belas baris berikut adalah isi .git/config clone Budi:

bash
cat .git/config

Output yang Dihasilkan:

text
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
[remote "origin"]
	url = /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-upstream/proyek-utama.git
	fetch = +refs/heads/*:refs/remotes/origin/*
[user]
	name = Budi Santoso
	email = [email protected]
[branch "main"]
	remote = origin
	merge = refs/heads/main

Perhatikan dua entri terakhir. Bagian [branch "main"] memuat pasangan remote = origin dan merge = refs/heads/main — begitulah upstream tersimpan: nama remote tempat mitra berada, plus nama cabang di sana. Kedua nilai inilah yang dibaca git status, git pull, dan git push setiap kali kita malas mengetik argumen. Blok [branch "<nama>"] seperti ini dimiliki tiap branch yang berupstream — fitur-pengiriman punya bloknya sendiri begitu --set-upstream dijalankan. Daftar entri konfigurasi per-branch tersedia di dokumentasi git-config .

Ikatan upstream menjelaskan mitra remote satu branch lokal. Masih ada dua penanya lanjutan: origin/main sendiri sebenarnya apa, dan bagaimana branch baru dibuat agar langsung terikat ke cabang remote pilihan kita — termasuk opsi --track yang belum tersentuh? Itu materi chapter Tracking Branch .