Script Valley
Open Source Contribution: A Practical Guide
Git Workflow for ContributorsLesson 2.5

How to keep a fork up to date with upstream over time

fetch vs pull, upstream sync workflow, GitHub sync fork button, automating sync with GitHub Actions, rebase vs merge strategy, diverged fork recovery

Forks Go Stale Fast

Every commit to the original repo widens the gap between upstream and your fork. Left unchecked, this makes rebasing painful and PRs harder to review.

Manual Sync

# Fetch all upstream changes without merging
git fetch upstream

# Fast-forward your local main
git checkout main
git rebase upstream/main

# Update your remote fork
git push origin main

Use rebase here instead of merge to keep your fork history clean and linear.

GitHub UI Sync

GitHub added a Sync fork button to the fork page. It is one click to pull upstream changes into your fork default branch. Useful if you are doing light work without a local clone.

Automating Sync with GitHub Actions

# .github/workflows/sync-fork.yml
name: Sync Fork
on:
  schedule:
    - cron: '0 6 * * 1'
jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - run: |
          git remote add upstream https://github.com/OWNER/REPO.git
          git fetch upstream
          git rebase upstream/main
          git push origin main --force-with-lease

This workflow keeps your fork current automatically. Only do this on personal forks where you control the workflow.

Recovering a Diverged Fork

If you have merged instead of rebased repeatedly, your fork history diverges significantly from upstream. Signs: git status shows you are many commits ahead and behind simultaneously, and git log --oneline upstream/main..HEAD shows dozens of merge commits. Recovery: create a fresh branch from upstream/main, cherry-pick your actual work commits onto it, and open a new PR from that clean branch. The old fork branch can be deleted. Diverged forks are recoverable -- they just require deliberate cleanup rather than a quick rebase.