Gambaran Umum
Git push adalah perintah fundamental dalam sistem version control Git yang berfungsi untuk mengunggah (upload) commit-commit lokal dari repository di komputer Anda ke repository remote, seperti GitHub, GitLab, atau Bitbucket. Secara sederhana, ketika Anda melakukan git push, Anda sedang mentransfer seluruh perubahan yang telah Anda simpan secara lokal ke server terpusat agar anggota tim lain dapat mengaksesnya, atau agar Anda sendiri memiliki backup di cloud.
Perintah ini menjadi sangat penting dalam workflow kolaborasi modern karena menjadi satu-satunya mekanisme standar untuk menyinkronkan pekerjaan lokal ke upstream. Tanpa git push, semua commit yang Anda buat hanya tersimpan di mesin lokal. Bayangkan sebuah skenario di mana hard drive Anda rusak — tanpa push, seluruh riwayat perubahan hilang selamanya. terus, dalam konteks tim, push adalah cara Anda memberi sinyal bahwa fitur baru atau bug fix sudah siap di-review atau di-merge oleh rekan kerja. Inilah mengapa memahami git push secara mendalam bukan sekadar kelebihan, melainkan kebutuhan mutlak bagi setiap developer.
Berikut adalah step-by-step dasar untuk melakukan push pertama Anda:
# 1. Inisialisasi repository lokal
git init my-project
cd my-project
# 2. Buat file dan commit pertama
echo "Hello World" > README.md
git add README.md
git commit -m "Initial commit"
# 3. Tambahkan remote repository
git remote add origin https://github.com/username/my-project.git
# 4. Push commit ke remote
git push -u origin main
Perintah git push -u origin main pada langkah ke-4 tidak hanya mengunggah commit, tetapi juga menetapkan upstream tracking reference berkat flag -u (shorthand dari --set-upstream). Artinya, ke depannya Anda cukup mengetik git push tanpa menyebutkan nama remote dan branch secara eksplisit, karena Git sudah "mengingat" hubungan antara branch lokal main dengan branch remote origin/main.
Alur Kerjanya
Untuk memahami bagaimana git push bekerja di balik layar, kita perlu memahami konsep object transfer protocol yang digunakan Git. Git bukan sekadar menyalin file — Git mentransfer objek-objek yang bersifat immutable, yaitu blob (isi file), tree (struktur direktori), dan commit (snapshot + metadata). Ketika Anda menjalankan git push, Git melakukan serangkaian negosiasi dengan server remote untuk menentukan objek mana saja yang belum dimiliki oleh remote, lalu mengirimkan hanya objek-objek tersebut dalam format yang dikompresi menggunakan zlib. Pendekatan ini membuat push sangat efisien bahkan untuk repository berukuran besar, karena tidak ada file yang dikirim dua kali.
Komponen utama yang terlibat dalam proses push meliputi beberapa hal. Pertama adalah refspec, yaitu pemetaan antara branch lokal dan branch remote. Secara default, ketika Anda menjalankan git push origin main, Git menggunakan refspec implisit refs/heads/main:refs/heads/main, yang berarti "push local ref refs/heads/main ke remote ref refs/heads/main". Kedua adalah remote tracking branch, yaitu snapshot di lokal yang merepresentasikan state terakhir dari branch di remote. Ketiga adalah fast-forward check — sebelum menerima push, server remote akan memvalidasi bahwa push yang masuk dapat diterapkan sebagai fast-forward, artinya commit baru yang di-push merupakan perpanjangan langsung (descendant) dari commit terakhir di remote. Jika bukan, remote akan menolak push dan Anda harus melakukan merge atau rebase terlebih dahulu.
Sebagai ilustrasi visual dari alur kerja push:
Lokal Remote
┌─────────────┐ ┌─────────────┐
│ C1 → C2 → C3 (baru) │ C1 → C2 │
└─────────────┘ └─────────────┘
│ │
└─── git push origin main ───────┘
│ │
▼ ▼
┌─────────────┐ ┌─────────────┐
│ C1 → C2 → C3 │ C1 → C2 → C3│
└─────────────┘ └─────────────┘
Commit C3 yang hanya ada di lokal ditransfer ke remote, dan remote pointer main digeser dari C2 ke C3 (fast-forward).
Praktik di Dunia Nyata
Skenario 1: Push Pertama ke Repository Baru
Situasi paling umum bagi pemula adalah ketika Anda baru membuat repository di GitHub dan ingin mengunggah kode lokal untuk pertama kalinya. Proses ini membutuhkan pengecekan branch saat ini, penambahan remote, dan push dengan flag upstream.
# Cek branch aktif
git branch
# * main
# Tambahkan remote origin
git remote add origin git@github.com:username/new-repo.git
# Push pertama kali dengan set upstream
git push -u origin main
# Output:
# Enumerating objects: 5, done.
# Counting objects: 100% (5/5), done.
# Compressing objects: 100% (3/3), done.
# Writing objects: 100% (3/3), 1.23 KiB | 1.23 MiB/s, done.
# To github.com:username/new-repo.git
# * [new branch] main -> main
# Branch 'main' set up to track remote branch 'main' from 'origin'.
Setelah upstream ter-set, push berikutnya hanya perlu git push tanpa argumen tambahan.
Skenario 2: Push Branch Fitur untuk Pull Request
Dalam workflow Git Flow atau GitHub Flow, setiap fitur baru dikembangkan di branch terpisah. Setelah selesai, Anda push branch tersebut agar bisa dibuat Pull Request.
# Buat dan pindah ke branch fitur
git checkout -b feature/login-auth
# ... lakukan perubahan, lalu commit ...
git add src/auth/login.js
git commit -m "feat: implement JWT login authentication"
# Push branch fitur ke remote
git push -u origin feature/login-auth
# Output:
# Enumerating objects: 7, done.
# Counting objects: 100% (7/7), done.
# Compressing objects: 100% (4/4), done.
# Writing objects: 100% (4/4), 2.01 KiB | 2.01 MiB/s, done.
# To github.com:username/project.git
# * [new branch] feature/login-auth -> feature/login-auth
# Branch 'feature/login-auth' set up to track remote branch 'feature/login-auth' from 'origin'.
Setelah push berhasil, Anda bisa membuka browser dan membuat Pull Request dari branch feature/login-auth ke main.
Skenario 3: Push Setelah Rebase
Rebase menulis ulang riwayat commit, yang berarti SHA commit berubah. Akibatnya, jika Anda sudah pernah push branch tersebut sebelumnya, remote akan menolak push biasa karena bukan fast-forward. Anda membutuhkan force push, tetapi dengan pendekatan yang lebih aman menggunakan --force-with-lease.
# Rebase branch fitur ke main terbaru
git fetch origin
git rebase origin/main
# Output menunjukkan commits being rebased...
# Force push dengan lease (aman daripada --force)
git push --force-with-lease origin feature/login-auth
# Output:
# Enumerating objects: 9, done.
# Counting objects: 100% (9/9), done.
# Compressing objects: 100% (5/5), done.
# Writing objects: 100% (5/5), 1.89 KiB | 1.89 MiB/s, done.
# To github.com:username/project.git
# + abc1234...def5678 feature/login-auth -> feature/login-auth (forced update)
Flag --force-with-lease lebih aman karena Git akan memverifikasi bahwa remote branch masih dalam state yang Anda harapkan sebelum menimpa. Jika ada orang lain yang sudah push ke branch yang sama, operasi akan gagal — mencegah Anda menimpa pekerjaan rekan secara tidak sengaja.
Skenario 4: Push Semua Branch Sekaligus
Dalam situasi tertentu, misalnya saat migrasi repository atau saat Anda ingin memastikan semua branch lokal tersimpan di remote, Anda bisa menggunakan flag --all.
git push --all origin
# Output:
# Enumerating objects: 25, done.
# Counting objects: 100% (25/25), done.
# Compressing objects: 100% (15/15), done.
# Writing objects: 100% (15/15), 5.67 KiB | 5.67 MiB/s, done.
# To github.com:username/project.git
# a1b2c3d..e4f5g6h main -> main
# * [new branch] feature/login-auth -> feature/login-auth
# * [new branch] feature/dashboard -> feature/dashboard
# i7j8k9l..m0n1o2p develop -> develop
Perintah ini mengunggah semua branch yang ada di lokal ke remote origin. Gunakan dengan hati-hati, terutama jika ada branch yang berisi data sensitif atau eksperimen yang belum siap dibagikan.
Skenario 5: Push Tag ke Remote
Tag dalam Git biasanya digunakan untuk menandai rilis versi (misalnya v1.0.0). Tag tidak otomatis ter-push bersama commit, sehingga Anda perlu mengunggahnya secara eksplisit.
# Buat tag annotated
git tag -a v1.0.0 -m "Release version 1.0.0"
# Push tag tertentu
git push origin v1.0.0
# Output:
# To github.com:username/project.git
# * [new tag] v1.0.0 -> v1.0.0
# Atau push semua tag sekaligus
git push --tags
# Output:
# To github.com:username/project.git
# * [new tag] v1.0.0 -> v1.0.0
# * [new tag] v0.9.0 -> v0.9.0
Menggunakan --tags mengunggah semua tag lokal yang belum ada di remote, sedangkan menyebut nama tag secara spesifik hanya mengunggah tag yang disebutkan.
Masalah Umum dan Cara Mengatasinya
Masalah Umum: Push Ditolak Karena Non-Fast-Forward
Ini adalah error paling sering ditemui, terutama bagi pemula. Error muncul ketika ada commit baru di remote yang belum Anda miliki di lokal, sehingga push Anda bukan merupakan fast-forward.
git push origin main
# Output:
# To github.com:username/project.git
# ! [rejected] main -> main (non-fast-forward)
# error: failed to push some refs to 'github.com:username/project.git'
# hint: Updates were rejected because the remote contains work that you do
# hint: not have locally. This is usually caused by another repository pushing
# hint: to the same ref. You may need to first integrate the remote changes
# hint: (e.g., 'git pull ...') before pushing again.
Solusinya adalah melakukan pull terlebih dahulu, menyelesaikan konflik jika ada, lalu push kembali:
# Opsi 1: Pull dengan merge (menjaga riwayat asli)
git pull origin main
# Jika ada konflik, resolve, lalu:
git add .
git commit -m "Merge remote main into local main"
git push origin main
# Opsi 2: Pull dengan rebase (riwayat lebih bersih)
git pull --rebase origin main
# Jika ada konflik, resolve per commit, lalu:
git rebase --continue
git push origin main
Pendekatan rebase umumnya lebih disukai untuk branch fitur karena menghasilkan riwayat linear yang lebih mudah dibaca, sementara merge lebih cocok untuk branch utama seperti main atau develop di mana riwayat merge memiliki nilai dokumentasi.
Masalah Umum: Permission Denied (Publickey)
Ketika menggunakan SSH untuk push, Anda mungkin menemui error autentikasi:
git push origin main
# Output:
# git@