The Notice Board and Your Diary
Every college has a notice board. When you walk past it, you read what is new: a timetable change, an exam date, a fest announcement. Reading the board does not change anything in your own diary. Later, when you are ready, you copy the new timetable into your diary.
Git works with GitHub in exactly these two steps. git fetch is reading the notice board: it downloads what is new but leaves your work alone. git merge is copying it into your diary. git pull does both at once.
In the Push, Pull and Clone lesson you used git push and git pull on one branch. Now Asha, Ravi and Imran all push to the Utsav repository asha-utsav-demo/college-fest-site every day, so Asha needs to understand what her computer knows about GitHub, and when.
Remotes and origin
A remote is a saved address of another copy of your repository, usually on GitHub. When you clone a repository, Git automatically creates a remote called origin. It is only a short nickname, so you do not have to type the full address every time.
# Show the remotes this project knows about
git remote -v
# Show all branches, including remote-tracking ones
git branch -a
You will see something like:
origin https://github.com/asha-utsav-demo/college-fest-site.git (fetch)
origin https://github.com/asha-utsav-demo/college-fest-site.git (push)
* main
remotes/origin/main
Remote-tracking branches: origin/main
origin/main is a remote-tracking branch. It is your computer’s memory of where main was on GitHub the last time you checked. You cannot commit on it. Git moves it only when you talk to GitHub, for example with git fetch, git pull or git push.
So there are really three things to keep in mind:
GitHub (origin) main A---B---C---D
^ Ravi pushed D
Your computer:
origin/main (last seen) A---B---C
main (your work) A---B---C
Ravi pushed commit D to GitHub. Asha’s computer does not know yet. Her origin/main is like an old photo of the notice board.
git fetch: Read the Notice Board
git fetch downloads new commits and branches from the remote and updates the remote-tracking branches (origin/main and others). It does not touch your own branches or the files in your folder. That makes it completely safe to run at any time.
# Download new commits from GitHub. Your files do NOT change.
git fetch
# See how your branch compares with origin/main
git status
You will see something like:
From https://github.com/asha-utsav-demo/college-fest-site
c3d4e5f..d4e5f6a 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)
The line c3d4e5f..d4e5f6a main -> origin/main means “origin/main moved from this commit to that one”. Before you merge, you can look at exactly what arrived:
# List the commits on GitHub that you do not have yet
git log --oneline main..origin/main
# See exactly what they change
git diff main origin/main
# Happy? Bring them into your branch
git merge origin/main
main..origin/main means “commits that are in origin/main but not in main”. This is a careful habit when you are not sure what your teammates changed.
git pull: Fetch and Merge Together
Most days you trust your team and simply want the latest work. git pull runs git fetch and then merges the tracking branch into your current branch:
# fetch + merge in one command
git pull
| Command | Downloads new commits? | Changes your branch and files? |
|---|---|---|
git fetch | Yes | No |
git merge origin/main | No | Yes |
git pull | Yes | Yes (fetch, then merge) |
Because a pull includes a merge, it can create a merge commit or even a merge conflict. You fix those exactly as you learned in the Merging lesson.
When Git asks how to pull
If you and a teammate both made new commits (your branches have diverged), recent versions of Git refuse to guess and print:
hint: You have divergent branches and need to specify how to reconcile them.
...
fatal: Need to specify how to reconcile divergent branches.
Tell Git your choice once, and the message goes away:
# Choose once: make "git pull" merge (the method used in this course)
git config --global pull.rebase false
# Or, for a single pull, replay your commits on top instead
git pull --rebase
git pull --rebase takes your new commits off for a moment, adds your teammates’ commits, then puts yours back on top. The history stays in one straight line with no merge commit. You will learn rebase properly in the Rebase and Clean History lesson. Until then, the merge setting is the simplest choice.
Tracking Branches and Ahead/Behind
A local branch can be linked to a remote branch. This link is called a tracking (or upstream) branch. Your local main tracks origin/main. Because of this link, plain git pull and git push know where to go, and git status can compare the two.
After a git fetch, git status shows one of these messages:
Your branch is ahead of 'origin/main' by 2 commits.
(use "git push" to publish your local commits)
Your branch is behind 'origin/main' by 3 commits, and can be fast-forwarded.
Your branch and 'origin/main' have diverged,
and have 2 and 3 different commits each, respectively.
- Ahead: you have commits GitHub does not have. Run
git push. - Behind: GitHub has commits you do not have. Run
git pull. - Diverged: both. Pull first (and fix any conflict), then push.
git status does not ask GitHub. It compares with your last saved copy of origin/main. If you have not fetched for two days, it may happily say “up to date” while your team has pushed ten commits. Run git fetch first.
To see every branch and its tracking information at once, use git branch -vv (two v’s for “very verbose”):
# Show each branch, its tracking branch and ahead/behind counts
git fetch
git branch -vv
You will see something like:
feature/sponsors b2c3d4e Add sponsor logos
* main a1b2c3d [origin/main: behind 2] Add home page
Here main tracks origin/main and is 2 commits behind. feature/sponsors has no brackets, which means it exists only on this computer.
Pushing a New Branch: git push -u
A branch you create on your computer is private until you push it. The first push needs the remote name and the branch name. The -u option (short for --set-upstream) also sets up tracking, so afterwards plain git push and git pull work on that branch.
# Create the branch and do your work
git switch -c feature/schedule
git add schedule.html
git commit -m "Add fest schedule page"
# First push: create the branch on GitHub and set up tracking
git push -u origin feature/schedule
# Later pushes from this branch need no extra words
git push
You will see something like:
To https://github.com/asha-utsav-demo/college-fest-site.git
* [new branch] feature/schedule -> feature/schedule
branch 'feature/schedule' set up to track 'origin/feature/schedule'.
Now Ravi and Imran can see feature/schedule on GitHub. When they run git fetch, they get origin/feature/schedule. To work on it themselves they run git switch feature/schedule, and Git creates a local branch that tracks it automatically.
Deleting Remote Branches
After a branch is merged, delete it on GitHub as well as on your computer. Your teammates should also clean up the old origin/... names on their computers with --prune.
# Delete a branch on GitHub
git push origin --delete feature/schedule
# Remove remote-tracking branches that no longer exist on GitHub
git fetch --prune
# Delete your local copy too
git branch -d feature/schedule
Renaming and Changing Remotes
Sometimes the address of a remote changes. For example, Asha renames the repository on GitHub to utsav-website. GitHub usually redirects the old address for a while, but it is better to update it. You can also rename a remote, or add a second one:
# Rename a remote
git remote rename origin github
# Point a remote at a new address (for example, a renamed repository)
git remote set-url origin https://github.com/asha-utsav-demo/utsav-website.git
# Add a second remote, for example a teammate's copy
git remote add imran https://github.com/imran-utsav-demo/college-fest-site.git
# Check the result
git remote -v
You will use a second remote, called upstream, in the Forks and Open Source lesson.
Real-Life Example: Asha’s Daily Routine
With three people pushing to the fest site, Asha follows a simple routine every day. It keeps her up to date and avoids surprise conflicts:
# 1. Start of the day: what did the team push?
git switch main
git fetch
git status
# 2. Update main
git pull
# 3. Start today's work on a fresh branch
git switch -c fix/schedule-timings
git commit -am "Fix dance competition timing"
git push -u origin fix/schedule-timings
# 4. Before leaving: how do my branches look?
git branch -vv
At the end, git branch -vv shows something like:
* fix/schedule-timings e5f6a7b [origin/fix/schedule-timings] Fix dance competition timing
main d4e5f6a [origin/main] Add sponsors page
No “ahead” or “behind” in the brackets means each branch matches GitHub. Everything is saved and shared.
Try these changes:
- Ask a friend to push a commit, then run
git fetchandgit statusbefore pulling. - Make a local commit without pushing and see “ahead by 1” in
git branch -vv. - Run
git log --oneline --graph --allafter a fetch to seeorigin/maindrawn next tomain.
Common Mistakes
- Expecting git fetch to change your files. It only updates
origin/.... Fix: after fetching, rungit merge origin/main, or usegit pull. - Trusting an old status. “Your branch is up to date” only means “up to date with what I last fetched”. Fix: run
git fetchfirst. - Pushing a new branch with plain git push. Git replies that the branch has no upstream branch. Fix:
git push -u origin branch-namethe first time. - Pushing before pulling. GitHub rejects the push because it has commits you do not have. Fix:
git pull, resolve any conflict, thengit push. - Old remote branches piling up. Deleted branches still appear in
git branch -a. Fix:git fetch --prune.
Practice Task: Fetch, Pull and a New Branch
Use a repository of yours that is already on GitHub.
# Use your college-fest-site repository that is already on GitHub
cd college-fest-site
git remote -v
git branch -vv
- Check your remotes and tracking branches.
- On GitHub, edit
README.mdin the browser and commit the change there. On your computer, rungit fetch, read the status and list the new commit, without merging yet. - Pull the change and check the log.
- Create
feature/faq-page, commit a smallfaq.html, push it with tracking and look atgit branch -vv. - Delete the branch on GitHub and on your computer, and prune old remote-tracking branches.
Show one possible answer (try it yourself first!)
# 1. Look at your remotes and tracking branches
git remote -v
git branch -vv
# 2. On GitHub, edit README.md in the browser and commit it there.
# Then, on your computer:
git fetch
git status
git log --oneline main..origin/main
# 3. Bring the change in
git pull
git log --oneline -3
# 4. Push a new branch
git switch -c feature/faq-page
git add faq.html
git commit -m "Add FAQ page"
git push -u origin feature/faq-page
git branch -vv
# 5. Clean up
git switch main
git push origin --delete feature/faq-page
git fetch --prune
git branch -D feature/faq-page
git branch -a
Key Takeaways
- origin is the default nickname of your GitHub copy.
origin/mainis your last known picture of its main branch. git fetchdownloads and updatesorigin/...only. It is always safe.git pullisgit fetchplus a merge.git pull --rebaseis an alternative you will meet later.- Tracking branches power plain
git push,git pulland the ahead/behind counts ingit statusandgit branch -vv. - Push a new branch with
git push -u origin name, delete it withgit push origin --delete name. - Use
git remote renameandgit remote set-urlwhen names or addresses change.