Git & GitHub Best Practices
A condensed summary of the 25 most important Git and GitHub practices for Expo SDK 57 mobile teams - drawn from every page in this section.
Search across all documentation pages
A condensed summary of the 25 most important Git and GitHub practices for Expo SDK 57 mobile teams - drawn from every page in this section.
main is always integration truth: Every merged PR must pass CI; never leave main broken overnight - store and OTA pipelines assume a green tip (Git Basics for Mobile Teams).
Commit the lockfile: package-lock.json (or pnpm-lock.yaml) is required for reproducible npm ci in Mobile CI/CD Basics - never gitignore it.
Ticket IDs in every commit: feat(checkout): summary sheet [SHIP-412] - cherry-picks to release/* and hotfix/* depend on traceable messages.
Squash merge features to main: One ticket, one commit on integration branch - simplifies cherry-pick to release and hotfix lanes.
Short-lived feature branches: Target 1–3 days; rebase or merge main daily to avoid app.json, native folder, and eas.json conflicts.
Cut release/X.Y before freeze: Release branch holds the store candidate; new features land on main only until the train ships (Release Train Calendar).
Code freeze is a Git policy: During App Review, release/* accepts bugfixes only - enforce with branch protection, not Slack reminders.
Cherry-pick - never merge main into release/*: Merging pulls un-QA'd features into the store candidate; pick explicit SHAs listed in the release ticket.
Tag from release/* after QA sign-off: v2.6.0 triggers EAS release CI; tag message includes build_id QA tested (Automated Store Promotion).
Merge release/* back to main after rollout: Fast-forward or merge commit preserves train boundary; delete the release branch when 100% rollout completes.
Hotfix branches from tags: git checkout -b hotfix/2.4.2 v2.4.1 - not from main or release/2.5.0 - guarantees correct runtimeVersion and native baseline (GitHub Flow & Release Branches).
Parallel hotfix lanes per live minor: When 2.4.x and 2.5.0 RC coexist, separate hotfix/2.4.* and release/2.5.0 - one open hotfix per minor at a time.
Backport every hotfix: Cherry-pick fix SHA to main (if not already there) and to open release/* - production OTA alone does not protect the next store binary.
Map Git branches to OTA channels: Production channel publishes from hotfix/* or documented production branch - never from feat/* (Release Channels & Branches).
Never force-push main, release/*, or hotfix/*: Rewriting shared history breaks audit trails, tags, and OTA bundle lineage.
SDK upgrades on spike/* + worktrees: git worktree add keeps main open for features while expo upgrade runs in isolation (Interactive Rebase & Worktrees).
Interactive rebase on private branches only: Squash WIP before PR with git rebase -i origin/main; use --force-with-lease, never --force on shared branches.
Separate Metro ports per worktree: EXPO_PACKAGER_PORT=8082 in spike worktree - avoids packager collisions with daily feature work.
Pre-commit hooks mirror CI: Husky runs format:check, lint, typecheck - same scripts as pr-checks.yml (GitHub Actions Integration).
PR template requires device evidence: iOS and Android rows with PASS, test paths, and EAS build_id or install link - not "tested locally" placeholders.
Auto-label UI and native paths: needs-device-qa on src/**, ios/**, android/** changes; skip-device-qa for docs-only PRs.
Branch protection requires quality + evidence: GitHub Actions gates merge - policy beats honor system; pair with Preview Builds on PRs for QR installs.
Never commit signing secrets: No .p8, .jks, or .env with API keys - EAS credentials and EAS environment variables only.
Review native diffs on SDK bumps: git diff main -- ios/ android/ app.json eas.json before merge; run npx expo-doctor in CI on spike PRs.
Document rollback in PR and tag messages: OTA channel, feature flag, or hotfix branch plan - ties Git history to Rollback Runbook and on-call actions.
Prefer trunk (main) + short release/* + hotfix/*. Long-lived develop diverges from store binaries and OTA channels on mobile teams.
main + feature branches + squash merge + Husky hooks + tag-driven eas build. Add release branches and PR evidence when QA or a second engineer joins.
Squash merge at PR time is enough for most teams. Rebase onto main before review if you want linear history; avoid rebasing after review starts.
Tags trigger release pipelines; PRs trigger quality gates; branch protection connects both. Git choices define what CI builds - see CI/CD Best Practices.
Publishing production OTA from main while two store versions with different runtimeVersion values are live - use hotfix lanes mapped to channels.
Stack versions: This page was written for React 19.2.3, React Native 0.86.0, and Expo SDK 57 (
expo~57.0.4).
Reviewed by Chris St. John·Last updated Jul 16, 2026