Skip to main content
Follow this workflow for all repositories to maintain clean history, minimize conflicts, and ensure production stability.
This document explains how we branch, commit, and merge so that:
  • History stays clean
  • Merge conflicts are rare (and small when they happen)
  • Production is always stable
  • Work-in-progress is easy to manage

Goals

Stable Main

main is always deployable and production-ready

Short-lived Branches

Every change goes through a short-lived branch

Clear Communication

Branch names and commits tell you what changed and why

Minimal Conflicts

Conflicts minimized through small branches and frequent syncs

Branch Types

We keep it simple and modern:
  • main – production-ready, stable code
  • dev (optional, for larger teams) – integration branch, where feature branches are merged before going to main
  • feature/*, fix/*, chore/* – topic branches for actual work

Solo or Small Team

Just use main + feature/* branches. Merge feature/*main via pull requests (even if it’s just you).
Branches:
  • main
  • feature/* branches

Larger Collaborator Team

Use a three-tier approach: feature/*dev → (when stable) → main
Branches:
  • main (production)
  • dev (integration)
  • feature/* (work branches)

Branch Naming Rules

Use clear, structured names that match your commit prefixes:
feature/<short-topic>
Examples:
  • feature/rn-sdk-upload
  • feature/flutter-auth-support
  • feature/user-profile-endpoint
fix/<short-topic>
Examples:
  • fix/login-null-crash
  • fix/api-timeout-error
  • fix/sdk-type-definitions
chore/<short-topic>
Examples:
  • chore/update-deps
  • chore/regenerate-sdk
  • chore/cleanup-old-files
refactor/<short-topic>
Examples:
  • refactor/api-client-structure
  • refactor/auth-flow-logic
  • refactor/database-queries
hotfix/<short-topic>
Examples:
  • hotfix/handle-500-error-in-prod
  • hotfix/critical-security-patch
  • hotfix/payment-gateway-issue
Branch names should match the commit prefix and clearly describe the purpose.

Complete Workflow

Step 1: Create a New Feature Branch

1

Update main branch

git checkout main
git pull origin main
2

Create feature branch

git checkout -b feature/my-new-feature
3

Work and commit

# Make your changes
git add .
git commit -m "feat(sdk): add loginWithOtp method"
4

Sync with main regularly

git fetch origin
git rebase origin/main
# or: git merge origin/main
5

Push branch

git push -u origin feature/my-new-feature
6

Open pull request

Open a PR: feature/my-new-featuremain
7

Merge and clean up

After PR approval, merge using squash (recommended) or rebase & merge

Merge Strategy

All commits in feature/* are squashed into one commit on main.
Benefits:
  • main history stays clean (one commit per feature)
  • Small, readable Git log
  • Easier to revert a feature if needed
feat(sdk): add loginWithOtp support

Rebase & Merge (Alternative)

Keeps individual commits from the feature branch, but rewrites history to be linear. Good if you have very clean small commits.

When to Branch

  • You’re working on anything that will take more than ~30–60 minutes
  • You’re adding a feature, fixing a bug, or doing a refactor
  • You’re experimenting, but might want to keep or scrap the work later
  • It’s an ultra-trivial change (e.g., fixing a typo in README)
  • And even then—it’s often better to still use a branch + PR for consistency

Minimizing Merge Conflicts

You can’t avoid conflicts forever, but you can dramatically reduce them with these practices.

1. Keep Branches Short-lived

Aim to merge branches within 1–2 days, not 1–2 weeks. The longer a branch lives, the more the rest of the codebase moves.

2. Sync with Main Regularly

On your feature branch, do this often:
git fetch origin
git rebase origin/main
Rebasing keeps history linear and clean

3. Avoid “Big Bang” Changes

❌ Don't Do This

Combine formatting + huge refactor + new features in one branch

✅ Do This Instead

Run formatter in separate chore/formatting branch and merge it first

4. Own Specific Areas

If two people keep editing the same files, conflicts are inevitable. Coordinate ownership:
  • SDK core client → one owner at a time
  • Auth flows → one owner at a time
  • Huge config files → modify carefully and incrementally

Command Cheat Sheet

git checkout main
git pull origin main
git checkout -b feature/my-feature
git add .
git commit -m "feat(api): add /users/search endpoint"
git fetch origin
git rebase origin/main
# or: git merge origin/main
git push -u origin feature/my-feature
# then open PR in GitHub/GitLab
git checkout main
git pull origin main
git branch -d feature/my-feature      # delete local
git push origin --delete feature/my-feature  # delete remote

Handling Merge Conflicts

When conflicts occur during git rebase origin/main or merge:
1

Git marks conflicts

Files will have conflict markers: <<<<<<<, =======, >>>>>>>
2

Open and resolve

Open those files, manually decide what to keep
3

Stage resolved files

git add <file1> <file2>
4

Continue the operation

git rebase --continue   # if rebasing
# or: git commit         # if merging
If a conflict is huge, investigate why: big refactor? formatting change? simultaneous edits? In future, break PRs into smaller units and merge formatting/structural changes separately.

Example: SDK Change Workflow

Scenario: You add a new endpoint to your API and then regenerate the React Native SDK.

Backend Repository

git checkout -b feature/add-search-endpoint

SDK Repository

git checkout main
git pull origin main
git checkout -b feature/sdk-search-endpoint

Do’s and Don’ts

✅ Do

  • Use short-lived feature branches
  • Use clear, structured branch names
  • Use Conventional Commits
  • Sync with main frequently
  • Use squash merges for clean history

❌ Don't

  • Work on main for real changes
  • Keep branches alive for weeks
  • Combine unrelated changes in one PR
  • Ignore merge conflicts until the end
  • Skip code reviews (even solo)

TL;DR Workflow

1

Start from main

git checkout main && git pull
2

Create branch

git checkout -b feature/specific-task
3

Commit with convention

4

Sync regularly

git rebase origin/main
5

Open PR

Review → squash & merge into main
6

Delete branch

Clean up after merge
Follow this workflow and your repositories will stay clean, predictable, and conflict-light.