Long-Lived Integration Workflow

When your project isn’t just a temporary contribution but has its own identity (e.g., a “mod,” a “custom flavor,” or a “branded fork”), the workflow shifts from “temporary branch” to “long-lived integration.”

You are essentially maintaining a parallel product while siphoning updates from the original source.

The Branching Strategy

In this scenario, you need two permanent branches that never die:

  1. upstream-main (or vendor): A clean, untouched mirror of the original project. You only ever pull into this branch.
  1. prod (or custom-main): Your project’s identity. This contains your unique branding, features, and configurations.

The Mental Model

Think of the upstream project as the engine and your project as the car body. You want to be able to swap out the engine for a newer model without denting the car.

The Long-Term Integration Workflow

Step A: Keeping the “Engine” Current

Periodically update your mirror branch so you have a clean base:

git checkout upstream-main

git pull upstream main

Step B: The “Integration” Merge

Instead of rebasing (which is for short-lived features), you will Merge the upstream changes into your custom project. This creates a “Merge Commit” that acts as a historical marker of when you synced.

git checkout prod

git merge upstream-main

Step C: Resolving “Identity” Conflicts

Because your project has its own identity, you will likely have permanent conflicts (e.g., you changed the README.md or the logo.png).

  • Keep your identity: Always favor your custom files during the merge.
  • Refactor for compatibility: If the upstream project changed a core function that your custom code relies on, you must update your custom code to match the new API.
  1. 3. 3. Architecture for Easier Maintenance

If you find yourself resolving the same conflicts every month, your project is too “intertwined.” Aim for decoupling:

StrategyAction
Configuration Over ModificationUse .env files or config objects rather than hardcoding changes into the upstream source code.
The “Plugin” PatternKeep your personal code in separate directories (e.g., /custom) and hook into the main app via imports, rather than editing the original files.
Wrapper ScriptsIf you need to change how the app starts, write a wrapper script (start-my-flavor.sh) instead of modifying the upstream Makefile or package.json.
  1. 4. 4. Handling Contributions Back

If you develop a bug fix in your “Identity” project that would benefit the “Upstream” project:

  1. Cherry-pick that specific commit:

git checkout -b fix-upstream-bug

git cherry-pick <commit-hash-from-your-prod-branch>

  1. Push this clean, isolated branch to your fork and open a PR.

Summary of the “Identity” Workflow

  1. Mirror the upstream in a dedicated local branch.
  2. Merge (don’t rebase) that branch into your custom branch.
  3. Isolate your unique code into separate files/folders to minimize merge conflicts.
  4. Cherry-pick fixes back to upstream when they are generic enough to share.