Mert Özen Further With Every Line
Software Architecture Bookstore: The Site's Example Application — #03

The Bookstore Repo and Reading Map: Where Is the Code and Which Part Is in Which Series?

Mert Özen Nov 14, 2026 9 min 4 views
The Bookstore Repo and Reading Map: Where Is the Code and Which Part Is in Which Series?

Bookstore's code lives in a single GitHub repo: main is the reference application, every series is a series/<series-slug> branch and every post a <series-slug>/NN tag. We cover getting a post's code with git switch --detach, seeing the difference between two posts with git diff, experimenting on your own branch, and reading paths for backend, frontend, architecture and team leads.

Version note: The Git commands in this post were tested with Git 2.54; the outputs come from a small test repository set up with the same layout as the real one.

Guess First: Getting the Code of a Post

You are reading the fourth post of the TDD series and want to run its code on your own machine. You have cloned the repo of Bookstore, the online bookstore used as the shared example across this site's series, and you know every post has a tag. The command you type and the answer you get:

git switch tdd/04
fatal: a branch is expected, got tag 'tdd/04'
hint: If you want to detach HEAD at the commit, try again with the --detach option.

Three questions. Why does Git object? If you follow its advice, switch with --detach, make a change and commit it, where does that commit go? And what is the shortest way to see what the fourth post changed compared to the third?

The Repo's Layout: main, Series Branches and Tags

Since every series on the site works on the same Bookstore, the code lives in a single GitHub repo as well. Its address:

https://github.com/mrtozn1923/bookstore

The repo will be at this address once it is opened on the site owner's account; it may not be reachable yet on the day this post is published. Its layout rests on three rules:

  • main: the reference application. The Catalog, Ordering and Inventory core described in the second post of this series, its tests and the Angular client.
  • series/<series-slug>: one branch per series. A series starts from the reference application and adds its own topic on this branch.
  • <series-slug>/NN: every post on a series branch is one commit plus a tag that marks it. tdd/04 is the complete code as it stands at the end of the fourth post of the TDD series.

A tag in Git is a fixed name given to a specific commit; unlike a branch, it does not move. On the day you read the post and a year later, tdd/04 points at the same code. A branch shows the latest state of the series and moves forward as new posts are added. Posts without code, like the first and third posts of this series, have no code state of their own.

That difference is also the reason for the error in Guess First. git switch is designed for moving between branches; switching to a tag means switching to a commit that belongs to no branch. Git's documentation calls this a "detached HEAD" and recommends the --detach option for inspection and throwaway experiments. The command asks for an explicit confirmation to protect you.

Getting the Code of a Post

Cloning the whole repo and switching to the tag you want is the most general way:

git clone https://github.com/mrtozn1923/bookstore.git
cd bookstore
git switch --detach tdd/04
HEAD is now at 849a754 tdd/04

The working folder now holds the code from the end of the fourth post. The run steps are in the post itself and in the README at the root of the repo; those for the reference application are in the second post of this series. To see which tags exist:

git tag --list "tdd/*"

If you only want the history of one series, you can limit the clone to its branch. A repo cloned with --single-branch also receives the tags that point at that branch's commits:

git clone --branch series/tdd --single-branch https://github.com/mrtozn1923/bookstore.git bookstore-tdd

If you cloned the repo earlier, git fetch --tags is enough to get the tags of new posts. To work with the latest state of a series branch, type git switch series/tdd; in a full clone Git creates a local branch with the same name from the remote branch.

Seeing the Difference Between Two Posts

Since every post is a tag, the answer to "what did this post change?" is a diff:

git diff --stat tdd/03 tdd/04
git diff tdd/03 tdd/04 -- src/

The first shows the list of changed files with line counts, the second shows only the changes under src/. To see what changed over the whole series, compare the series branch with main:

git log --oneline main..origin/series/tdd
git diff --stat main origin/series/tdd

main..origin/series/tdd lists the commits that are on the series branch but not on main; each line is one post. You can make the same comparison on GitHub's compare page in the web interface by picking two tags. The layout has a writer's side too: since each post contains only its own change, the diff stays short and readable, and what the post explains matches the part of the code that changed.

Doing Your Own Experiments on a Separate Branch

You can switch to a tag with --detach and start experimenting, but the commits you make there belong to no branch. When you move somewhere else, Git warns you:

Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  b010824 my experiment

If you want to keep it by creating a new branch, this may be a good time
to do so with:

 git branch <new-branch-name> b010824

After a while that commit can disappear when Git cleans up. This is the answer to the second question in Guess First: the commit goes to no branch. If you want to keep your experiment, open your own branch from the start:

git switch -c my/tdd-04-experiment tdd/04

We use the my/ prefix to keep your own branches apart from the series branches; it is not required, it just keeps the list tidy. If you want the code of two posts open side by side, git worktree gives you a second working folder:

git worktree add ../bookstore-tdd-03 tdd/03

This folder also opens with a detached HEAD and shares the same repo; no second clone is needed. When you are done, remove it with git worktree remove ../bookstore-tdd-03. The details of these Git commands are in the Git & GitHub series.

The Reading Map: Where to Start?

The first two posts of this series are enough to get to know Bookstore. What comes next depends on your interests. The paths below are suggestions; the series can be read independently, and every post briefly introduces Bookstore again where it first appears.

Backend developer

Start with C# Fundamentals and continue with C# Object-Oriented Programming, LINQ and C# Asynchronous Programming. Then move to the ASP.NET Core Web API series for the Web API side, the Entity Framework Core series for data access, and SQL Fundamentals. For testing, Unit Testing and TDD, followed by Integration and E2E Testing. On the security side, the Web Security (OWASP Top 10), API Security (OWASP API Top 10), ASP.NET Core Security and Authentication and Authorization series work on the same API. As Bookstore grows it needs Caching, Background Jobs and Scheduled Jobs, Working with Message Queues and Logging in .NET.

Frontend developer

HTML5 and Semantic HTML, then JavaScript Basics, Intermediate and Advanced, and TypeScript Basics, Intermediate and Advanced. The foundations of the topics in bookstore-web are in the Angular series; the RxJS and State Management in Angular series go deeper into cart and catalog state, the Frontend Testing series tests the same pages, and the Frontend Security series covers vulnerabilities on the browser side.

Interested in architecture

Introduction to Architecture explains why Bookstore started as a monolith and which quality targets drive its growth. After SOLID and Design Principles and Data Modeling and Normalization come Clean, Onion and Hexagonal Architecture, Vertical Slice Architecture and Domain-Driven Design. Module boundaries are covered in Modular Monolith, events in Messaging and Event-Driven Architecture, separate read and write models for the ordering side in CQRS and Event Sourcing, and the split into services in Microservices. The Distributed Systems Fundamentals, System Design and Architecture Decisions series show these decisions at large scale and how they are recorded.

Team lead

The Bookstore team works in the SDLC, Agile Mindset, Scrum and Kanban series. Introduction to Product Management and Requirements Analysis tell how the Institutional Orders feature came about; Estimation and Planning estimates and plans the same work. On the code side, the Test Strategy, Code Review and Coding Conventions and Team Standards series discuss the team's shared rules.

Which Part of Bookstore Is in Which Series?

If you prefer to read the same map by part:

Part of BookstoreSeries that cover the topic
Product, roles, business rulesPost 01 of this series, Requirements Analysis, Domain-Driven Design
Data model and SQL Server schemaData Modeling and Normalization, SQL Fundamentals, SQL Server in Depth
BookstoreContext and data accessEntity Framework Core, Dapper
Bookstore.ApiASP.NET Core Web API, ASP.NET Core Security, API Security (OWASP API Top 10)
Identity and rolesAuthentication and Authorization
bookstore-webAngular, RxJS, State Management in Angular, Frontend Testing
TestsUnit Testing, TDD, Integration and E2E Testing
Events and NotificationsMessaging and Event-Driven Architecture, Working with Message Queues, Background Jobs and Scheduled Jobs
Module boundaries and splittingModular Monolith, Microservices, .NET Microservices Application
Build and deployGit & GitHub, CI/CD Fundamentals, GitHub Actions, Kubernetes, Deployment Strategies; the upcoming Docker and Docker Compose series
Performance and cacheCaching, Performance and Load Testing; the upcoming Redis series

The series named in the table are either published or being written now; some of the published ones explain the topic with another example that was chosen before Bookstore. The ones marked "upcoming" are planned but not written yet; once published, they will have their own branches in the same repo.

What Is in the Repo Today, and What Is Not?

An honest picture: the repo is new and not all of the code is in it yet. The reference application on main is ready. Series written from now on add their code post by post, directly on their own branches. The code of series published earlier is being added step by step; in those posts the example code currently lives inside the post, and some of it is written as short self-contained programs rather than following the repo's layout.

In some older posts you may also see an example other than Bookstore, most often an HR portal. The mapping is in the first post of this series: company, department and employee are Institution, InstitutionUnit and InstitutionUser in Bookstore; a leave or purchase approval is PurchaseApproval. The quickest way to see whether a series has a branch is to clone the repo and list the remote branches with git branch -r.

Common Pitfalls

Switching to a tag and continuing to work there. Commits on a detached HEAD belong to no branch; to avoid losing your work, open your own branch with git switch -c before you start experimenting.

Taking the latest state of the series branch for the code of a post. series/tdd shows the series' last post; if you are reading the fourth post you should switch to tdd/04, or you will see code that has not been explained yet.

Trying to merge series branches into each other. Every series departs from main in its own direction; the changes of two series were not designed to work together. If you want to combine ideas from two series, do it by hand and on purpose on your own branch.

Cloning the repo and typing dotnet run right away. The reference application expects a SQL Server and a connection string; the steps are in the README and in the second post of this series. Put the connection string in user-secrets, not in the repo's appsettings.json, or your password leaves with your first commit.

Treating the parts missing from the repo today as errors. If an older published series has no branch, its code simply has not been moved yet; the code inside the post still works.

A Small Experiment

★☆☆ Once the repo is open, clone it and list the series branches with git branch -r and the tags with git tag --list. How many series branches are there, and which one has the most tags?

★★☆ Pick two consecutive tags of a series and look at the changed files with git diff --stat. Then read that post and compare the diff with the changes it describes: is there a file in the diff that the post does not mention?

★★★ Choose a path from the reading map, open a branch with the my/ prefix and collect your experiments along the way there. Whenever you finish a series, compare it with main and write a paragraph summarizing your own changes.

This is where the series ends: we have seen Bookstore's product side, its technical structure and where its code lives. Whichever series you read next, the Book, Order or StockItem you meet is part of the application you got to know in these three posts; when something is unclear, this series is the place to come back to.