ARM64 OS Handbook
🔍

Chapter 45: Git Workflow

What You Will Learn in This Chapter
  • How to structure branches and commits for a team project
  • How to write good commit messages
  • How to use feature branches and code review
  • How to resolve merge conflicts
  • The release and tagging strategy
  • How to set up CI for the kernel

45.1 Branch Strategy

We follow a simplified trunk-based development model with short-lived feature branches:

BranchPurpose
mainStable, reviewed, tested. Protected branch.
feature/<name>Feature branches. One per developer per feature. Short-lived (1-3 days).
fix/<name>Bug fix branches. Same rules as feature branches.
release/v*Release branches. Created at each milestone (v0.1, v0.2, etc.).

Rules:

  • Never commit directly to main
  • Feature branches are merged via pull request with at least one review
  • Delete feature branches after merging
  • Keep branches up to date with main (rebase, not merge)

45.2 Commit Messages

Every commit message follows the conventional format:

component: short summary (50 chars or less)

Detailed explanation of what changed and why. Wrap at 72
characters. Explain the motivation, not just the change.

If the change fixes a bug, reference the issue number:
Fixes: #42

Signed-off-by: Your Name <email@example.com>

Examples of good commit messages:

uart: fix character drop on fast input

The UART RX interrupt handler was not reading the data register
fast enough when characters arrived back-to-back. The fix reads
all available characters in a loop before returning from the
handler, using the RX FIFO level status bit.

Fixes: #18
Signed-off-by: Alice <alice@example.com>

mm: add physical page allocator

Implements a buddy allocator for physical memory with orders
0 through 10. Supports allocation and freeing of individual
pages and contiguous ranges. No virtual memory mapping yet;
the allocator returns physical addresses only.

Signed-off-by: Bob <bob@example.com>

Commit message rules:

  • First line must be 50 characters or fewer
  • First line uses past tense ("added", "fixed", not "adds", "fixes")
  • Include the subsystem prefix (e.g., "uart:", "mm:", "sched:")
  • Blank line between subject and body
  • Body wraps at 72 columns
  • Explain WHY, not just WHAT
  • Reference issue numbers when applicable

45.3 Feature Branch Workflow

# Start a new feature
git checkout main
git pull origin main
git checkout -b feature/page-cache

# Work on the feature
git add kernel/mm/page_cache.c kernel/include/mm/page_cache.h
git commit -m "mm: add page cache data structure"

git add kernel/mm/page_cache.c
git commit -m "mm: implement page cache lookup and insert"

# Keep branch up to date
git fetch origin
git rebase origin/main

# If conflicts occur:
#   - Resolve them in your editor
#   - git add <resolved files>
#   - git rebase --continue

# Push and create a pull request
git push -u origin feature/page-cache
# On GitHub/GitLab: create PR, request review

45.4 Code Review Checklist

Before requesting review, verify:

  • Code compiles without warnings (-Wall -Wextra -Werror)
  • clang-format produces no diffs
  • All existing tests pass
  • New code has corresponding tests
  • No dead code, commented-out code, or debugging prints left in
  • Error paths are handled (no unchecked kmalloc return values)
  • No magic numbers: use named constants or macros
  • Memory allocations have matching frees (no leaks)
  • Lock ordering is consistent (no deadlock risk)

45.5 Merging Strategy

We use squash merge for feature branches. All commits from the feature branch are combined into a single commit on main:

# Merge (via GitHub/GitLab UI, or command line):
git checkout main
git merge --squash feature/page-cache
git commit -m "mm: add page cache subsystem"
git push origin main

# Delete the feature branch (local and remote):
git branch -d feature/page-cache
git push origin --delete feature/page-cache

Squash merging keeps the main branch history clean and linear, while allowing detailed commits during development. Each commit on main represents a complete, reviewed feature.

45.6 Tagging and Releases

Releases are tagged with semantic versioning:

# Tag a release
git tag -a v0.1.0 -m "v0.1.0: Boots to shell with UART support"
git push origin v0.1.0

# Version format: vMAJOR.MINOR.PATCH
# MAJOR: breaking changes
# MINOR: new features (backward compatible)
# PATCH: bug fixes (backward compatible)

45.7 CI Pipeline

Our CI pipeline (GitHub Actions) runs on every push to a feature branch and on every PR:

# .github/workflows/kernel.yml
name: Kernel CI
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Install toolchain
        run: sudo apt install gcc-aarch64-linux-gnu qemu-system-arm
      - name: Build kernel
        run: make
      - name: Run host tests
        run: make test-host
      - name: Run QEMU tests
        run: make test-qemu
      - name: Check formatting
        run: clang-format --dry-run --Werror kernel/**/*.c kernel/**/*.h

45.8 Our Workflow Summary

StepAction
1Create a feature branch from main
2Commit changes with descriptive messages
3Push branch and create a pull request
4Request review from at least one teammate
5Address review feedback in new commits
6Squash merge to main after approval
7Delete the feature branch
8Tag releases at milestones

45.9 Exercises

Exercise 1: Simulate a Merge Conflict

Create two branches that modify the same line in a file. Practice resolving the conflict manually and with a merge tool.

Exercise 2: Squash Commits

Make three related commits on a branch, then squash them into one using git rebase -i. Verify the commit history is clean.

Exercise 3: Set Up CI

Create a GitHub Actions workflow (or similar) for the kernel that builds and runs the host-based unit tests on every push.

45.10 Summary

A consistent git workflow keeps the team organized and the codebase stable. Feature branches isolate work in progress. Meaningful commit messages document the history. Code review ensures quality before merging. Squash merging keeps the main branch linear. CI automation catches regressions early. Following this workflow allows five developers to collaborate on the kernel without stepping on each other's work.