# Git Workflow and Commit Message Convention for Contributing One Commit Per Lesson

> Learn the Git workflow and commit message convention for contributing one commit per lesson to rohitg00/ai-engineering-from-scratch. Ensure atomic history and focused reviews with feat(phase-NN/MM): lesson-slug format.

- Repository: [Rohit Ghumare/ai-engineering-from-scratch](https://github.com/rohitg00/ai-engineering-from-scratch)
- Tags: best-practices
- Published: 2026-08-31

---

**The rohitg00/ai-engineering-from-scratch repository enforces a strict one-commit-per-lesson policy using the conventional commit format `feat(phase-<NN>/<MM>): <lesson-slug>` to maintain atomic history, enable focused code reviews, and ensure each lesson receives proper attribution.**

Contributing educational content to the rohitg00/ai-engineering-from-scratch curriculum requires adhering to a precise Git workflow and commit message convention documented in the repository's hard rules. This workflow treats every lesson as a discrete unit of work, ensuring that the project history remains traceable and that automated systems can correctly ingest lesson metadata.

## The One-Commit-Per-Lesson Policy

According to [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md), the repository maintains a strict **one-commit-per-lesson** policy designed to keep reviews fast and ensure each lesson gets proper credit. When you modify or add content, a pull request that spans ten lessons must contain exactly ten separate commits—one for each lesson touched. This atomic approach prevents sprawling changes that span multiple educational units, allowing reviewers to focus on a single, coherent change set per commit.

## Conventional Commit Format

Every commit message must follow the **conventional-commit format** specified in [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md). The subject line structure is:

```

feat(phase-<NN>/<MM>): <lesson-slug>

```

- **`feat`** indicates a new feature (adding a lesson).
- **`phase-<NN>`** represents the phase number (e.g., `phase-05`).
- **`<MM>`** is the lesson number within that phase (e.g., `03`).
- **`<lesson-slug>`** is the kebab-case identifier matching the lesson directory name.
- The subject line must be **≤ 72 characters** to ensure readability in GitHub interfaces and command-line tools.

## Complete Git Workflow for Contributors

The full contribution process is defined in [`CONTRIBUTING.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/CONTRIBUTING.md) and requires strict adherence to branching, validation, and submission steps.

### Fork and Branch Strategy

Begin by forking the repository and creating a descriptive feature branch that identifies the lesson you are adding:

```bash
git checkout -b add-lesson-phase-05-03-gradient-descent

```

Branch names should follow the pattern `add-lesson-phase-<NN>-<slug>` to clearly indicate the scope of work.

### Local Development and Validation

Add your lesson files under the appropriate directory structure (`phases/<phase-slug>/<lesson-slug>/`). Before committing, validate your changes:

```bash

# Run language-specific tests

python3 -m unittest discover

# If modifying README.md or ROADMAP.md, verify site generation

node site/build.js

```

The site builder check is critical—the generated [`site/data.js`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/site/data.js) should only change timestamps, confirming that markdown tables and phase headers remain parsable by the CI pipeline.

### Committing Your Lesson

Stage and commit each lesson individually using the conventional format:

```bash
git add phases/05-optimization/03-gradient-descent
git commit -m "feat(phase-05/03): gradient-descent"

```

Each lesson directory corresponds to exactly one commit. If you update [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md) or [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) to reference the new lesson, those changes should be committed separately if they affect multiple lessons, or squashed appropriately following the one-commit-per-lesson rule for the specific lesson addition.

### Pull Request Requirements

Push your branch to your fork and open a pull request against the main repository:

```bash
git push origin add-lesson-phase-05-03-gradient-descent

```

Your PR description must clearly explain what the lesson adds and confirm that you have run local tests. Reviewers will verify that the PR contains exactly one commit per lesson modified and that all commit messages comply with the 72-character limit and conventional format.

## Preserving Site Generation Contracts

The repository uses automated systems to parse [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md) and [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md) for the website. When you edit these files to add lesson metadata or update the curriculum roadmap, you must run `node site/build.js` locally afterward. As documented in [`CONTRIBUTING.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/CONTRIBUTING.md), this verification step ensures that the markdown tables and phase headers remain compatible with the CI pipeline's ingestion logic, preventing build failures that would break the published site.

## Summary

- **One commit per lesson** is mandatory according to [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md), ensuring atomic changes and clean attribution.
- Use the format **`feat(phase-<NN>/<MM>): <lesson-slug>`** with a strict 72-character limit for all commit messages.
- Create feature branches named **`add-lesson-phase-<NN>-<slug>`** to organize your contribution workflow.
- Validate site generation integrity by running **`node site/build.js`** whenever modifying [`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md) or [`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md).
- Each lesson lives in **`phases/<phase-slug>/<lesson-slug>/`** and must be committed as a discrete unit.

## Frequently Asked Questions

### What happens if I combine multiple lessons into a single commit?

Violating the one-commit-per-lesson policy outlined in [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md) complicates the review process and prevents proper attribution for individual lessons. PRs containing multi-lesson commits will be rejected until split into atomic commits, as this ensures reviewers can evaluate each educational unit independently and the history remains traceable.

### How should I format commit messages when fixing an existing lesson?

Use the **`fix`** type prefix instead of `feat` while maintaining the same scope format: `fix(phase-<NN>/<MM>): <lesson-slug>`. The 72-character limit and structural requirements remain identical, ensuring consistency across the repository's history whether you are adding new content or correcting existing material.

### Why is there a 72-character limit on commit subject lines?

The character limit ensures readability across all Git interfaces, including command-line terminals, GitHub web views, and automated email notifications. As specified in [`AGENTS.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/AGENTS.md), this constraint prevents truncation and forces contributors to write concise, descriptive summaries that clearly identify the lesson being modified.

### Do I need to run the site builder for every contribution?

You only need to execute `node site/build.js` when modifying **[`README.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/README.md)** or **[`ROADMAP.md`](https://github.com/rohitg00/ai-engineering-from-scratch/blob/main/ROADMAP.md)**, as these files feed the website's data layer. If you are only adding or modifying lesson content within the `phases/` directory without touching the metadata files, running the standard test suite (`python3 -m unittest discover` or equivalent) is sufficient for validation.