Arah masuk sudah kita kuasai: git fetch menyalin catatan remote, git pull menyalin sekaligus menggabungkan. Kolaborasi baru utuh bila arah keluar juga dikuasai — pekerjaan Budi baru “ada” bagi Siti setelah commit-nya sampai ke titik temu. Perintahnya git push: mengirim commit dari repository lokal ke remote. Chapter ini menguji push dari repository kosong, lalu bentuk polosnya, pengiriman branch fitur, penolakan saat remote lebih dulu maju, dan kiriman singkat berupa tag.
Membangun Kembali Panggung Latihan #
Lab baru memakai pola akrab dari chapter Konsep Remote
: bare repository proyek-utama.git sebagai titik temu, Budi meng-clone-nya. Clone menempel pada repository yang masih kosong, dan Git mengatakannya dengan terbuka:
git clone proyek-utama.git budiOutput yang Dihasilkan:
Cloning into 'budi'...
warning: You appear to have cloned an empty repository.
done.Peringatan ini bukan kegagalan — done. menandakan clone sukses, hanya belum ada satu pun commit untuk disalin. Budi membuat commit pertama seperti biasa:
printf '# Toko Budi\n' > README.md
git add README.md
git commit -m "Buat README toko"Push Pertama dengan -u #
Saat inilah momen yang ditunggu: commit Budi ada di lokal, remote masih hampa. Perintahnya:
git push -u origin mainOutput yang Dihasilkan:
Enumerating objects: 3, done.
Counting objects: 100% (3/3), done.
Writing objects: 100% (3/3), 232 bytes | 232.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 (from 0)
To /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git
* [new branch] main -> main
branch 'main' set up to track 'origin/main'.Keluaran terpadat sejauh ini — mari bedah per blok. Empat baris pertama — Enumerating objects, Counting objects, Writing objects, hingga Total 3 — adalah banner progress pengiriman: Git memeriksa objek mana yang belum dimiliki remote, memadatkannya, lalu mengirimnya; angka 232 bytes dan laju KiB/s bergantung pada isi repository serta kecepatan mesin. Baris To ... menyebut tujuan, disusul inti laporan: * [new branch] main -> main berarti branch main lahir di remote dan kini sejajar dengan milik Budi. Baris terakhir, branch 'main' set up to track 'origin/main'., adalah kerja flag -u: memasang ikatan upstream dari main lokal ke origin/main — bentuk ringkasnya sudah kita lihat di chapter Konsep Remote
, dan efek ikatannya dibedah di chapter Upstream Branch
.
Push Berikutnya dalam Bentuk Polos #
Budi menambah satu commit lagi — daftar produk — lalu mengirimnya. Kali ini tidak ada flag, tidak ada nama remote, tidak ada nama branch:
git pushOutput yang Dihasilkan:
To /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git
2bd3e21..77fa258 main -> mainBaris 2bd3e21..77fa258 main -> main membaca rentang perpindahan: main di remote maju dari 2bd3e21 ke 77fa258. Bentuk polos ini bekerja karena ikatan upstream terpasang sejak push pertama — git push tanpa argumen mengirim branch aktif ke upstream-nya. Di balik satu baris itu Git tetap menjalankan pemeriksaan yang sama: objek yang belum ada di remote dikemas dan dikirim dulu, barulah penunjuk remote digeser.
Mengirim Branch Fitur Baru #
Branch fitur tidak ikut terkirim dengan sendirinya — git push hanya mengurus branch aktif. Budi membuat branch baru dan menyiapkan satu commit di dalamnya:
git switch -c fitur-pengirimanOutput yang Dihasilkan:
Switched to a new branch 'fitur-pengiriman'printf 'Pengiriman wilayah Jakarta\n' > pengiriman.md
git add pengiriman.md
git commit -m "Tambah halaman pengiriman"Push untuk branch ini menyebut nama branch secara eksplisit — git push <remote> <branch>:
git push origin fitur-pengirimanOutput yang Dihasilkan:
To /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git
* [new branch] fitur-pengiriman -> fitur-pengirimanPenanda * [new branch] mengabarkan kelahiran fitur-pengiriman di remote — persis bentuk push pertama kita. Perhatikan apa yang tidak terjadi: tanpa baris set up to track. Push eksplisit mengirim branch tanpa memasang ikatan upstream, dan konsekuensinya terasa pada commit berikutnya:
printf 'Pengiriman wilayah Jakarta dan Bekasi\n' > pengiriman.md
git add pengiriman.md
git commit -m "Perluas wilayah pengiriman"
git pushOutput yang Dihasilkan:
fatal: The current branch fitur-pengiriman has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin fitur-pengiriman
To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.git push polos menolak menebak ke mana commit fitur-pengiriman harus dikirim, dan hint-nya langsung menawarkan jalan keluar yang sekaligus memasang ikatan:
git push --set-upstream origin fitur-pengirimanOutput yang Dihasilkan:
To /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git
08dba45..ab348c3 fitur-pengiriman -> fitur-pengiriman
branch 'fitur-pengiriman' set up to track 'origin/fitur-pengiriman'.Rentang 08dba45..ab348c3 mencatat dua commit yang terkirim sekaligus, dan baris set up to track menutup persoalan. Push polos kini berfungsi — karena semuanya sudah ada di remote, Git melaporkannya dengan jujur:
git pushOutput yang Dihasilkan:
Everything up-to-dateMenandai Titik Rilis dengan –tags #
Budi kembali ke main dan menandai keadaan “daftar produk lengkap” sebagai rilis v1.0 — tag dibuat lokal dengan git tag v1.0, lalu dikirim:
git push --tagsOutput yang Dihasilkan:
To /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git
* [new tag] v1.0 -> v1.0Penanda * [new tag] menunjukkan v1.0 sampai ke remote. Flag --tags mengirim seluruh tag lokal yang belum ada di remote — hanya tag; branch tidak ikut tergeser. Seni menandai rilis — tag beranotasi, penomoran versi — dibahas pada chapter Release dan Tags
.
Saat Remote Berjalan Lebih Dulu #
Skenario terakhir, yang paling sering menyakitkan: push ditolak bukan karena branch, melainkan isi remote. Siti ikut bekerja — meng-clone, menambah halaman tentang, mengirimkannya. Budi yang belum menarik apa pun menyelesaikan slogan barunya lalu push:
git pushOutput yang Dihasilkan:
To /home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git
! [rejected] main -> main (fetch first)
error: failed to push some refs to '/home/z/my-project/tutorial-extracted/work/sandbox/remote-repository/part-a/latihan-push/proyek-utama.git'
hint: Updates were rejected because the remote contains work that you do not
hint: have locally. This is usually caused by another repository pushing to
hint: the same ref. If you want to integrate the remote changes, use
hint: 'git pull' before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.Baris ! [rejected] berarti remote menolak pergeseran main: di sana sudah ada commit Siti yang tidak dimiliki Budi, dan menimpanya akan mengubur pekerjaan Siti. Dua hal penting: commit Budi tidak hilang — semuanya aman di repository lokal — dan hint menunjuk langkah berikutnya, git pull sebelum push ulang. Penyelesaian lengkap skenario ini dibedah tuntas pada chapter Push Rejected
.
Alamat Remote pada Layanan Hosting #
Sepanjang section ini remote kita berupa folder lokal — agar keluaran bisa direproduksi tanpa jaringan. Pada layanan hosting seperti GitHub, perintahnya sama persis; yang berubah hanya alamat di buku alamat. Dua format paling umum: HTTPS menyertakan skema dan akhiran .git,
https://github.com/budi/katalog-buku.gitsedangkan SSH memakai pola user@host:proyek,
[email protected]:budi/katalog-buku.gitBedanya ada pada autentikasi: HTTPS meminta nama pengguna dan personal access token (kecuali disimpan credential helper), sedangkan SSH memakai kunci kriptografi yang dipasang dan didaftarkan lebih dulu ke layanan. Perbandingannya dibahas pada chapter SSH vs HTTPS ; cara mengganti format terpasang sudah dipraktikkan di chapter Mengganti Remote URL . Bentuk perintah push lengkap tersedia di dokumentasi git push .
Keluaran push hari ini berkali-kali menyebut upstream — set up to track, penolakan push polos, flag --set-upstream. Semuanya berputar pada satu hubungan yang belum dibedah: ikatan branch lokal dengan cabang remote yang dilacaknya. Chapter berikutnya mengangkatnya ke meja pembedah.