Git & GitHub · lesson 5 of 12
Remotes: Fetch, Pull, Push, and Tracking Branches
Push to a real shared remote, have a second clone push a commit, then fetch and pull to see exactly what a tracking branch reports before and after merging.
By SkillByExample · Published
A remote is just another repository Git knows a URL for. This lesson uses a real
second clone to simulate a colleague, so fetch and pull have something genuine to
retrieve.
1) Register a remote and push with tracking
$ git remote add origin ../origin.git
$ git push -u origin main
branch 'main' set up to track 'origin/main'.
To ../origin.git
* [new branch] main -> main
-u does two things at once: pushes main, and records that local main tracks
origin/main — the link that later lets plain git status, fetch, and pull work
without spelling out remote and branch names.
2) A colleague clones and pushes their own commit
$ git clone origin.git colleague && cd colleague
$ # ...append version() to app.py...
$ git commit -am "Add version() helper"
$ git push origin main
$ git log --oneline -1
6d0fc2d Add version() helper
This is a second, independent clone of the same remote — a stand-in for a teammate’s
machine. Its push updates the shared origin.git, but the original demo clone
doesn’t know yet.
3) Fetch downloads without touching your branch
$ # ...back in the original demo clone...
$ git fetch origin
$ git status
From ../origin
c489307..6d0fc2d main -> origin/main
On branch main
Your branch is behind 'origin/main' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
nothing to commit, working tree clean
git fetch updated the remote-tracking ref origin/main to 6d0fc2d, but local
main and the working directory are untouched — git status compares the two refs
and reports the gap without merging anything.
4) Pull merges the fetched commit in
$ git pull
$ git log --oneline -2
Updating c489307..6d0fc2d
Fast-forward
app.py | 4 ++++
1 file changed, 4 insertions(+)
6d0fc2d Add version() helper
c489307 Urgent: add farewell test
git pull is git fetch followed by git merge origin/main (or rebase, if
configured). Because local main hadn’t diverged from origin/main, the merge is
another fast-forward — the same mechanism from the branching lesson, just against a
remote-tracking branch instead of a local one.
Practice
-
Run
git branch -vvafter the pull above to see which local branches track which remote branches, and whether they’re ahead/behind.Solution
* main 6d0fc2d [origin/main] Add version() helper[origin/main]with noahead/behindannotation means the two are in sync. -
Make a commit in
demoand have the colleague clone push a different commit, so the two diverge. Rungit pulland observe it now performs a real merge (or refuses, depending on your pull strategy config) instead of a fast-forward. -
Run
git fetch originthen inspectorigin/maindirectly withgit log origin/main --oneline -1before pulling, to confirm you can see incoming history without merging it. -
Push a new branch (not
main) withgit push -u origin feature/x, then in the colleague clone rungit fetchandgit checkout feature/xto confirm a fetch makes remote branches checkoutable locally. -
Run
git remote show originand read its summary of local branches, their tracked remote counterparts, and whether each is up to date.