Git 2b 🧩 Connecting Local to Remote
A local Git repository works fine on its own — until you want to share it, back it up, or collaborate. That’s when you connect it to a remote. The link is set up once, and after that, push and pull keep the two in sync.
This chapter covers the commands that establish that connection and move data between the two.
Commands
Five commands handle almost everything: git remote add, git push, git pull, git clone, and git remote -v.
git remote add origin [URL]
Links your local repository to a remote repository. The name origin is a convention — it’s the default name for the primary remote, but you can use any name.
git remote add origin https://github.com/username/repository.git
This doesn’t copy anything yet — it just records the URL. From now on, origin refers to that remote.
Why “origin”? It’s just a label. Git doesn’t require it — but every tutorial and tool assumes it, so using
originfor your primary remote keeps things predictable.
git push
Uploads your committed changes from the local repository to the remote.
Basic form:
git push origin main
This pushes the current branch’s commits to the main branch on origin. If the remote branch doesn’t exist, it’s created.
Setting upstream with -u:
git push -u origin main
The -u flag sets the upstream branch — the default remote and branch for the current local branch. After this, you can just run:
git push
git pull
without specifying origin main. Git remembers the link.
Why upstream matters: Without it, Git doesn’t know where to push. With it,
git pushandgit pullbecome one-word commands. Set upstream once per branch and never worry about it again.
git pull
Downloads changes from the remote and merges them into your current local branch. It’s git fetch followed by git merge.
git pull origin main
Or, with upstream set:
git pull
If both you and a teammate have committed since your last pull, Git will attempt to merge their changes into yours. If they touched the same lines, you’ll get a merge conflict to resolve.
git clone [URL]
Copies an entire remote repository — all branches, all history — to your local machine. This is how you start working on an existing project.
git clone https://github.com/username/repository.git
The result is a new folder named after the repository, with a configured origin remote already pointing back to the URL you cloned from.
Clone vs init:
git initcreates a fresh, empty repository.git clonecopies an existing one. If the project already exists on a remote, clone. If you’re starting from scratch, init.
git remote -v
Lists the configured remotes for the current repository, with their URLs.
git remote -v
Output looks like:
origin https://github.com/username/repo.git (fetch)
origin https://github.com/username/repo.git (push)
The (fetch) and (push) lines tell you the URL used for each direction — they’re usually the same, but can differ.
Example: Connecting Local Repository to Remote
A complete walkthrough — from empty directory to synced with remote.
Step 1: Initialize a new local repository
mkdir my-new-project
cd my-new-project
git init
You now have an empty repository with a .git folder.
Step 2: Create and commit initial files
echo "# My New Project" > README.md
git add .
git commit -m "Initial commit"
One commit lives in the local repository.
Step 3: Link to a remote repository
git remote add origin https://github.com/username/my-new-project.git
The remote is configured. Nothing has been uploaded yet — the local and remote are linked but not synced.
Step 4: Push changes to the remote
git push -u origin master
The -u sets upstream. If the remote was empty, the branch is created there. If the remote had commits, you’d need to pull first.
Note on
mastervsmain: Older repos usemaster; modern ones usemain. Match whatever branch name your remote expects.
Step 5: Clone an existing remote repository
git clone https://github.com/username/my-existing-project.git
cd my-existing-project
Now you have a full copy — all branches, all history, and the origin remote pre-configured.
Step 6: Pull changes from the remote
git pull origin master
Or, since clone sets upstream automatically:
git pull
This downloads any new commits from teammates and merges them into your current branch.
Step 7: View configured remotes
git remote -v
Confirms what’s configured — typically origin pointing at your fork or the upstream repository.
Complete Example Session
# ============================================
# PART 1: START FROM SCRATCH
# ============================================
mkdir my-new-project
cd my-new-project
git init
# [ Initialized empty Git repository ... ]
# ============================================
# PART 2: INITIAL COMMIT
# ============================================
echo "# My New Project" > README.md
git add .
git commit -m "Initial commit"
# [ [main (root-commit) a1b2c3d] Initial commit ]
# ============================================
# PART 3: LINK TO REMOTE
# ============================================
git remote add origin https://github.com/username/my-new-project.git
# ============================================
# PART 4: PUSH AND SET UPSTREAM
# ============================================
git push -u origin main
# [ Enumerating objects: 3, done. ]
# [ Counting objects: 100% (3/3), done. ]
# [ Writing objects: 100% (3/3), 234 bytes | 234.00 KiB/s, done. ]
# [ Total 3 (delta 0), reused 0 (delta 0), pack-reused 0 ]
# [ To https://github.com/username/my-new-project.git ]
# [ * [new branch] main -> main ]
# [ branch 'main' set up to track 'origin/main'. ]
# ============================================
# PART 5: SUBSEQUENT PUSHES
# ============================================
echo "more content" >> README.md
git add .
git commit -m "Add more content"
git push
# [ 1 file changed, 1 insertion(+) ]
# [ To https://github.com/username/my-new-project.git ]
# [ a1b2c3d..e4f5g6h main -> main ]
# ============================================
# PART 6: CLONE AN EXISTING REPO
# ============================================
cd ..
git clone https://github.com/username/my-existing-project.git
cd my-existing-project
# [ Cloning into 'my-existing-project'... ]
# [ remote: Enumerating objects: 42, done. ]
# [ remote: Total 42 (delta 0), reused 0 (delta 0) ]
# [ Receiving objects: 100% (42/42), done. ]
# ============================================
# PART 7: PULL LATEST CHANGES
# ============================================
git pull
# [ Already up to date. ]
# ============================================
# PART 8: VIEW REMOTES
# ============================================
git remote -v
# [ origin https://github.com/username/my-existing-project.git (fetch) ]
# [ origin https://github.com/username/my-existing-project.git (push) ]
# ============================================
# PART 9: ADD A SECOND REMOTE
# ============================================
git remote add upstream https://github.com/original-owner/my-existing-project.git
git remote -v
# [ origin https://github.com/username/my-existing-project.git (fetch) ]
# [ origin https://github.com/username/my-existing-project.git (push) ]
# [ upstream https://github.com/original-owner/my-existing-project.git (fetch) ]
# [ upstream https://github.com/original-owner/my-existing-project.git (push) ]
# ============================================
# PART 10: FETCH FROM UPSTREAM
# ============================================
git fetch upstream
# [ remote: Enumerating objects: 5, done. ]
# [ Unpacking objects: 100% (5/5), done. ]
# [ From https://github.com/original-owner/my-existing-project ]
# [ * [new branch] main -> upstream/main ]
Quick Reference
Core Commands
| Command | Purpose |
|---|---|
git remote add NAME URL | Link to a remote |
git push origin BRANCH | Push commits |
git push -u origin BRANCH | Push and set upstream |
git pull origin BRANCH | Fetch and merge |
git pull | Pull from upstream |
git clone URL | Full copy of a remote |
git remote -v | List remotes |
Push and Pull Forms
| Form | Behavior |
|---|---|
git push | Push to tracked upstream |
git push origin main | Push to specific remote/branch |
git push -u origin main | Push and set upstream |
git pull | Pull from tracked upstream |
git pull origin main | Pull from specific remote/branch |
Remote Management
| Command | Purpose |
|---|---|
git remote | List remote names |
git remote -v | List with URLs |
git remote add NAME URL | Add a remote |
git remote remove NAME | Remove a remote |
git remote rename OLD NEW | Rename a remote |
git remote set-url NAME URL | Change a remote’s URL |
Push vs Pull vs Fetch
| Command | Direction | Merges? |
|---|---|---|
git push | Local → Remote | N/A |
git pull | Remote → Local | ✅ |
git fetch | Remote → Local | ❌ |
Remote Naming
| Name | Purpose |
|---|---|
origin | Your primary remote (clone source or fork) |
upstream | The original repo you forked from |
NAME | Any label — backup, staging, etc. |
Best Practices
✅ Do This:
# Set upstream on the first push
git push -u origin main # ✅
# Pull before starting work
git pull # ✅
# Use HTTPS or SSH consistently
git remote add origin git@github.com:u/r.git # ✅ SSH
git remote add origin https://github.com/u/r.git # ✅ HTTPS
# Check remotes when in doubt
git remote -v # ✅
# Use upstream for forks
git remote add upstream https://github.com/original/repo.git # ✅
# Fetch before pulling on busy branches
git fetch && git status # ✅
❌ Don’t Do This:
# Don't push without setting upstream and then expect plain `git push` to work
git push origin main # ⚠️ works, but plain `git push` won't
# Don't force-push to shared branches
git push --force # ❌ destroys teammates' work
# Don't push secrets
git push # ⚠️ check what you're committing
# Don't ignore "rejected" push messages
git push # ❌ means you're behind — pull first
# Don't use `origin` for everything when you have multiple remotes
git remote add origin https://... # ⚠️ name them meaningfully
# Don't switch between HTTPS and SSH mid-project
git remote set-url origin git@... # ⚠️ pick one
Common Pitfalls
| Pitfall | Problem | Solution |
|---|---|---|
| Push rejected | Remote has newer commits | git pull then push |
Forgot -u | git push doesn’t work | Set upstream once |
| Pull creates merge commit | Diverged branches | Use git pull --rebase |
| Wrong branch pushed | Pushed to main by accident | Check branch before push |
| HTTPS asks for password | No credential helper | Configure git config credential.helper |
| SSH key not loaded | Auth fails | ssh-add ~/.ssh/id_ed25519 |
| Remote URL wrong | Push fails | git remote set-url |
| Clone vs init confusion | Wrong starting point | Clone existing, init new |
Real-World Examples
1. Link to a remote
git remote add origin https://github.com/user/repo.git
Records the remote URL.
2. First push
git push -u origin main
Uploads commits and sets upstream.
3. Subsequent push
git push
Uses the tracked upstream.
4. Pull from upstream
git pull
Fetches and merges.
5. Pull from a specific branch
git pull origin develop
Overrides tracking.
6. Clone a repository
git clone https://github.com/user/repo.git
Full copy.
7. View remotes
git remote -v
Shows URLs.
8. Add upstream (for forks)
git remote add upstream https://github.com/original/repo.git
Tracks the original.
9. Fetch without merging
git fetch origin
Downloads only.
10. Change a remote URL
git remote set-url origin git@github.com:user/repo.git
Switches to SSH.
Visual: Connecting Local to Remote
┌──────────────────────────────────────────────┐
│ Your Machine │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ Local Repository │ │
│ │ (.git) │ │
│ └────────────┬─────────────────────────┘ │
│ │ │
│ │ git remote add origin URL │
│ │ git push -u origin main │
│ ▼ │
└───────────────┼──────────────────────────────┘
│
▼
┌──────────────────────────────────────────────┐
│ Remote Repository │
│ │
│ origin/main │
│ ├── commit A │
│ ├── commit B │
│ └── commit C │
│ │
└──────────────────────────────────────────────┘
Visual: Push, Pull, Fetch
┌──────────────────────────────────────────────┐
│ Push — Upload │
│ │
│ Local ──────► Remote │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Pull — Download and merge │
│ │
│ Remote ──────► Local │
│ (fetch + merge) │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ Fetch — Download only │
│ │
│ Remote ──────► Local (staged, not merged) │
│ │
└──────────────────────────────────────────────┘
Visual: Upstream Tracking
┌──────────────────────────────────────────────┐
│ Without -u │
│ │
│ local main ──── no link │
│ │
│ git push → error: no upstream │
│ git push origin main → works │
│ │
└──────────────────────────────────────────────┘
┌──────────────────────────────────────────────┐
│ With -u │
│ │
│ local main ────────► origin/main │
│ │
│ git push → works │
│ git pull → works │
│ │
└──────────────────────────────────────────────┘
Visual: Multiple Remotes
┌──────────────────────────────────────────────┐
│ origin → your fork │
│ upstream → original repo │
│ │
│ Fetch from upstream: git fetch upstream │
│ Push to origin: git push origin main │
│ │
│ Typical for open-source contributions │
│ │
└──────────────────────────────────────────────┘
Summary
| Command | Purpose |
|---|---|
git remote add origin URL | Link to remote |
git push origin BRANCH | Push to remote |
git push -u origin BRANCH | Push + set upstream |
git pull origin BRANCH | Fetch + merge |
git pull | Pull from upstream |
git clone URL | Full copy |
git remote -v | List remotes |
git fetch origin | Download only |
Key takeaways:
git remote addlinks a local repository to a remote — it doesn’t copy anything yetoriginis the conventional name for the primary remotegit pushuploads commits;git pulldownloads and merges-uon the first push sets the upstream — after that,git pushandgit pullwork without argumentsgit clonecreates a full local copy of a remote repo, withoriginalready configuredgit remote -vshows what remotes are configured and where they pointgit fetchdownloads without merging — safer than pull when you want to inspect first- Use
upstreamas a second remote when working from a fork - Never force-push shared branches
- If a push is rejected, pull first, then push
Remember: Connecting local to remote is a one-time setup. After git remote add and the first git push -u, the two are linked — push sends your work up, pull brings others’ work down. Clone when starting from an existing project; init and remote-add when starting fresh. Keep origin for your fork, upstream for the original, and let upstream tracking handle the rest.
Stop using slow, ad-bloated tool sites! 🤮
🔎 Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
✅ Finance (Mortgage, Interest, Inflation)
✅ Tech (Base64, JSON, Dev Suite, IP)
✅ Health (BMI, BMR, TDEE)
✅ Productivity (Timer, Workspace, QR)
⚡️ Fast & Private
🔒 No data leaves your device
💎 100% Free
🔗 Use it now: https://tools.kandz.me
🔖 Bookmark it—you’ll need it later!