Lesson 06 / 15
Writing Commit Messages
The message structure made up of the subject line, the blank separator, and the body; recording the rationale, and how tools make use of the message format.
Contents
Three commits have been written, and all three had a one-line message. This is enough for small changes; but the reason for a fix, the options tried and abandoned, or the grounds for a design decision do not fit on one line. This lesson defines the message’s structure.
The commit message is not a formality; it is the one free-text field that determines whether history can be read. What a line does is read from the code; why it was written that way is read only from the message.
The Message’s Structure
The message has three parts:
Subject line: a summary of the change Body: the rationale for the change. What the problem was, why this solution was chosen, and which options were ruled out are written here. A second paragraph is added if needed.
What separates the parts is the first blank line, and this separator is a formal rule: tools read the first line as the subject and everything after the blank line as the body. If no blank line is inserted, the entire text counts as the subject and gets squeezed onto a single line in summary listings.
How tools use this distinction can be seen directly. %s gives the subject line,
%b the body:
git log -1 --format='%s' 43370ca
Üç veri yapısı terimi ekle
git log -1 --format='%b' 43370ca
Ağaç, karma tablosu ve bağlı liste terimleri listede yoktu; bu terimler sorulduğunda arama betiği boş çıktı veriyordu. Karşılıklar Veri Yapıları kursunun sözlüğüyle aynı biçimde yazıldı.
The Subject Line
Four rules are settled for the subject line:
- Written in the imperative mood. “Sort the term list,” not “Sorted the term list” or “I sorted the term list.” The reason is formal: tool-generated messages are also imperative (“Revert “…””, “Merge …”), so history reads in one grammatical mood. Test: the subject line should complete “If applied, this commit will: ….”
- Kept to around fifty characters. There is no hard limit, but the line gets truncated in summary listings and narrow interfaces. A subject line over fifty characters is often a sign the commit holds more than one piece of work.
- Not ended with a period. It is a title, not a sentence.
- States what changed, not how. The detail is the body’s job.
The Body
The question the body answers is not “what was done” but “why it was done.” The change itself is already visible in the diff; what is not visible in the diff is the situation that required that change.
A useful body includes:
- The problem. Which behavior was wrong, or which need went unmet?
- The rationale. Why was this path chosen?
- Options ruled out. An approach tried and abandoned, so the same path is not retried.
- Known limits. Situations the solution does not cover.
Lines are wrapped by hand at around seventy-two characters. The reason is that git log’s output writes the message body with a four-space indent: to avoid overflow in
an eighty-column space, the body itself has to be narrower.
Example
Three terms are added to the term list, and the message is written in an editor.
When git commit is run with no option, the configured text editor opens; once the
file is saved and closed, its content becomes the message. If it is left empty, no
commit is written.
Üç veri yapısı terimi ekle Ağaç, karma tablosu ve bağlı liste terimleri listede yoktu; bu terimler sorulduğunda arama betiği boş çıktı veriyordu. Karşılıklar Veri Yapıları kursunun sözlüğüyle aynı biçimde yazıldı.
The subject line says what was done; the body records why the terms were considered missing and where the equivalents came from. Both are pieces of information that cannot be extracted from the code.
A second example belongs to a fix in the search script:
Aramayı büyük/küçük harften bağımsız yap Terimler listede küçük harfle tutuluyor. Kullanıcı "Yığıt" yazdığında arama boş dönüyor, terim listede olduğu hâlde bulunamıyordu. grep çağrısına -i seçeneği eklendi; bu seçenek POSIX'te tanımlıdır ve ek bağımlılık getirmez.
This message records more than the one-line diff itself: why the -i option was
added, and why another solution — uppercasing the list, say — was not chosen instead.
What Not to Write
Some message patterns add nothing to history:
- Subject lines that repeat the content. “terimler.txt updated” — already visible in the diff. Write the work done, not the file name.
- Status patterns. “wip,” “temporary,” “fix.” These do not say what the commit does and leave no searchable trace.
- A bare external number, with no context. A message with only a ticket number is empty for a reader without access to that system. A number goes in the body, with a one-sentence summary of the problem.
- Subject lines that count more than one job. The “and” in “Added X and fixed Y” is a sign the commit should be split.
The last item shows how the commit message ties back to the atomic-commit habit: when a good subject line cannot be written, the problem is most often not in the message but in the commit’s scope.
Ways to Give the Message
| Way | Use |
|---|---|
git commit |
Opens the editor; the usual way for a multi-line message |
git commit -m "subject" |
A one-line message |
git commit -m "subject" -m "body" |
Each -m becomes a paragraph, with a blank line inserted between them |
git commit -F file |
The message is read from a file |
The template that opens in the editor has lines starting with #; these are
excluded from the message and summarize the current state. Reading this summary
before writing is the cheapest way to notice the wrong files were staged.
Result
git log --oneline
60e13bd Aramayı büyük/küçük harften bağımsız yap 43370ca Üç veri yapısı terimi ekle 3132c78 Biçim örneğindeki yazımı düzelt 546c174 Terim arama betiği ekle 13d31bf Terim listesini ve biçim belgesini ekle
Five lines describe the project’s five steps in readable form. This readability comes directly from two habits: every commit holding a single piece of work, and every subject line summarizing that work in the imperative. Break either one, and the list loses its value.
A Message Is a Search Field
Messages are not just read, they are also searched. The subject and body text can be filtered:
git log --oneline --grep="arama"
60e13bd Aramayı büyük/küçük harften bağımsız yap 43370ca Üç veri yapısı terimi ekle 546c174 Terim arama betiği ekle
The search is done letter for letter; word stems are not recognized. This detail stands out in this repository’s Turkish commit messages:
git log --oneline --grep="betik"
The command returns no lines, even though history holds the commit “Terim arama
betiği ekle” (Add term search script). The reason is Turkish consonant softening:
when a suffix attaches to “betik” (script), the final k softens to ğ, so
“betiği” never contains the substring “betik” at all. A shortened pattern does
return a result:
git log --oneline --grep="beti"
43370ca Üç veri yapısı terimi ekle 546c174 Terim arama betiği ekle
Because --grep matches substrings literally rather than recognizing word stems,
this kind of miss can arise in any language whose suffixes alter the stem; Turkish
consonant softening is the case this repository’s history happens to show. It makes
choosing subject-line words that resist this kind of alteration a practical
necessity.
Summary
- The message is made up of a subject line and a body; the first blank line separates the two, and tools rely on this separation.
- The subject line is written in the imperative mood, at around fifty characters, with no period.
- The body answers “why,” not “what”: the statement of the problem, the rationale for the solution, options ruled out, and known limits.
- Body lines are wrapped at around seventy-two characters;
git log’s output writes the body indented. - Messages can be searched with
--grep; this turns writing subject lines consistently into a practical necessity.
Next Step
History has reached five commits and was listed with git log --oneline. But
listing is only the simplest form of reading history: commits touching a specific
file, commits adding or removing specific text, and a specific time range can each
be queried separately. The next lesson takes up the tools for reading history.
To keep your progress and take notes, Log in
My notes
Log in to take notes.