Before this:Branches explainedWhat is GitHub?
Remotes: clone, fetch, pull & push
Key takeaways
A remote is a named link to a repository hosted elsewhere; the default one is
called origin. git clone copies a remote down to start; git push
uploads your commits; and the pair people confuse most — git fetch only
downloads commits, while git pull fetches then merges into your branch.
Git tracks the remote’s state in remote-tracking branches like origin/main.
The first time you push a new branch, use git push -u origin <branch> to set
its upstream. Prefer git pull --rebase for a tidy history, and delete remote
branches with git push origin --delete <branch>.
You met the idea of a remote in the last lesson: a copy of your repository living on a server. This lesson is the practical half — the commands that move commits between your machine and that server. These four verbs (clone, fetch, pull, push) are the daily vocabulary of working with GitHub.
What a remote is, and the origin convention
A remote is simply a named bookmark for a repository URL. List your remotes with
git remote -v (the -v means verbose, showing the URLs):
$ git remote -v
origin git@github.com:alice/myproject.git (fetch)
origin git@github.com:alice/myproject.git (push)
By convention the remote you cloned from is named origin. There’s nothing
magic about the name — it’s just the default Git picks. You can add more remotes by
hand with git remote add <name> <url>:
$ git remote add backup git@gitlab.com:alice/myproject.git
$ git remote -v
backup git@gitlab.com:alice/myproject.git (fetch)
backup git@gitlab.com:alice/myproject.git (push)
origin git@github.com:alice/myproject.git (fetch)
origin git@github.com:alice/myproject.git (push)
Most projects have just origin. A second remote called upstream is common when
you’re forking someone else’s project — more on that later.
Clone: starting from a remote
To get a local copy of a repository that already exists on GitHub, clone it.
Cloning downloads the full history and automatically sets up origin for you:
$ git clone git@github.com:alice/myproject.git
Cloning into 'myproject'...
remote: Enumerating objects: 412, done.
remote: Total 412 (delta 0), reused 412 (delta 0), pack-reused 0
Receiving objects: 100% (412/412), 1.83 MiB | 4.10 MiB/s, done.
Resolving deltas: 100% (210/210), done.
You now have a directory myproject/ with the entire project and its history, an
origin remote pointing back at GitHub, and a local main already tracking
origin/main. From here, the other three verbs keep the two copies in sync.
Fetch vs pull vs push — the crucial distinction
This is the part worth slowing down for. The three commands move data in different directions and do different amounts of work.
| Command | Direction | What it does |
|---|---|---|
git fetch |
remote → you | Downloads new commits, but does not change your branch or files |
git pull |
remote → you | Runs fetch, then merges (or rebases) into your current branch |
git push |
you → remote | Uploads your local commits to the remote |
Fetch is the cautious move. It updates your knowledge of the remote without disturbing your work:
$ git fetch origin
remote: Enumerating objects: 8, done.
From github.com:alice/myproject
a1b2c3d..e4f5a6b main -> origin/main
Notice it updated origin/main, not your main. You can now inspect what changed
before integrating it.
Pull does the fetch and the merge in one go:
$ git pull
Updating a1b2c3d..e4f5a6b
Fast-forward
README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Push sends your commits the other way:
$ git push
Enumerating objects: 5, done.
To github.com:alice/myproject.git
e4f5a6b..c7d8e9f main -> main
Rule of thumb: fetch to look, pull to look-and-integrate, push to share.
Remote-tracking branches vs local branches
When you fetch, Git stores the remote’s state in remote-tracking branches —
read-only pointers named like origin/main. These are Git’s local cache of “where
the remote was last time we talked to it.” They are distinct from your own main:
main ← your local branch (you commit here)
origin/main ← remote-tracking branch (updated by fetch/pull)
You never commit directly to origin/main; it moves only when you fetch or pull.
This separation is what lets you compare your work against the server’s:
$ git log main..origin/main # commits on the remote you don't have yet
$ git log origin/main..main # commits you have that aren't pushed yet
Setting upstream and pulling with rebase
The first time you push a new branch, tell Git which remote branch it should
track using -u (short for --set-upstream):
$ git switch -c feature/login
$ git push -u origin feature/login
...
branch 'feature/login' set up to track 'origin/feature/login'.
After that, plain git push and git pull work with no arguments because Git
knows the pairing. You only need -u once per branch.
When you pull, the default is to merge the remote commits, which can create extra
“merge” commits. Many people prefer git pull --rebase, which replays your
local commits on top of the fetched ones for a straight-line history (you’ll learn
the mechanics in rebasing):
$ git pull --rebase
Successfully rebased and updated refs/heads/main.
You can make rebase the default with git config --global pull.rebase true.
Deleting remote branches and multiple remotes
Once a feature branch is merged, tidy up the remote copy with --delete:
$ git push origin --delete feature/login
To github.com:alice/myproject.git
- [deleted] feature/login
That removes the branch on the server only; delete your local copy separately with
git branch -d feature/login.
Finally, remember that a repo can have multiple remotes. The classic case is
contributing to a project you don’t own: you fork it, clone your fork as origin,
and add the original project as a second remote called upstream so you can pull
in its updates. That whole pattern is the subject of the next lesson.
Quick check: you want to see what's new on the remote without changing your current branch. Which command?
Recap
- A remote is a named link to a hosted repo; the default is
origin. git clonecopies a remote down and sets uporiginautomatically.git fetchdownloads only;git pullfetches and integrates;git pushuploads.- Remote-tracking branches like
origin/mainare Git’s cache of the remote’s state. - Use
git push -u origin <branch>the first time; prefergit pull --rebasefor tidy history. - Delete a remote branch with
git push origin --delete <branch>; add extra remotes for forks.
Next up: keeping things secure with SSH keys and tokens.
Frequently asked questions
What is the difference between git fetch and git pull?
git fetch only downloads new commits from the remote into your remote-tracking branches (like origin/main); it does not touch your working files or current branch. git pull does a fetch and then immediately merges (or rebases) those commits into your current branch. Fetch is the safe, look-before-you-leap option; pull is fetch plus integrate in one step.
What does origin mean in Git?
origin is just the default name Git gives to the remote you cloned from. It is a convention, not a keyword — you could rename it or add remotes with other names. When you run git clone, Git automatically creates a remote called origin pointing at the URL you cloned, which is why so many commands mention origin.
What does git push -u origin main do?
It pushes your main branch to the remote called origin and, thanks to -u (short for –set-upstream), records that your local main should track origin/main. After that, you can simply run git push and git pull with no arguments because Git knows which remote branch they correspond to. You only need -u the first time you push a new branch.
How do I delete a branch on the remote?
Run git push origin –delete