Git Workflow

You are helping with a git operation or workflow question: $ARGUMENTS

Apply the rules below based on the specific operation needed. Every git operation you perform or advise must be reversible by default — flag destructive operations explicitly before executing.


1. Branching Strategy

Use a trunk-based or GitFlow-lite strategy depending on team size:

For most teams (trunk-based with short-lived branches):

main          ← always deployable, protected
  └── feature/user-authentication
  └── fix/password-reset-email
  └── chore/update-dependencies
  └── refactor/extract-payment-service

Branch naming rules:

  • feature/short-description — new functionality
  • fix/short-description — bug fixes
  • hotfix/short-description — urgent production fixes (branch from main, merge back to main)
  • chore/short-description — dependency updates, tooling, no behaviour change
  • refactor/short-description — code restructuring, no behaviour change
  • docs/short-description — documentation only

Branch lifetime: Feature branches must merge within 2 days. If longer, the feature is too large — break it down.


2. Commit Conventions

All commits use Conventional Commits format:

<type>(<scope>): <description>

[optional body: explain the WHY, not the WHAT]

[optional footer: BREAKING CHANGE: ..., Closes #123]
Types: Type Use for
feat New feature visible to users
fix Bug fix
test Adding or fixing tests
refactor Code restructuring — no behaviour change
perf Performance improvement
docs Documentation only
chore Build, deps, tooling — no src change
ci CI/CD configuration changes
revert Reverting a previous commit

Good commit messages:

feat(auth): add two-factor authentication via TOTP

- Users can enable 2FA from Account Settings
- Uses TOTP-compatible apps (Authy, Google Authenticator)
- Backup codes generated at enrollment

Closes #142
fix(checkout): correct tax calculation for EU VAT exempt customers

Root cause: the exemption flag was checked after tax was applied
instead of before. Exempt customers were charged 20% VAT incorrectly.

Regression test added: tests/Checkout/TaxCalculationTest.php

Anti-patterns:

  • fix stuff — meaningless
  • WIP — never commit WIP to shared branches
  • asdfasdf — obvious
  • Update file.php — describes what git already knows

3. Common Operations

Starting a new feature

git checkout main
git pull origin main
git checkout -b feature/my-feature-name

Keeping your branch up to date (prefer rebase over merge)

git fetch origin
git rebase origin/main   # reapplies your commits on top of latest main
# If conflicts arise, resolve each one then:
git rebase --continue

Squashing commits before PR (clean up noisy WIP commits)

# Squash last 4 commits into one clean commit
git rebase -i HEAD~4
# In the editor: change 'pick' to 'squash' for commits 2-4
# Write a clean commit message

Viewing what you're about to push

git log origin/main..HEAD --oneline    # commits not yet in main
git diff origin/main...HEAD            # all file changes vs main

Undoing things (safest first)

# Undo last commit but keep changes staged
git reset --soft HEAD~1

# Undo last commit and unstage changes (files still modified)
git reset HEAD~1

# Revert a pushed commit without rewriting history (SAFE for shared branches)
git revert abc1234

# ⚠️ DESTRUCTIVE — discard all uncommitted changes
git restore .

# ⚠️ DESTRUCTIVE — discard a specific file's changes
git restore src/specific-file.php

4. Pull Request Standards

A PR must contain all of the following before requesting review:

PR description template:

## What
[One paragraph: what does this change do?]

## Why
[One paragraph: why is this needed? Link to issue/ticket]

## How
[Optional: any non-obvious implementation choices]

## Testing
- [ ] Unit tests added/updated
- [ ] Manual testing performed: [describe what you tested]
- [ ] No regressions introduced

## Checklist
- [ ] Code follows project conventions
- [ ] Documentation updated if needed
- [ ] No secrets or debug output left in
- [ ] CI passes

PR size guidelines:

  • Ideal: < 400 lines changed
  • Acceptable: 400-800 lines
  • Too large (split it): > 800 lines

5. Conflict Resolution

# When rebase conflicts occur, for each conflicted file:

# 1. See what's conflicting
git status
git diff

# 2. Open the file — three markers:
<<<<<<< HEAD              # your changes
code you changed
=======
code from main branch
>>>>>>> origin/main

# 3. Edit the file to the correct final state (remove all markers)
# 4. Stage the resolved file
git add path/to/resolved-file.php

# 5. Continue rebase
git rebase --continue

# If it's too messy and you want to start over:
git rebase --abort

Conflict resolution principles:

  • Take both changes if both are independently correct
  • Understand what each branch was trying to do before deciding
  • When in doubt, run the tests after resolution
  • Never accept "theirs" or "ours" blindly without reading both

6. Tagging Releases

# Create an annotated tag (the right kind for releases)
git tag -a v1.2.0 -m "Release v1.2.0 — see CHANGELOG.md"
git push origin v1.2.0

# List all tags
git tag -l --sort=-creatordate | head -10

# Check what changed between two releases
git log v1.1.0..v1.2.0 --oneline
git diff v1.1.0 v1.2.0 -- src/

Semantic versioning rules:

  • MAJOR.MINOR.PATCH (e.g., 2.4.1)
  • PATCH: Bug fixes, no API change
  • MINOR: New features, backward compatible
  • MAJOR: Breaking changes

7. Git Bisect — Finding Which Commit Introduced a Bug

# Start bisect session
git bisect start
git bisect bad                  # current HEAD is broken
git bisect good v1.1.0          # v1.1.0 was known good

# git checks out a midpoint commit — run your test:
# If this commit is broken:
git bisect bad
# If this commit is fine:
git bisect good

# Repeat until git prints "first bad commit is abc1234"
git bisect reset   # exit bisect mode