Engineering Standards

Your comprehensive guide to Git workflow excellence

Our Git workflow is designed for traceability, reversibility, and collaboration. We optimize for a clean history over fast integration, ensuring every change can be tracked, understood, and rolled back if needed.

Pro Tip: Following these standards reduces merge conflicts by 70% and speeds up code reviews by 50%. Consistency is key!

Zero Confusion

Clear rules on branching means no guessing where code belongs. Every branch has a specific purpose and lifecycle.

  • Predictable branch names
  • Clear merge policies
  • No ambiguity in workflow

Atomic History

Small, semantic commits allow us to generate changelogs automatically and pinpoint bugs instantly.

  • One logical change per commit
  • Self-documenting messages
  • Easy to revert if needed

Code Reviews

No code reaches production without a second pair of eyes. PRs are our quality gate and knowledge sharing mechanism.

  • Mandatory peer review
  • Automated checks pass
  • Knowledge transfer

Before You Start

Ensure your global git config is set correctly. This ensures your commits are properly attributed to you in the project history and helps with accountability.

Terminal Commands
$ git config --global user.name "Your Name"
$ git config --global user.email "your.email@company.com"

Verify your config: Run git config --list to see all your settings. Check that user.name and user.email match your company email.

Why These Standards Matter

1
Faster Onboarding

New team members can understand the codebase history and contribute confidently within days, not weeks.

2
Easier Debugging

When bugs appear, semantic commits help you quickly identify which change introduced the issue.

3
Better Releases

Automated changelog generation from commit messages saves hours of manual documentation work.

4
Reduced Conflicts

Clear branching strategy minimizes merge conflicts and makes resolution straightforward when they occur.

Monorepo Structure

We use a "Single Source of Truth" structure that keeps all related code in one repository for easier dependency management and cross-project changes.

Why Monorepo? Easier code sharing, atomic commits across projects, simplified dependency management, and unified tooling.
project-root/
├── .github/ # Actions & Templates
│   ├── workflows/
│   └── PULL_REQUEST_TEMPLATE.md
├── frontend/ # NextJS / React
│   ├── src/
│   ├── public/
│   ├── package.json
│   └── tsconfig.json
├── backend/ # Express / Python
│   ├── src/
│   ├── tests/
│   ├── Dockerfile
│   └── requirements.txt
├── .gitignore
├── .env.example Safe!
├── .env Never commit!
└── README.md

The .env Rule

Never commit .env files containing real keys. Always commit .env.example with dummy values so teammates know which variables are required.

# Never commit this
DATABASE_URL=postgresql://user:password@localhost/db
# Always commit this
DATABASE_URL=postgresql://user:password@localhost/db

Node Modules

Ensure node_modules/ is in your .gitignore. If you accidentally commit it, the repo size balloons and it's painful to fix.

If you already committed node_modules: Use git rm -r --cached node_modules then commit the removal.

Essential Files

  • README.md - Project overview, setup instructions, and contribution guidelines
  • .gitignore - Patterns for files that should never be committed
  • .github/ - CI/CD workflows, issue templates, PR templates
  • LICENSE - Project license (MIT, Apache, etc.)

Recommended .gitignore Patterns

# Dependencies
node_modules/
vendor/
.venv/
# Environment variables
.env
.env.local
.env.*.local
# Build outputs
dist/
build/
*.log
# IDE
.vscode/
.idea/
*.swp

Branching Strategy

We follow a simplified GitFlow model that balances flexibility with structure. This strategy ensures code quality while maintaining development velocity.

Core Principle: main and dev are protected. All work happens in feature branches that merge via Pull Requests.

Protected Long-Lived Branches

Read-Only via PR
main Production

Production Branch LIVE

The "Gold Standard". Only code that is live or ready to go live immediately. Direct commits are blocked via branch protection rules. Deploys automatically to Production environment.

Merge Rules:

  • • Only merges from dev branch
  • • Requires 2+ approvals
  • • All CI checks must pass
  • • No force pushes allowed
dev Staging

Integration / Staging Branch TESTING

The "Working Copy". All features merge here first for integration testing. This branch deploys to the Staging environment for QA testing and stakeholder review.

Merge Rules:

  • • Merges from feature/bugfix/hotfix branches
  • • Requires 1+ approval
  • • CI checks must pass
  • • Auto-deploys to staging environment

Temporary Branches (Yours)

Your Workspace

These branches are created for specific work and deleted after merging. Never commit directly to main or dev.

Naming Convention: type/short-description

Good examples:

  • feature/user-authentication
  • bugfix/payment-gateway-timeout
  • hotfix/critical-security-patch

Bad examples:

  • my-branch
  • fix-stuff
  • feature
Feature
feature/auth-login

New functionality or enhancements

  • • Merges to: dev
  • • Lifecycle: Days to weeks
  • • Delete after merge
Bugfix
bugfix/header-alignment

Non-critical bug fixes

  • • Merges to: dev
  • • Lifecycle: Hours to days
  • • Delete after merge
Hotfix
hotfix/prod-crash-db

Critical production fixes

  • • Merges to: main & dev
  • • Lifecycle: Minutes to hours
  • • Use sparingly!

Branch Lifecycle Flow

feature/new-feature dev main

1. Create feature branch from dev → 2. Develop & test → 3. PR to dev → 4. After QA, PR to main → 5. Deploy to production

Daily Workflow

Follow these steps every day to maintain a clean, organized workflow. Consistency prevents most Git headaches.

Daily Checklist: Sync → Branch → Code → Commit → Push → PR → Review → Merge

1

Sync First (Always!)

Never start coding on an old branch. Always sync with the remote to get the latest changes from your team. This prevents merge conflicts later.

# Switch to development branch
git checkout dev
# Pull latest changes from remote
git pull origin dev
If you have local changes: Stash them first with git stash, then pull, then git stash pop
2

Create Feature Branch

Create a new branch from the updated dev branch. Use descriptive names following our naming convention.

# Create and switch to new branch
git checkout -b feature/user-profile-page
Good: feature/auth-oauth
Bad: my-branch

Interruption? Use Stash

Need to switch branches urgently but not ready to commit? Git stash saves your work temporarily without creating a commit.

# Save changes temporarily
git stash
# Optional: add message
git stash save "WIP: auth work"
# List all stashes
git stash list
# Restore most recent
git stash pop
Pro Tip: Use git stash list to see all stashes. Apply specific stash with git stash apply stash@{0}
3

Make Changes & Commit

Write your code, test it locally, then commit with a semantic message. Make small, frequent commits rather than one large commit at the end.

# Stage all changes
git add .
# Or stage specific files
git add src/components/Profile.tsx
# Commit with semantic message
git commit -m "feat(profile): add user avatar component"

Commit Best Practices:

  • Commit related changes together
  • Write clear, descriptive messages
  • Test before committing
  • Keep commits small and focused
4

Push to Remote

Push your branch to the remote repository. This makes it available for code review and allows others to see your progress.

# Push branch to remote (first time)
git push -u origin feature/user-profile-page
# Subsequent pushes
git push
📝 Note: The -u flag sets up tracking so future git push commands know where to push.
5

Create Pull Request

After pushing, create a Pull Request on GitHub/GitLab. Fill out the PR template completely with description, screenshots, and related issues.

PR Checklist:

  • Code builds and tests pass
  • Self-review completed
  • PR description filled out
  • ✓ Screenshots attached (if UI changes)
  • ✓ Related issues linked

Semantic Commits

Semantic commits make your Git history readable and enable automated tooling. Every commit message follows a consistent format that clearly describes what changed and why.

Format: type(scope): description

The scope is optional but highly recommended. It helps categorize changes by area (e.g., auth, api, ui).

Commit Types Reference

Type Use Case Example When to Use
feat New feature for users feat(auth): add google oauth login Adding new functionality
fix Bug fix fix(cart): prevent negative quantity Fixing a bug
docs Documentation only docs(readme): add setup instructions README, comments, docs
refactor Code restructuring refactor(api): simplify user helper Improving code structure
chore Maintenance tasks chore(deps): upgrade react to v19 Dependencies, configs
test Test additions/changes test(auth): add login unit tests Adding or updating tests
style Formatting, styling style(ui): format button component CSS, formatting, no logic change
perf Performance improvements perf(api): optimize database query Speed or memory improvements

Good Examples

  • feat(payment): add stripe integration
  • fix(api): handle null user gracefully
  • refactor(utils): extract date formatting
  • docs(api): update endpoint documentation

Bad Examples

  • fixed bug
  • update
  • wip
  • changes
  • save work

Writing Great Commit Messages

1. Use Imperative Mood

Write as if completing: "This commit will..."

✓ add user authentication
✗ added user authentication
2. Keep It Short

First line should be 50 chars or less

✓ feat(api): add pagination
✗ feat(api): add pagination feature with...
3. Add Body for Context

Use body to explain why, not what

feat(auth): add 2FA
Adds two-factor authentication to
improve account security...
4. Reference Issues

Link to related tickets/issues

✓ fix(ui): resolve button alignment
Closes #123

Pull Request Protocol

Pull Requests are our quality gate and knowledge sharing mechanism. A well-crafted PR makes code review efficient and helps the team learn from each other.

🎯 Goal: Make it easy for reviewers to understand what changed, why it changed, and how to test it.

Pre-PR Checklist

Code Review Etiquette

1
Be Kind & Constructive

Critique the code, not the person. Use "we" language: "We could improve this by..."

2
Be Specific & Actionable

"Suggest renaming `userData` to `userProfile` for clarity" is better than "Fix naming".

3
Actually Review

Don't just approve. Run the code, test edge cases, check for security issues.

4
Respond Promptly

Aim to review within 24 hours. Blocked PRs slow down the team.

PR Description Template

## Summary
Added the new login component using JWT authentication with refresh token support.
## Changes
- Created Login.tsx component
- Added useAuth hook for token management
- Updated routes.ts to include auth routes
- Added error handling for expired tokens
## Testing
- [x] Tested login with valid credentials
- [x] Tested error handling for invalid credentials
- [x] Verified token refresh mechanism
## Screenshots
[Attach screenshots if UI changes]
## Related Issues
Closes #452

PR Size Guidelines

Small
< 200 lines changed

Ideal size. Easy to review, quick to merge.

Medium
200-500 lines

Acceptable. Consider splitting if possible.

Large
> 500 lines

Too large. Split into multiple PRs.

Conflict Resolution

Conflicts occur when Git cannot automatically merge changes. This usually happens when two people edit the same lines in different branches. Don't panic—conflicts are normal and easily resolved.

💡 Prevention Tip: Keep your feature branches up to date with dev by regularly running git pull origin dev.

Anatomy of a Conflict Block

You will see this in your code editor (VS Code highlights conflicts with red/green indicators).

<<<<<<< HEAD (Your Current Change)
const buttonColor = 'blue';
// Your version
======= (Separator)
const buttonColor = 'red';
// Incoming version
>>>>>>> feature/new-design (Incoming Change)
Understanding the markers: <<<<<<< marks your changes, ======= separates the two versions, >>>>>>> marks incoming changes.

Step-by-Step Resolution

  1. 1
    Ensure you're on your feature branch git checkout feature/my-branch
  2. 2
    Pull latest changes from dev git pull origin dev

    This triggers the conflict if there are overlapping changes.

  3. 3
    Open your editor and locate conflicts

    VS Code highlights conflicts. Search for <<<<<< to find them quickly.

  4. 4
    Resolve each conflict

    Choose your version, incoming version, or combine both. Delete all conflict markers.

  5. 5
    Stage and commit the resolution git add . && git commit -m "fix: resolve merge conflicts"

VS Code Conflict Tools

  • • Click "Accept Current Change" to keep yours
  • • Click "Accept Incoming Change" to use theirs
  • • Click "Accept Both Changes" to combine
  • • Manually edit for complex resolutions

Best Practices

  • • Test after resolving conflicts
  • • Communicate with the other developer
  • • Don't just pick one side blindly
  • • Review the final code carefully

Emergency & Undo

Made a mistake? Don't panic. Git is very forgiving if you haven't pushed yet. Most mistakes can be undone safely.

⚠️ Important: These commands are safe if you haven't pushed. If you've already pushed, be more careful and consider using git revert instead.

Wrong Branch Commit

You committed to dev instead of your feature branch.

# 1. Undo commit, keep changes
git reset HEAD~1
# 2. Create correct branch
git checkout -b feature/correct-branch
# 3. Commit again
git add . && git commit -m "feat: ..."

Fix Commit Message

Typos or wrong message format in your last commit.

# ⚠️ Only if NOT pushed!
git commit --amend -m "feat: correct message"
# Or edit interactively
git commit --amend

Discard Local Changes

Revert file(s) to last committed state. ⚠️ Irreversible!

# Single file
git restore filename.js
# ⚠️ ALL changes (dangerous!)
git reset --hard HEAD

Check Current Status

Lost? Check where you are and what's changed.

# Current branch & status
git status
# List all branches
git branch
# Recent commits
git log --oneline -5

Undo Last Commit

Remove last commit but keep changes staged/unstaged.

# Keep changes staged
git reset --soft HEAD~1
# Keep changes unstaged
git reset HEAD~1

Unstage Files

Accidentally staged files? Unstage them.

# Unstage specific file
git restore --staged filename.js
# Unstage all files
git restore --staged .

If You've Already Pushed

If you've pushed your mistake, use git revert instead of git reset. Revert creates a new commit that undoes the mistake, which is safer for shared branches.

# Revert last commit (safe for pushed commits)
git revert HEAD

Git Commands Guide

Comprehensive reference for all Git commands organized by category. Click on a category to explore commands in that area.

💡 Tip: Hover over commands to see descriptions. Use the search to quickly find what you need.

Basic Commands

git init

Initialize a new Git repository in the current directory.

git clone <url>

Clone a remote repository to your local machine.

git add <file>

Stage a specific file for commit. Use git add . for all files.

git status

Show the working directory status and staged changes.

git config --global user.name "Name"

Set your Git username globally for all repositories.

git config --global user.email "email"

Set your Git email globally for all repositories.