Skip to content

Latest commit

 

History

History
200 lines (149 loc) · 5.82 KB

File metadata and controls

200 lines (149 loc) · 5.82 KB

Git Workflow: Rebase-Only, Linear History

Core Principle: We maintain a strict linear history in master. NEVER merge from master to branches - always rebase instead to avoid merge commits and keep history clean.

Note: All commands below are supported by IDE Git integrations (IntelliJ, VSCode, etc.). This section uses command-line examples for clarity, but the same operations work in any modern IDE.

Initial Git Configuration

Required: Configure git to use rebase by default to prevent accidental merge commits:

# Check current setting
git config --get pull.rebase

# Set globally (recommended)
git config --global pull.rebase true

# Or set for this repository only
git config --local pull.rebase true

The output of the first command should be true. If not, run one of the configuration commands above.

Branch-Based Development Workflow

Rule 1: Always work in feature branches. Direct commits to master are prohibited. Rule 2: Always rebase your branch on top of latest master. Never merge master into your branch.

1. Create and Set Up Your Feature Branch

# Create new branch from latest master
git checkout master
git pull                                    # This will rebase thanks to pull.rebase=true
git checkout -b feature/descriptive-name   # Use descriptive names

# Push and set upstream tracking
git push --set-upstream origin feature/descriptive-name

2. Work on Your Changes

# Make changes and commit frequently
git add .
git commit -m "Add feature X functionality"

# Push your work regularly
git push

3. Keep Your Branch Current (Critical Step)

Before creating a PR, and anytime master moves ahead, rebase your branch:

# Fetch latest changes from all remotes
git fetch origin

# Rebase your branch on top of latest master
git rebase origin/master

If conflicts occur during rebase:

  1. Fix conflicts in your editor
  2. Test that everything still builds: ./gradlew build
  3. Continue the rebase:
    git add .
    git rebase --continue
  4. If you get stuck, abort and ask for help:
    git rebase --abort

After successful rebase, force-push (this is safe and necessary):

git push --force-with-lease  # Safer than git push -f

4. Clean Up Your Commits (Before PR)

Use interactive rebase to create clean, logical commits:

# Interactive rebase for last n commits
git rebase -i HEAD~3  # Example: last 3 commits

# In the editor, you can:
# - squash: combine commits
# - reword: change commit message
# - drop: remove commits
# - reorder: change commit order

PR Quality Standards:

  • Each commit should build and pass tests
  • Commit messages should be descriptive
  • Related changes should be in the same commit
  • Unrelated changes should be in separate commits
  • No "fix typo", "wip", or broken commits

5. Create Pull Request

# Final push after cleanup
git push --force-with-lease

# Create PR using GitHub CLI (optional)
gh pr create --title "Add feature X" --body "Description of changes"

What NOT to Do

NEVER do these things:

# DON'T: Merge master into your branch
git merge master                    # This creates merge commits!
git pull origin master             # This might create merge commits!

# DON'T: Work directly on master
git checkout master
git commit -m "direct change"      # Use branches instead!

# DON'T: Create merge commits
git merge feature/my-branch        # Maintainers handle PR merging

ALWAYS do these instead:

# DO: Rebase your branch on master
git rebase origin/master

# DO: Use pull with rebase configured
git pull                           # Safe with pull.rebase=true

# DO: Work in branches
git checkout -b feature/my-change

Emergency: Fixing a Broken Rebase

If you get into a confusing state during rebase:

# 1. Abort the rebase to start over
git rebase --abort

# 2. Make sure you have the latest master
git fetch origin

# 3. Try again with a clean approach
git rebase origin/master

# 4. If still stuck, ask for help on the team chat

GitHub Branch Protection Settings

For Repository Administrators: Configure GitHub to enforce this workflow:

Settings -> Branches -> Add rule for master branch:

  • "Restrict pushes that create merge commits"
  • "Require pull request reviews before merging"
  • "Require status checks to pass before merging"
  • "Require branches to be up to date before merging"
  • "Include administrators" (enforce rules for everyone)

GitHub CLI setup (for administrators):

# Enable branch protection with merge commit prevention
gh api repos/xtclang/xvm/branches/master/protection \
  --method PUT \
  --field required_status_checks='{"strict":true,"checks":[]}' \
  --field enforce_admins=true \
  --field required_pull_request_reviews='{"required_approving_review_count":1}' \
  --field restrictions=null \
  --field allow_force_pushes=false \
  --field allow_deletions=false \
  --field block_creations=false \
  --field required_linear_history=true

The required_linear_history=true setting blocks merge commits and enforces the rebase-only workflow.

Why This Workflow Matters

Benefits of linear history:

  • Easy to follow: git log --oneline shows clear chronological development
  • Simple debugging: git bisect works reliably to find bugs
  • Clean commits: Each commit represents a logical change
  • Fast builds: CI doesn't waste time on merge commit combinations
  • Clear blame: git blame points to actual changes, not merge commits

Problems with merge commits:

  • Complex history: Hard to understand what actually changed
  • Difficult bisection: Merge commits create confusing paths
  • CI overhead: More commit combinations to test
  • Unclear metrics: Commit counts and author statistics get distorted