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:
templateis a clean copy of the upstream branch.maincontains the actual site and all of my changes.- Upstream updates go to
templatefirst, then get merged intomain.
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:
git clone https://github.com/YOU/YOUR-BLOG.gitcd YOUR-BLOGBecause the repository was empty, there was no main history to preserve. I created the clean template branch first:
git switch -c templateThen I added the source repository as upstream:
git remote add upstream https://github.com/AUTHOR/REPO.gitI only need to fetch from that remote. Disabling pushes adds a small guard against sending anything there by mistake:
git remote set-url --push upstream DISABLENow 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:
git fetch upstreamgit reset --hard upstream/masterThe 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:
git switch -c mainAll personal changes belong on this branch.
I then pushed both branches to my own repository:
git push -u origin maingit push -u origin templateAt 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:
git fetch upstream
git switch templategit reset --hard upstream/master
git switch maingit merge template
git push origin maingit push origin templateUsing 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:
git status --short --branchIf 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!



