Remotes, Refspecs, and Tracking Branches
Learn Git In Action - Part 035
Remote repository, refspec, remote-tracking branch, upstream branch, fetch/push mapping, pruning, deletion, dan workflow multi-remote yang aman.
Part 035 — Remotes, Refspecs, and Tracking Branches
Skill target: kamu bisa membaca dan mengendalikan hubungan local repository dengan remote secara deterministic: branch mana yang local, branch mana yang hanya snapshot remote, ref mana yang di-fetch, ref mana yang di-push, kapan upstream dipakai, kapan pruning aman, dan bagaimana mencegah push ke tempat yang salah.
Banyak engineer memakai Git remote dengan mental model yang terlalu sederhana:
origin = GitHub/GitLab repo
pull = update
push = upload
Model itu cukup untuk pekerjaan kecil, tetapi runtuh ketika ada fork, upstream, release branch, protected branch, mirror, vendor repository, force-push incident, atau multi-remote enterprise workflow.
Git tidak berpikir dalam istilah “upload folder”. Git berpikir dalam istilah:
- object graph;
- refs;
- namespace ref;
- refspec mapping;
- local refs;
- remote-tracking refs;
- upstream configuration;
- push destination.
Remote collaboration baru aman jika kamu bisa menjawab empat pertanyaan ini kapan pun:
- Apa nama ref lokal yang sedang saya pegang?
- Apa snapshot terakhir dari remote yang saya tahu?
- Apa remote branch yang menjadi upstream branch saya?
- Ke ref mana command push saya akan menulis?
1. Mental Model: Remote Bukan Branch, Remote Adalah Named Transport Endpoint
Remote adalah nama lokal untuk endpoint repository lain.
Contoh:
git remote -v
Output umum:
origin git@github.com:acme/payments.git (fetch)
origin git@github.com:acme/payments.git (push)
origin bukan branch. origin bukan server secara magic. origin adalah nama konfigurasi lokal yang punya URL fetch/push.
Secara konseptual:
Yang penting:
- remote branch di server biasanya berada di
refs/heads/<name>pada remote repository; - snapshot lokal dari remote branch disimpan sebagai
refs/remotes/<remote>/<name>; - local branch milikmu berada di
refs/heads/<name>; - fetch umumnya meng-update
refs/remotes/origin/*, bukanrefs/heads/*; - push meng-update refs di remote repository.
origin/main yang kamu lihat lokal bukan main di server secara live. Itu adalah snapshot terakhir yang berhasil kamu fetch.
2. Namespace Ref yang Harus Dibedakan
Git refs punya namespace. Namespace ini bukan kosmetik; ini menentukan safety boundary.
| Namespace | Example | Meaning |
|---|---|---|
| Local branch | refs/heads/main | Branch yang bisa kamu checkout dan biasanya kamu commit ke sana. |
| Remote-tracking branch | refs/remotes/origin/main | Snapshot lokal dari branch remote terakhir kali fetch. |
| Tag | refs/tags/v1.2.0 | Nama untuk release/version/checkpoint. |
| Notes | refs/notes/commits | Metadata tambahan untuk object. |
| Stash | refs/stash | Ref untuk stash stack lokal. |
| Pull request refs | refs/pull/*, refs/merge-requests/* | Platform-specific refs, tidak selalu di-fetch default. |
Jangan campur konsep:
main = biasanya shorthand untuk refs/heads/main jika branch lokal ada
origin/main = biasanya shorthand untuk refs/remotes/origin/main
refs/heads/main = branch lokal penuh
refs/remotes/origin/main = remote-tracking ref lokal
Inspect dengan command:
git show-ref --heads
git show-ref --tags
git show-ref | grep refs/remotes
Atau lebih eksplisit:
git for-each-ref --format='%(refname) %(objectname:short) %(committerdate:relative)' refs/heads refs/remotes refs/tags
3. Apa yang Terjadi Saat git clone?
Saat clone repository biasa:
git clone git@github.com:acme/payments.git
cd payments
Git umumnya membuat:
- remote bernama
origin; - fetch refspec default;
- remote-tracking refs seperti
origin/main; - local branch yang tracking ke remote default branch;
- working tree checkout dari branch tersebut.
Periksa konfigurasi:
git config --get remote.origin.url
git config --get-all remote.origin.fetch
git branch -vv
Contoh output:
+refs/heads/*:refs/remotes/origin/*
* main 3a9f12c [origin/main] Add payment reversal audit log
Baris refspec ini adalah inti clone default:
+refs/heads/*:refs/remotes/origin/*
Artinya:
Saat fetch dari
origin, ambil semua branch remote direfs/heads/*dan simpan snapshot lokalnya direfs/remotes/origin/*.
Tanda + berarti Git boleh memperbarui ref tujuan walaupun update-nya bukan fast-forward. Untuk remote-tracking refs, ini masuk akal karena remote bisa saja force-push, dan snapshot lokal harus mencerminkan remote terbaru.
4. Remote-Tracking Branch: Snapshot, Bukan Branch Aktif
origin/main bukan branch yang kamu commit ke sana. Ia adalah read-mostly local ref yang Git update ketika fetch.
Contoh:
git log --oneline --decorate --graph --all --max-count=20
Kamu mungkin melihat:
* a8c1042 (HEAD -> feature/refund) Add refund audit event
* 91a8840 (origin/main, main) Harden payment idempotency
Meaning:
mainadalah branch lokal;origin/mainadalah snapshot remote branchmaindari terakhir fetch;feature/refundadalah branch lokal aktif;HEADmenunjukfeature/refund.
Remote-tracking refs menjadi basis untuk:
- melihat divergence;
- membuat branch lokal dari remote branch;
- menghitung merge-base;
- membandingkan lokal vs remote;
- recovery dari salah push/fetch;
- memilih base untuk rebase.
Command inspeksi:
git branch -r
git log --oneline main..origin/main
git log --oneline origin/main..main
git rev-list --left-right --count main...origin/main
Interpretasi rev-list --left-right --count main...origin/main:
2 5
Artinya:
- local
mainpunya 2 commit yang tidak ada diorigin/main; origin/mainpunya 5 commit yang tidak ada di localmain.
5. Tracking Branch dan Upstream Branch
Local branch bisa dikonfigurasi untuk “tracking” remote branch tertentu.
Contoh:
git branch -vv
Output:
* feature/refund 8c12d9a [origin/feature/refund: ahead 2] Add refund audit
main 91a8840 [origin/main] Harden payment idempotency
[origin/feature/refund] adalah upstream branch untuk local branch feature/refund.
Konfigurasi yang tersimpan:
git config --get branch.feature/refund.remote
git config --get branch.feature/refund.merge
Biasanya:
origin
refs/heads/feature/refund
Artinya:
- remote upstream:
origin; - remote branch upstream:
refs/heads/feature/refund.
Upstream dipakai oleh command seperti:
git status
git pull
git push
Tergantung config push mode, upstream juga bisa memengaruhi default destination push.
6. Membuat Local Branch dari Remote Branch
Jika remote punya branch release/2026.07, setelah fetch kamu punya:
origin/release/2026.07
Untuk membuat local branch yang tracking remote branch:
git switch --track origin/release/2026.07
Atau eksplisit:
git switch -c release/2026.07 origin/release/2026.07
Lalu set upstream jika belum otomatis:
git branch --set-upstream-to=origin/release/2026.07 release/2026.07
Cek:
git branch -vv
Common mistake:
git switch -c release/2026.07
Command ini membuat branch baru dari current HEAD, bukan dari origin/release/2026.07, kecuali current HEAD kebetulan sama. Untuk release/hotfix, mistake ini bisa sangat mahal.
Safe pattern:
git fetch origin
git switch --track origin/release/2026.07
git status -sb
git log --oneline --decorate -5
7. Refspec: Bahasa Mapping Ref
Refspec menentukan mapping source ref ke destination ref.
Format umum:
[+]<src>:<dst>
Komponen:
| Component | Meaning |
|---|---|
src | Ref sumber. Untuk fetch: ref di remote. Untuk push: ref lokal. |
dst | Ref tujuan. Untuk fetch: ref lokal. Untuk push: ref remote. |
+ | Izinkan non-fast-forward update pada destination ref. |
* | Wildcard mapping. |
| empty src | Delete destination ref saat push. |
Default fetch refspec:
+refs/heads/*:refs/remotes/origin/*
Manual fetch satu branch:
git fetch origin refs/heads/release/2026.07:refs/remotes/origin/release/2026.07
Manual push local branch ke remote branch:
git push origin feature/refund:refs/heads/feature/refund
Push current HEAD ke remote branch tertentu:
git push origin HEAD:refs/heads/feature/refund
Delete remote branch:
git push origin :refs/heads/feature/refund
Atau porcelain form:
git push origin --delete feature/refund
Mental model:
8. Fetch Refspec vs Push Refspec
Remote configuration can contain separate fetch URL, push URL, fetch refspec, and push behavior.
Inspect:
git remote show origin
git config --get-all remote.origin.fetch
git config --get remote.origin.pushurl
git config --get push.default
Fetch refspec is usually remote-specific:
git config --get-all remote.origin.fetch
Push default is often global or repository config:
git config --get push.default
Important push.default modes:
| Mode | Practical meaning |
|---|---|
simple | Push current branch to upstream branch of same name. Safe default for many users. |
current | Push current branch to branch of same name on remote. |
upstream | Push current branch to its upstream branch. |
matching | Push all matching branch names. Dangerous in many modern workflows. |
nothing | Push nothing unless refspec explicit. Very safe but verbose. |
For serious teams, do not leave push behavior ambiguous. Prefer:
git config --global push.default simple
For critical release repositories, some engineers prefer:
git config --global push.default nothing
Then every push must be explicit:
git push origin HEAD:refs/heads/release/2026.07
This is slower but eliminates many accidental push destinations.
9. git fetch: Update Remote-Tracking Refs, Not Working Tree
git fetch origin generally does two things:
- downloads missing objects needed to represent remote refs;
- updates local remote-tracking refs according to fetch refspec.
It does not normally change:
- current branch;
- working tree;
- index.
This is why fetch is the safest network operation for inspection.
Safe daily sync pattern:
git fetch --all --prune
git status -sb
git log --oneline --decorate --graph --all --max-count=30
Then choose integration explicitly:
# Option A: merge remote changes
git merge --ff-only origin/main
# Option B: rebase private branch onto updated main
git rebase origin/main
Do not teach teams “just pull” before they understand fetch. pull is fetch plus integration; fetch alone is observation.
10. git pull: Not a Primitive, But Fetch + Integrate
git pull is shorthand for:
git fetch <remote>
then merge or rebase fetched upstream
Which integration it performs depends on config and flags:
git pull --ff-only
git pull --rebase
git pull --no-rebase
Problem: git pull hides two decisions:
- What remote/ref did I fetch?
- Did I merge, rebase, or fast-forward?
For individual work this is okay once policy is configured. For training, incident recovery, and regulated systems, prefer explicit operations:
git fetch origin
git merge --ff-only origin/main
Or:
git fetch origin
git rebase origin/main
Team standard should define pull policy:
git config pull.ff only
Or:
git config pull.rebase true
The dangerous state is not merge or rebase. The dangerous state is implicit integration policy.
11. git push -u: Publish and Set Upstream
When creating a new branch:
git switch -c feature/refund
# commits...
git push -u origin HEAD
-u / --set-upstream records upstream configuration for current branch.
After this:
git branch -vv
You may see:
* feature/refund 8c12d9a [origin/feature/refund] Add refund audit
Now git status can show ahead/behind, and git pull / git push have branch context.
For clarity in teams, prefer:
git push -u origin HEAD:refs/heads/feature/refund
This makes destination explicit.
12. Remote Branch Deletion and Local Cleanup
Delete remote branch:
git push origin --delete feature/refund
This deletes refs/heads/feature/refund on remote.
But your local remote-tracking ref may remain until prune:
git fetch origin --prune
Or:
git remote prune origin
Local branch cleanup:
git branch --merged main
git branch -d feature/refund
Force delete local branch:
git branch -D feature/refund
Use -D only after checking:
git log --oneline main..feature/refund
git branch -vv
A branch being deleted remotely does not automatically mean your local branch has no useful commits.
13. Pruning: Removing Stale Remote-Tracking Refs
When a branch is deleted on remote, your local origin/<branch> can become stale.
Detect stale branches:
git remote show origin
Prune:
git fetch origin --prune
Set automatic prune:
git config --global fetch.prune true
Prune tags? Be careful.
git fetch --prune --prune-tags
Tag pruning is more dangerous in release-heavy systems because tags are release identities. Do not enable aggressive tag pruning globally unless your team knows exactly why.
Safe team policy:
- Prune remote-tracking branches regularly.
- Do not auto-prune tags in release repositories unless documented.
- Never move public release tags silently.
14. Tags and Remotes
Tags are refs too:
refs/tags/v1.8.0
Fetch behavior around tags is subtle:
- Git often fetches tags that point into fetched histories automatically;
--tagsfetches all tags from remote;- explicit tag refspecs can be configured;
- deleting/moving tags requires deliberate handling.
Fetch all tags:
git fetch origin --tags
Push a tag:
git push origin v1.8.0
Push all tags:
git push origin --tags
Avoid --tags in automation unless release process owns all tags. It can accidentally publish local experiment tags.
Better release push:
git push origin refs/tags/v1.8.0
Delete remote tag:
git push origin :refs/tags/v1.8.0
Operational rule:
Branch refs are often mutable; release tags should be treated as immutable after publication.
15. Multiple Remotes: Fork + Upstream
Open-source or fork-based workflow often has:
git remote -v
origin git@github.com:yourname/project.git (fetch)
origin git@github.com:yourname/project.git (push)
upstream git@github.com:acme/project.git (fetch)
upstream git@github.com:acme/project.git (push)
Common convention:
origin= your fork;upstream= canonical project.
Fetch both:
git fetch --all --prune
Create branch from upstream main:
git switch -c feature/refund upstream/main
Push branch to your fork:
git push -u origin HEAD
Update local main from upstream:
git switch main
git fetch upstream
git merge --ff-only upstream/main
git push origin main
Important distinction:
upstream/main = canonical project snapshot
origin/main = fork's main snapshot
main = your local main
Do not blindly rebase against origin/main if the real source of truth is upstream/main.
16. Multiple Remotes in Enterprise Systems
Enterprise repos may use remotes like:
| Remote | Meaning |
|---|---|
origin | Team writable remote. |
upstream | Platform canonical remote. |
mirror | Read-only disaster recovery mirror. |
vendor | Vendor-delivered source. |
customer-a | Customer-specific fork or customization stream. |
staging | Deployment mirror, not necessarily source-of-truth. |
The risk grows because remote names encode authority.
Anti-pattern:
git push --all origin
In multi-remote environments, this can publish branches that should stay local or internal.
Safer pattern:
git remote -v
git branch -vv
git push origin HEAD:refs/heads/feature/refund
For automation, never rely on developer-local remote naming unless you control bootstrap.
Better automation input:
CANONICAL_REMOTE_URL="git@github.com:acme/payments.git"
TARGET_REF="refs/heads/release/2026.07"
Then validate:
git remote get-url origin
git ls-remote --heads origin release/2026.07
17. Remote URL vs Push URL
A remote can have different fetch and push URLs.
Useful for:
- read-only mirror fetch;
- push over SSH but fetch over HTTPS;
- fork workflows;
- restricted write endpoints.
Inspect:
git remote get-url origin
git remote get-url --push origin
Set push URL:
git remote set-url --push origin git@github.com:acme/payments.git
Multiple push URLs can exist. Be careful:
git remote set-url --add --push origin git@github.com:mirror/payments.git
Pushing to multiple destinations is powerful but risky. Use it only for mirror automation with explicit monitoring.
18. Remote-Tracking Ref Can Move Backward
If someone force-pushes remote branch, your next fetch may move origin/main backward or sideways.
Before fetch:
origin/main -> C
Remote is force-updated:
main -> B
After fetch:
origin/main -> B
Your local branch main may still point to C.
Detection:
git fetch origin
git reflog show refs/remotes/origin/main
Remote-tracking refs have reflogs if enabled/available. They can help recover old remote positions.
Team implication:
- force push to shared branch is not just a local rewrite;
- it changes what everyone sees as remote truth after fetch;
- remote-tracking reflog may be the only easy path to old tip.
For shared branches, use branch protection. For private PR branches, use --force-with-lease and communicate.
19. origin/main Staleness Trap
This is a classic bug:
git rebase origin/main
But you forgot:
git fetch origin
So you rebased onto an old snapshot.
Safe pattern:
git fetch origin
git rebase origin/main
Or:
git fetch origin main
git rebase FETCH_HEAD
For critical operations, inspect the timestamp:
git log -1 --format='%h %ci %s' origin/main
Remember:
origin/main is not live remote/main.
origin/main is your last fetched view of remote/main.
20. FETCH_HEAD: Temporary Fetch Result
After fetch, Git writes .git/FETCH_HEAD describing fetched refs.
Example:
git fetch origin main
cat .git/FETCH_HEAD
You can merge it directly:
git merge FETCH_HEAD
But for human workflow, remote-tracking branch names are usually clearer:
git merge origin/main
FETCH_HEAD is useful when fetching an explicit ref that is not mapped to a remote-tracking branch, such as PR refs:
git fetch origin pull/123/head
git switch -c review/pr-123 FETCH_HEAD
Platform-specific example for GitHub PR refs:
git fetch origin refs/pull/123/head:refs/heads/review/pr-123
Do not assume all hosting platforms expose the same PR/MR ref namespace.
21. Refspec for Pull Request / Merge Request Review
Some platforms expose review refs outside refs/heads/*.
Examples:
refs/pull/<id>/head
refs/pull/<id>/merge
refs/merge-requests/<id>/head
These are not fetched by default because default refspec usually fetches only refs/heads/*.
Manual fetch example:
git fetch origin refs/pull/123/head:refs/heads/review/pr-123
Now inspect locally:
git switch review/pr-123
git log --oneline --decorate --graph --max-count=20
For CI, be explicit whether you build:
| Ref | Meaning |
|---|---|
| PR head | Contributor branch as submitted. |
| PR merge ref | Synthetic merge result with target branch. |
| Target branch | Base branch without PR changes. |
Building the wrong ref can hide integration failures.
22. Mirror and Bare Repository Semantics
Bare repository has no working tree and is often used as server or mirror:
git clone --bare git@github.com:acme/payments.git payments.git
Mirror clone:
git clone --mirror git@github.com:acme/payments.git payments.git
Mirror is stronger than normal clone. It maps all refs and configures mirror fetch/push behavior.
Mirror push:
git push --mirror target
Danger:
--mirrorcan create, update, and delete refs on the target to match source.
Use only in controlled replication jobs, never as casual developer workflow.
For disaster recovery mirror:
- make mirror read-only for developers;
- monitor ref divergence;
- log mirror updates;
- do not use mirror as accidental source-of-truth unless failover is declared.
23. Local Branch Name Does Not Have to Match Remote Branch Name
A local branch can track a remote branch with a different name.
Example:
git switch -c my-fix origin/release/2026.07
git branch --set-upstream-to=origin/release/2026.07 my-fix
Now:
my-fix tracks origin/release/2026.07
This is valid but can be confusing.
Push behavior depends on config. With push.default=simple, Git may reject if upstream branch name differs from local branch name.
In production workflows, matching names reduce cognitive load:
local: release/2026.07
remote: origin/release/2026.07
For temporary branches, different names are fine if push is explicit:
git push origin my-fix:refs/heads/users/alice/release-fix
24. Branch Naming as Operational Metadata
Branch names are refs. They become visible in PRs, CI logs, deployments, and incident timelines.
Good branch names encode intent:
feature/refund-audit-event
fix/idempotency-key-race
hotfix/2026-07-payment-timeout
release/2026.07
backport/2.4/refund-audit
experiment/sparse-index-benchmark
Weak names:
fix
changes
new
alice2
final
prod
Branch naming policy should answer:
| Prefix | Meaning |
|---|---|
feature/ | Normal feature branch. |
fix/ | Bug fix not necessarily emergency. |
hotfix/ | Production emergency fix. |
release/ | Stabilization or release branch. |
backport/ | Applying selected fix to older line. |
experiment/ | Not intended to merge as-is. |
users/<name>/ | Personal remote branch namespace. |
Do not over-engineer names, but do make them operationally useful.
25. Safe Push Checklist
Before pushing to shared branch:
git status -sb
git branch -vv
git log --oneline --decorate --graph @{u}..HEAD
git log --oneline --decorate --graph HEAD..@{u}
Then push explicitly:
git push origin HEAD:refs/heads/feature/refund
For force update on private branch:
git fetch origin
git push --force-with-lease origin HEAD:refs/heads/feature/refund
Never force-push shared release/main branches unless incident commander and repository policy explicitly require it.
26. Safe Fetch Checklist
Fetch is generally safe, but it changes your view of remote state.
Before high-risk recovery:
git branch backup/current-$(date +%Y%m%d-%H%M%S)
git for-each-ref --format='%(refname) %(objectname)' refs/remotes/origin > /tmp/origin-refs-before.txt
Fetch:
git fetch origin --prune
After fetch:
git for-each-ref --format='%(refname) %(objectname)' refs/remotes/origin > /tmp/origin-refs-after.txt
diff -u /tmp/origin-refs-before.txt /tmp/origin-refs-after.txt || true
This matters during incidents where remote refs may have been force-updated.
27. Common Failure Modes
27.1 Assuming origin/main Is Fresh
Symptom:
git rebase origin/main
But origin/main is days old.
Fix:
git fetch origin
git rebase origin/main
Prevention:
git log -1 --format='%h %ci %s' origin/main
27.2 Pushing to Wrong Remote
Symptom:
git push origin main
But origin points to personal fork, not canonical remote—or worse, to production mirror.
Fix:
git remote -v
git remote get-url origin
Prevention:
- use explicit remote names;
- protect critical branches;
- require PR for canonical repo;
- avoid ambiguous automation based on
origin.
27.3 Local Branch Tracks Unexpected Upstream
Symptom:
git status
shows ahead/behind relative to unexpected branch.
Inspect:
git branch -vv
git config --get branch.$(git branch --show-current).remote
git config --get branch.$(git branch --show-current).merge
Fix:
git branch --set-upstream-to=origin/feature/refund
Or unset:
git branch --unset-upstream
27.4 Deleting Remote Branch But Not Local Branch
Symptom:
Remote branch deleted after merge, but local branch remains and developer keeps committing.
Fix:
git fetch origin --prune
git branch -vv
git branch --merged main
git branch -d feature/refund
Prevention:
- cleanup branch after merge;
- use branch deletion automation;
- keep PR branch lifecycle visible.
27.5 Fetching PR Head Without Target Integration
Symptom:
CI passes PR head but merge to target fails.
Fix:
Build synthetic merge result or explicitly merge target branch in CI:
git fetch origin main
git fetch origin refs/pull/123/head:refs/heads/pr-123
git switch pr-123
git merge --no-commit --no-ff origin/main
Better: use platform-provided merge queue or merge ref if available.
28. Operational Invariants
Keep these invariants:
- Remote name is local config, not authority by itself. Validate URL for critical operations.
- Remote-tracking refs are snapshots. Fetch before using them as current truth.
- Upstream controls default pull/push context. Inspect
git branch -vv. - Refspec is the real mapping. Use explicit refspec for critical push/fetch.
- Fetch observes; pull integrates. Teach them separately.
- Release tags are identity refs. Push them explicitly and treat them as immutable after publication.
- Mirrors are dangerous.
--mirroris automation-grade, not casual user-grade. - Force update needs lease and protocol. Never rely on raw
--forcefor team branches.
29. Practical Lab: Build a Remote Mental Model
Create local playground:
mkdir /tmp/git-remote-lab
cd /tmp/git-remote-lab
git init --bare server.git
git clone server.git alice
git clone server.git bob
Alice creates main:
cd /tmp/git-remote-lab/alice
git switch -c main
echo 'v1' > app.txt
git add app.txt
git commit -m 'Initial app'
git push -u origin main
Bob fetches:
cd /tmp/git-remote-lab/bob
git fetch origin
git branch -r
git switch --track origin/main
Inspect refs:
git show-ref
git branch -vv
git config --get-all remote.origin.fetch
Alice creates feature:
cd /tmp/git-remote-lab/alice
git switch -c feature/refund
echo 'refund' >> app.txt
git commit -am 'Add refund line'
git push -u origin HEAD
Bob observes:
cd /tmp/git-remote-lab/bob
git branch -r
# feature branch may not appear yet
git fetch origin
git branch -r
git log --oneline --decorate --graph --all
Delete remote branch:
cd /tmp/git-remote-lab/alice
git push origin --delete feature/refund
Bob sees stale then prunes:
cd /tmp/git-remote-lab/bob
git branch -r
git fetch origin --prune
git branch -r
Learning point:
Remote state does not teleport into local refs. Fetch updates your local view according to refspec.
30. Engineering Checklist
Use this before changing remote configuration or pushing critical refs:
# identity
git remote -v
git remote get-url origin
# branch/upstream
git status -sb
git branch -vv
# ref mapping
git config --get-all remote.origin.fetch
git config --get push.default
# graph relationship
git fetch origin
git rev-list --left-right --count HEAD...@{u}
# outgoing changes
git log --oneline --decorate @{u}..HEAD
# incoming changes
git log --oneline --decorate HEAD..@{u}
For protected branches, push through PR/merge queue. For private branches, push explicitly. For release tags, push exact tag ref.
31. Summary
Remote Git is ref synchronization plus object transfer. The key entities are not “upload” and “download”; they are refs and mappings.
The core mental model:
remote repository has refs
local repository has refs
fetch maps remote refs into local remote-tracking refs
push maps local refs into remote refs
upstream config tells Git which remote branch a local branch relates to
Once this clicks, common Git mysteries become mechanical:
origin/mainstale? You have not fetched.git pushgoes to wrong place? Upstream or push.default is not what you think.- branch deleted remotely but still visible? You have not pruned.
- PR branch differs from target? You are comparing different refs.
- release tag moved? A supposedly stable ref was mutated.
The professional move is explicitness. Inspect refs. Inspect upstream. Use explicit refspecs for critical operations. Treat remote names as local configuration, not as authority.
References
- Git Documentation —
git remote: https://git-scm.com/docs/git-remote - Git Documentation —
git fetch: https://git-scm.com/docs/git-fetch - Git Documentation —
git push: https://git-scm.com/docs/git-push - Git Documentation —
git branch: https://git-scm.com/docs/git-branch - Git Documentation —
git config: https://git-scm.com/docs/git-config - Pro Git — Git Branching, Remote Branches: https://git-scm.com/book/en/v2/Git-Branching-Remote-Branches
- Pro Git — Git Internals, The Refspec: https://git-scm.com/book/en/v2/Git-Internals-The-Refspec
You just completed lesson 35 in build core. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.
Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.