Git Setup for Tracking Upstream

494 words
2 minutes
Git Setup for Tracking Upstream

I started this site from an existing template and expect to change quite a lot of it over time. I also want to keep a reasonable way to pull in useful changes from the original repository.

Those two goals get less compatible with every local edit.

The setup I am using is deliberately small:

  • template is a clean copy of the upstream branch.
  • main contains the actual site and all of my changes.
  • Upstream updates go to template first, then get merged into main.

This gives me a stable reference point without requiring a separate public fork.

These are practical notes for that setup, mostly so I do not have to reconstruct it later.

Starting from an Empty Repository#

I first created an empty repository on GitHub, then cloned it locally:

Terminal window
git clone https://github.com/YOU/YOUR-BLOG.git
cd YOUR-BLOG

Because the repository was empty, there was no main history to preserve. I created the clean template branch first:

Terminal window
git switch -c template

Then I added the source repository as upstream:

Terminal window
git remote add upstream https://github.com/AUTHOR/REPO.git

I only need to fetch from that remote. Disabling pushes adds a small guard against sending anything there by mistake:

Terminal window
git remote set-url --push upstream DISABLE

Now git remote -v should show something like this:

origin https://github.com/YOU/YOUR-BLOG.git (fetch)
origin https://github.com/YOU/YOUR-BLOG.git (push)
upstream https://github.com/AUTHOR/REPO.git (fetch)
upstream DISABLE (push)

Next, I fetched the upstream history and made template point to its default branch:

Terminal window
git fetch upstream
git reset --hard upstream/master

The upstream repository in this example uses master. If it uses main, the last command should be git reset --hard upstream/main instead.

There is no merge here. The local repository started empty, so template can simply begin at the same commit as upstream.

Creating the Working Branch#

With template in place, I created main from it:

Terminal window
git switch -c main

All personal changes belong on this branch.

I then pushed both branches to my own repository:

Terminal window
git push -u origin main
git push -u origin template

At this point, the branch roles are clear: template is the clean reference, while main is allowed to diverge.

Pulling Upstream Changes Later#

The update routine is:

Terminal window
git fetch upstream
git switch template
git reset --hard upstream/master
git switch main
git merge template
git push origin main
git push origin template

Using reset --hard on template is intentional. That branch should contain no personal work, so its job is to match upstream exactly.

It is still worth checking the current branch before running the reset:

Terminal window
git status --short --branch

If upstream has changed files that I also customised, the conflict happens when template is merged into main. That is where it belongs: the clean branch remains clean, and the decisions about my version stay on the working branch.

Why Keep the Extra Branch?#

It would be simpler to modify the template once and forget about upstream. For a small site, that may be entirely reasonable.

I kept the extra branch because it answers two useful questions:

  • What did the original project change?
  • What did I change on top of it?

The branch does not remove merge conflicts, but it makes their source much easier to understand.

A little structure now is cheaper than trying to remember the history six months later.

Share Article

If this article helped you, please share it with others!

Git Setup for Tracking Upstream
https://devin.uk/posts/tracking-upstream/
Author
Devin Cheung
Published at
2026-09-21
Profile Image of the Author
Devin Cheung
Full Stack Software Engineer
Announcement
Welcome to my blog, feel free to reach out!
Categories
Tags
Latest Moments
Site Statistics
Posts
3
Categories
3
Tags
5
Total Words
7,577
Running Days
0 days
Last Activity
0 days ago
Site Info
Build Platform
Cloudflare Pages
Blog Version
Firefly v6.16.8
License
CC BY-NC-SA 4.0
Table of Contents