Git Workflow: React Development
A practical guide for working with the Orcta React template.
Repository: Orctatech-Engineering-Team/orcta-react-template
Branching Model
We follow a simplified Git Flow that prioritizes clarity and reduces merge conflicts. All feature work happens in isolated branches that merge back to development.
Branch Structure
- main → Production-ready code. Protected branch. Only tech leads can merge.
- dev → Integration branch. All features merge here first for testing.
- feature/* → Individual feature branches. Created from dev, merged back to dev.
- hotfix/* → Emergency fixes. Created from main, merged to both main and dev.
Reference: Engineering Playbook, Section 4.2
Complete Workflow
Step 1: Clone and Setup
Start by creating your project from the React template on GitHub. Go to the template repository, select “Use this template”, create your new repository, then clone it to your machine.
# After creating your repo from the template
# Clone the newly generated repository
git clone git@github.com:Orctatech-Engineering-Team/YOUR-NEW-REPO.git
cd YOUR-NEW-REPO
# Install dependencies
pnpm install
# Verify the setup
pnpm run dev
pnpm testFirst Time Setup: Ensure you have Node.js 20+ and
pnpm 10+ installed. The template includes pre-configured ESLint,
Prettier, and TypeScript settings. Run the linter with
npm run lint before committing.
Step 2: Create a Feature Branch
Always create a new branch from the latest dev branch. Never work directly on main or dev.
# Switch to dev and get latest changes
git checkout dev
git pull origin dev
# Create your feature branch
git checkout -b feature/user-authenticationBranch Naming Convention: Use descriptive kebab-case
names: feature/user-profile-page,
feature/payment-integration,
hotfix/login-redirect-bug
Step 3: Develop Your Feature
Build your feature following React best practices and the template’s folder structure.
src/
components/
user-profile/
user-profile.tsx
user-profile.test.tsx
user-profile.module.css
Conventions:
- Component names use PascalCase but their file names are kebab-case:
user-profile.tsx - Component folders use kebab-case:
user-profile/ - Test files match component names:
user-profile.test.tsx - CSS modules use kebab-case:
user-profile.module.css
Reference: Naming Conventions Guide, Section 2.4
Step 4: Commit Your Changes
Make atomic commits with clear, descriptive messages in imperative mood.
# Stage your changes
git add src/components/user-profile/
# Commit with descriptive message
git commit -m "Add user profile component with avatar display"Good Commits:
- Add user authentication form
- Fix navigation menu overflow on mobile
- Update API endpoint for user profiles
- Refactor payment form validation logic
Bad Commits:
- Fixed stuff
- Update
- WIP
- asdfasdf
- Added feature and fixed bug and updated docs
Reference: Engineering Playbook, Section 4.1
Step 5: Keep Your Branch Updated
Regularly sync your feature branch with dev to minimize merge conflicts.
# Fetch latest changes from dev
git fetch origin dev
# Rebase your feature branch on top of dev
git rebase origin/dev
# If conflicts occur, resolve them and continue
# Edit conflicted files, then:
git add .
git rebase --continueRebase vs Merge: We prefer rebasing feature branches to maintain a linear history. This keeps the commit log clean and makes it easier to understand the evolution of the codebase. Only merge when integrating into dev or main.
Step 6: Run Tests and Linting
Ensure all tests pass and code meets quality standards before pushing.
# Run tests
pnpm test
# Run linter
pnpm run lint
# Fix auto-fixable linting issues
pnpm run lint:fix
# Check TypeScript types
pnpm run type-check
# Build to verify no errors
pnpm run buildPre-commit Hooks: The template includes Husky pre-commit hooks that automatically run linting and tests. If these checks fail, the commit will be blocked. Fix the issues before committing.
Step 7: Push Your Branch
Push your feature branch to the remote repository.
# Push your branch for the first time
git push -u origin feature/user-authentication
# Subsequent pushes (after first push)
git push
# Force push after rebasing (use with caution)
git push --force-with-leaseForce Pushing: Use --force-with-lease
instead of --force when you need to force push after
rebasing. This prevents accidentally overwriting someone else’s work if
they’ve pushed to your branch.
Step 8: Create a Pull Request
Open a pull request from your feature branch to dev. Use the PR template.
# Via GitHub CLI (if installed)
gh pr create --base dev --title "Add user authentication"
# Or visit GitHub and create PR manually
# The PR template will auto-populatePR Requirements:
- Base branch should always be
dev(not main) - Fill out all sections of the PR template
- Link to related issues or tickets
- Add screenshots for UI changes
- Request review from at least one team member
- Add appropriate labels: feature, bug fix, refactor, etc.
Reference: Engineering Playbook, Section 4.3
Step 9: Address Review Feedback
Respond to reviewer comments and make requested changes.
# Make changes based on feedback
# Edit files, then commit
git add .
git commit -m "Address review feedback: improve error handling"
# Push changes
git push
# PR will automatically updateReview Etiquette: Respond to all comments, even if just to acknowledge. If you disagree with a suggestion, explain your reasoning respectfully. Mark conversations as resolved once addressed. Reviewers should respond within 48 hours.
Reference: Engineering Playbook, Section 5.3
Step 10: Merge and Clean Up
Once approved, merge your PR and delete the feature branch.
# After PR is approved and CI passes
# Merge via GitHub UI (squash commits)
# Then locally, clean up your branch
git checkout dev
git pull origin dev
# Delete local feature branch
git branch -d feature/user-authentication
# Delete remote branch (usually auto-deleted by GitHub)
git push origin --delete feature/user-authenticationMerge Strategy: We use squash merging to keep the dev and main branches clean. All commits from your feature branch are combined into a single commit. Write a clear merge commit message that summarizes the entire feature.
Reference: Engineering Playbook, Section 4.3
Common Scenarios
Scenario: Working on Multiple Features
You’re working on a user profile feature, but need to start a hotfix for a critical bug.
# Commit your current work
git add .
git commit -m "WIP: user profile layout"
# Switch to main for hotfix
git checkout main
git pull origin main
git checkout -b hotfix/login-redirect
# Fix bug, commit, and create PR
# After hotfix is merged, return to feature
git checkout feature/user-profileScenario: Merge Conflict During Rebase
You’re rebasing your feature branch and encounter conflicts.
git rebase origin/dev
# Git shows conflicts in specific files
# Open conflicted files and look for markers:
# <<<<<<< HEAD
# Your changes
# =======
# Their changes
# >>>>>>>
# Edit files to resolve conflicts
# Remove conflict markers
# Keep the correct code
git add .
git rebase --continue
# If you want to abort the rebase
git rebase --abortScenario: Accidentally Committed to Wrong Branch
You made commits to dev instead of a feature branch.
# Currently on dev with uncommitted changes
# Create feature branch from current state
git checkout -b feature/my-feature
# Go back to dev and reset it
git checkout dev
git reset --hard origin/dev
# Your changes are now safely in feature branch
git checkout feature/my-featureScenario: Need to Update PR After Rebase
You rebased your feature branch and need to update the PR.
# After rebasing
git rebase origin/dev
# Force push with safety check
git push --force-with-lease
# PR will automatically update
# Add a comment explaining the rebaseQuick Reference Commands
# Check current branch and status
git status
git branch
# View commit history
git log --oneline --graph
# Undo last commit (keep changes)
git reset --soft HEAD~1
# Discard local changes
git checkout -- .
# Stash changes temporarily
git stash
git stash pop
# View diff before committing
git diff
# Amend last commit message
git commit --amend
# List all branches
git branch -a
# Clean up deleted remote branches
git fetch --prune