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:
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:
git branch -vvOutput yang Dihasilkan:
* main 77fa258 [origin/main] Tambah daftar produkEmpat 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}:
git rev-parse --abbrev-ref main@{upstream}Output yang Dihasilkan:
origin/mainGit menjawab nama lengkap cabang mitranya: origin/main. Notasi yang sama punya bentuk singkat @{u}:
git rev-parse --abbrev-ref main@{u}Output yang Dihasilkan:
origin/mainNotasi @{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:
printf 'Daftar persiapan stok\n' > persiapan.md
git add persiapan.md
git commit -m "Tambah catatan persiapan"
git statusOutput yang Dihasilkan:
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 cleanBaris 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:
git branch -vvOutput yang Dihasilkan:
* main 676b61a [origin/main: ahead 1] Tambah catatan persiapanKurung 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:
git branch --unset-upstreamOutput yang Dihasilkan:
Perintah ini tidak mencetak apa pun — dan bukti putusnya justru terlihat dari keluaran perintah lain:
git branch -vvOutput yang Dihasilkan:
* main 676b61a Tambah catatan persiapanTanda 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
:
git pullOutput yang Dihasilkan:
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> maingit 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>:
git branch --set-upstream-to=origin/main mainOutput yang Dihasilkan:
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:
git branch -vvOutput yang Dihasilkan:
* main 676b61a [origin/main: ahead 1] Tambah catatan persiapanTempat Ikatan Tersimpan #
Seluruh pembicaraan di atas ternyata tersimpan sederhana dalam satu berkas — empat belas baris berikut adalah isi .git/config clone Budi:
cat .git/configOutput yang Dihasilkan:
[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/mainPerhatikan 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
.