05 - Remote Collaboration
#05 - Remote Collaboration
##What is a Remote Repository?
So far your Git history has lived only on your own computer. A remote repositoryis a copy of your repository hosted on a server (GitHub, GitLab, Bitbucket, etc.). It serves two purposes:
- Backup: Your work is safe even if your laptop dies
- Collaboration: Your teammates can see your commits and you can see theirs
1
2
3
4
5
Your Laptop GitHub / GitLab
(local repo) (remote repo)
git push
git pull
##GitHub vs GitLab
You will encounter both at work. The Git commands are identical — only the web interface differs.
| GitHub | GitLab | |
|---|---|---|
| Owned by | Microsoft | GitLab Inc. |
| Best known for | Open source projects | Enterprise / self-hosted |
| CI/CD | GitHub Actions | GitLab CI (built-in, very popular) |
| Free private repos | Yes | Yes |
| Self-hosting option | GitHub Enterprise (paid) | GitLab Community Edition (free) |
| Pull Requests called | “Pull Requests” (PR) | “Merge Requests” (MR) |
For this course: We use GitHub. When you join a company, they may use GitLab — the workflow is the same.
##SSH vs HTTPS: Two Ways to Authenticate
When you push or pull, GitHub/GitLab needs to verify you are allowed to access the repository. There are two methods:
###HTTPS
The URL looks like: https://github.com/username/repo.git
- Uses your username + personal access token (not your password)
- Simpler to set up initially
- Prompts for credentials on each push (unless you use a credential manager)
- Works everywhere, including corporate firewalls
###SSH (Recommended)
The URL looks like: [email protected]:username/repo.git
- Uses a cryptographic key pair stored on your machine
- No password prompts after setup
- Faster and more convenient for daily use
Set up SSH once:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#Step 1: Generate your key pair
ssh-keygen -t ed25519 -C "[email protected]"
#Press Enter to accept the default file location
#Add a passphrase or press Enter for none
#Step 2: Show your public key
cat ~/.ssh/id_ed25519.pub
#Copy the entire output — it starts with "ssh-ed25519 ..."
#Step 3: Add it to GitHub
# github.com Settings SSH and GPG keys New SSH key
# Paste your public key Save
#Step 4: Test the connection
ssh -T [email protected]
Expected:
1
Hi priya! You've successfully authenticated, but GitHub does not provide shell access.
You are now connected. Every future push/pull happens silently without asking for credentials.
##Connecting Your Local Repo to GitHub
Create an empty repository on GitHub (do NOT tick “Add README” — your local repo already has content).
Then in your terminal:
1
git remote add origin [email protected]:your-username/my-project.git
Verify it was added:
1
git remote -v
Expected:
1
2
origin [email protected]:your-username/my-project.git (fetch)
origin [email protected]:your-username/my-project.git (push)
origin is just a name — it is the conventional name for your primary remote. You can have multiple remotes with different names.
##Your First Push and Upstream Tracking
1
git push -u origin main
Expected:
1
2
3
4
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Writing objects: 100% (5/5), 452 bytes | 452.00 KiB/s, done.
Branch 'main' set up to track remote branch 'main' from 'origin'.
The -u flag does something important: it sets up upstream tracking. This links your local main branch to origin/main. After this, you can just type git push or git pull — Git knows where to push/pull without you specifying.
Verify tracking is set up:
1
git branch -vv
Expected:
1
* main a1b2c3d [origin/main] Your last commit message
The [origin/main] tells you this local branch is tracking that remote branch.
##Fetch vs Pull: A Critical Distinction
This trips up many beginners. Here is the definitive explanation.
###git fetch
Downloads new commits and branches from the remote but does NOT touch your working directory or current branch. It is completely safe — it only updates Git’s internal knowledge of what the remote looks like.
1
git fetch
Expected (if your teammate pushed new commits):
1
2
3
remote: Enumerating objects: 3, done.
From github.com:your-username/my-project
a1b2c3d..f4e5d6c main -> origin/main
Your files are unchanged. But now you can inspect what changed:
1
git diff main..origin/main
This shows you what is on the remote that you do not have locally. Only after reviewing do you decide to merge:
1
2
git merge origin/main
#or equivalently: git pull
###git pull
Downloads AND immediately merges into your current branch. It is git fetch + git merge in one step.
1
git pull
###Which should you use?
1
2
New to Git or working on a shared branch? git fetch, then review, then pull
In a hurry or working alone? git pull is fine
The safe habit:```bash git fetch git diff main..origin/main #See what changed git pull #Then merge when ready
1
2
3
4
5
6
7
8
9
---
##Remote Tracking Branches
When you fetch, Git stores what it downloaded as **remote tracking branches**. These are read-only references that show you what the remote looked like at last fetch.
```bash
git branch -a
Expected:
1
2
3
* main
remotes/origin/main
remotes/origin/feature-login
main— your local branchremotes/origin/main— a snapshot of whatmainlooked like on the remote last time you fetched
Remote tracking branches update every time you run git fetch or git pull.
##Simulating Team Collaboration
Let’s simulate a teammate pushing a commit while you are working.
Step 1: Make a change via the GitHub web interface (click a file edit commit directly to main). This simulates your teammate pushing a change.
Step 2: Back in your terminal, check for updates:
1
2
git fetch
git log --oneline main..origin/main
Expected: Shows your teammate’s commit — a commit that is on the remote but not yet on your local main.
Step 3: See what they actually changed:
1
git diff main..origin/main
Step 4: Bring the change in:
1
2
git pull
git log --oneline
Expected: The teammate’s commit is now in your local history.
##Handling Divergent Branches
A divergent branchmeans both you and the remote have new commits that the other does not have. This happens when two people commit around the same time.
1
2
Remote: A B C D (D is a teammate's commit)
Local: A B C E (E is your commit)
When you try to pull, Git will warn:
1
hint: You have divergent branches and need to specify how to reconcile them.
Option A: Merge (safe for beginners)
1
git pull --no-rebase
Git creates a merge commit that ties both histories together. History shows the fork and the merge point.
Option B: Rebase (cleaner history)
1
git pull --rebase
Git replays your commits on top of the remote’s commits, creating a linear history. More on rebase in Module 10.
Set your preference:
1
2
git config --global pull.rebase false #always merge (recommended for beginners)
git config --global pull.rebase true #always rebase
##Push Rejected: What It Means and How to Fix It
You try to push and see:
1
2
3
4
! [rejected] main -> main (fetch first)
error: failed to push some refs to '[email protected]:...'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. Integrate the remote changes before pushing.
What happened: Someone else pushed commits after your last pull. Your local history is behind.
Fix:
1
2
3
git pull #bring in their commits first
#resolve conflicts if any appear
git push #now your push succeeds
Never use
git push --forceon a shared branch. It overwrites your teammates’ commits and creates chaos.
##Cloning a Repository
Cloning downloads a complete copy of a remote repository — all history, all branches — to your machine.
1
2
3
git clone [email protected]:username/project-name.git
cd project-name
git log --oneline
The clone automatically:
- Creates a folder named after the repository
- Sets
originto point back at the source - Sets up tracking for the default branch
- Checks out the default branch
Clone into a custom folder name:
1
git clone [email protected]:username/project-name.git my-custom-name
##Forking Workflow
A forkis your own copy of someone else’s repository on GitHub. You use this when contributing to projects you cannot push to directly (most open source projects, or repositories in other teams).
1
2
3
4
5
Original repo (upstream)
fork on GitHub
Your fork (origin) on GitHub
git clone
Your local machine
###How to fork and set up
Step 1: On GitHub, click Forkon the original repository. GitHub creates your-username/repo-name.
Step 2: Clone YOUR fork (not the original):
1
2
git clone [email protected]:your-username/repo-name.git
cd repo-name
Step 3: Add the original as a second remote called upstream:
1
2
git remote add upstream [email protected]:original-owner/repo-name.git
git remote -v
Expected:
1
2
3
4
origin [email protected]:your-username/repo-name.git (fetch)
origin [email protected]:your-username/repo-name.git (push)
upstream [email protected]:original-owner/repo-name.git (fetch)
upstream [email protected]:original-owner/repo-name.git (push)
Now you have two remotes:
origin— your fork (you can push here freely)upstream— the original (you can only read from here)
##Keeping Your Fork Up to Date
The original project keeps getting new commits. Pull them into your fork:
1
2
3
4
5
6
7
8
9
10
11
12
#Step 1: Get the latest from the original
git fetch upstream
#Step 2: Check what's new
git log --oneline main..upstream/main
#Step 3: Merge it into your local main
git checkout main
git merge upstream/main
#Step 4: Push to keep your GitHub fork current
git push origin main
Do this at the start of every work session so you are always working from the latest code.
##Summary
| Command | What it does |
|---|---|
git remote add origin <url> |
Connect local repo to a remote |
git remote -v |
List all remotes |
git push -u origin main |
Push and set upstream tracking |
git push |
Push to tracked remote (after -u is set) |
git fetch |
Download remote changes (safe, no merge) |
git pull |
Fetch + merge in one step |
git diff main..origin/main |
Compare local vs remote |
git clone <url> |
Download a complete repository |
git branch -a |
See all local and remote branches |
git branch -vv |
See tracking relationships |
Next: 06-branching-and-merging.md — Work on features in isolation with branches