Fork a repository and the clock starts: the original keeps moving, and your copy quietly becomes a snapshot of the past. Whether it is a package you patched or an internal template your team forked, syncing is the same two-remote routine.
Two remotes, two jobs#
git remote add upstream [email protected]:original/project.git
git remote -v
origin points at your fork - where you push. upstream points at the source - where you only read. Naming them this way is convention, and the convention matters: when every guide and every teammate says “upstream”, everyone means the same thing.
The sync routine#
git fetch upstream
git switch main
git merge upstream/main
git push origin main
Fetch first, look at what arrived (git log --oneline HEAD..upstream/main), then merge and push. This is the fetch-then-decide rhythm from Fetch vs Pull - the only difference is the remote’s name. If your team prefers linear history, git rebase upstream/main works too, but only on commits that exist solely in your fork.
Keep your changes out of main#
The fork stays easy to sync when your own work never touches its main. Do everything on feature branches - git switch -c our-patch - and let main mirror upstream exactly. The day you commit directly to the fork’s main, every future sync becomes a merge of two real histories instead of a fast-forward, and conflicts move in permanently.
If that has already happened, the repair is usually: branch your changes off (git branch our-work), reset main back to upstream (git reset --hard upstream/main after a fetch), and push. That is a force-push to your own fork, so do it with lease and warn anyone else using the fork.
How often#
Often enough that each sync is boring. Weekly keeps the diff readable; monthly is survivable; yearly turns syncing into an archaeology project. Teams running a self-hosted server can nudge this with a scheduled pipeline that fetches upstream and opens a pull request when main falls behind - boring automation for a task that should never be exciting.
Share this post
Keep reading
Annotating Commits with git notes: Metadata Without Rewriting History
Some things belong on a commit but not in it: review links, benchmark results, the ticket nobody remembered to reference. git notes adds them after the fact, no rebase required.
Backing Up Your Git Server So It Actually Restores
Every clone is a partial backup - but hooks, config and server state live outside the repo. Mirror, bundle, copy off-site, and rehearse the restore.
Cherry-Picking: One Commit Without the Branch
Cherry-pick copies a single commit onto your branch and leaves the rest behind. Right for hotfixes across release branches, wrong as a sync strategy.