Lesson 02 of 06Concept

Fetch Updates from a Remote

Goal: Download remote history with git fetch without changing a single file in your working tree.

git fetch is the safest command in Git. It asks the remote what it has, downloads anything new, and moves your remote-tracking branches to match.

What it never does is touch your branch, your working tree or your staging area. Fetching can surprise you with information, never with changes.

Fetching while a teammate pushes

Step 1 of 2

You committed "Add forecast panel", so your main is one ahead of origin/main. Meanwhile a teammate pushed a fix of their own — but nothing in your repository knows about it yet, and git status still reports only your own commit.

Step 1 of 2. You committed "Add forecast panel", so your `main` is one ahead of `origin/main`. Meanwhile a teammate pushed a fix of their own — but nothing in your repository knows about it yet, and `git status` still reports only your own commit.

What a fetch prints

$ git fetch

remote: Enumerating objects: 5, done.
From https://github.com/acme/weather-app
   1b7e55c..8d4c21e  main       -> origin/main

The last line is the important one: origin/main moved from 1b7e55c to 8d4c21e. The arrow is Git telling you which local name it updated to match which remote branch.

Look before you leap

Fetching first, deciding second, is the habit worth building:

  • git fetch — download, update origin/*, change nothing else
  • git log --oneline main..origin/main — the commits they have that you do not
  • git log --oneline origin/main..main — the commits you have that they do not
  • git diff main origin/main — what the two actually differ by

Only then do you choose how to combine them: git merge origin/main, or git rebase origin/main.

Fetch and pull are not the same

git fetch

  • Updates origin/main only
  • Working tree untouched, always
  • Can never cause a conflict

git pull

  • Fetches, then merges or rebases
  • Moves your branch and your files
  • Can stop halfway with a conflict

Useful variations

$ git fetch --all --prune

Fetching origin
 - [deleted]         (none)     -> origin/feature/old-nav
   1b7e55c..8d4c21e  main       -> origin/main

--all fetches from every remote, and --prune deletes remote-tracking branches whose branch no longer exists on the server. Without --prune, origin/feature/old-nav would linger for ever after the branch was merged and deleted.

Finished reading?

Marking it complete records your progress and XP for this lesson.