summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacob Walls <jacobtylerwalls@gmail.com>2026-03-05 12:14:59 -0500
committernessita <124304+nessita@users.noreply.github.com>2026-03-06 17:55:01 -0300
commitc27d368b92f321e6f91704f554dccbc18df5b075 (patch)
treeb92d6e2623213917e668f1ed84076b2da0077ae4
parent9adc205b6d0269a81ce93a7e6d6b0f375f6bd526 (diff)
Extended checks and docs for proper commit message format and edition.
Thanks to Tim Schilling for the review. Co-authored-by: Natalia <124304+nessita@users.noreply.github.com>
-rw-r--r--.github/pull_request_template.md2
-rw-r--r--.github/workflows/check_commit_messages.yml36
-rw-r--r--docs/internals/contributing/committing-code.txt36
-rw-r--r--docs/internals/contributing/writing-code/working-with-git.txt49
4 files changed, 103 insertions, 20 deletions
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index 7efa2f1384..0d30fbbced 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -16,7 +16,7 @@ Provide a concise overview of the issue or rationale behind the proposed changes
- [ ] This PR follows the [contribution guidelines](https://docs.djangoproject.com/en/stable/internals/contributing/writing-code/submitting-patches/).
- [ ] This PR **does not** disclose a security vulnerability (see [vulnerability reporting](https://docs.djangoproject.com/en/stable/internals/security/)).
- [ ] This PR targets the `main` branch. <!-- Backports will be evaluated and done by mergers, when necessary. -->
-- [ ] The commit message is written in past tense, mentions the ticket number, and ends with a period.
+- [ ] The commit message is written in past tense, mentions the ticket number, and ends with a period (see [guidelines](https://docs.djangoproject.com/en/dev/internals/contributing/committing-code/#committing-guidelines)).
- [ ] I have checked the "Has patch" ticket flag in the Trac system.
- [ ] I have added or updated relevant tests.
- [ ] I have added or updated relevant docs, including release notes if applicable.
diff --git a/.github/workflows/check_commit_messages.yml b/.github/workflows/check_commit_messages.yml
index 32f1558464..590cc58de3 100644
--- a/.github/workflows/check_commit_messages.yml
+++ b/.github/workflows/check_commit_messages.yml
@@ -68,3 +68,39 @@ jobs:
fi
echo "✅ All commits have the required prefix."
+
+ check-commit-suffix:
+ runs-on: ubuntu-latest
+ timeout-minutes: 60
+ steps:
+ - uses: actions/checkout@v6
+ with:
+ persist-credentials: false
+
+ - name: Fetch relevant branches
+ run: |
+ git fetch origin $BASE:base
+ git fetch origin pull/${{ github.event.pull_request.number }}/head:pr
+
+ - name: Check commit messages suffix
+ run: |
+ COMMITS=$(git rev-list base..pr)
+ echo "Checking commit messages for trailing period"
+ FAIL=0
+ for SHA in $COMMITS; do
+ MSG=$(git log -1 --pretty=%s $SHA)
+ echo "Checking commit $SHA: $MSG"
+ if [[ "${MSG: -1}" != "." ]]; then
+ echo "❌ Commit $SHA must end with a period."
+ echo "Refer to the guidelines linked in the PR checklist for commit message format."
+ echo "For how to rewrite commit messages, see https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/working-with-git/#editing-commit-messages"
+ FAIL=1
+ fi
+ done
+
+ if [[ $FAIL -eq 1 ]]; then
+ echo "One or more commit messages are missing a trailing period."
+ exit 1
+ fi
+
+ echo "✅ All commits have the required trailing period."
diff --git a/docs/internals/contributing/committing-code.txt b/docs/internals/contributing/committing-code.txt
index 3cf2554926..413745e644 100644
--- a/docs/internals/contributing/committing-code.txt
+++ b/docs/internals/contributing/committing-code.txt
@@ -3,8 +3,10 @@ Committing code
===============
This section is addressed to the mergers and to anyone interested in knowing
-how code gets committed into Django. If you're a community member who wants to
-contribute code to Django, look at
+how code gets committed into Django. The :ref:`committing-guidelines` apply
+to all contributors, with or without commit rights.
+
+If you're a community member who wants to contribute code to Django, look at
:doc:`/internals/contributing/writing-code/working-with-git` instead.
.. _handling-pull-requests:
@@ -102,8 +104,8 @@ community, getting work done, and having a usable commit history.
Committing guidelines
=====================
-In addition, please follow the following guidelines when committing code to
-Django's Git repository:
+These guidelines apply to all commits to Django's Git repository, whether
+submitted by a contributor via a pull request or landed directly by a merger:
* Never change the published history of ``django/django`` branches by force
pushing. If you absolutely must (for security reasons for example), first
@@ -119,16 +121,27 @@ Django's Git repository:
discussions immediately, so you may have to wait a couple of days before
getting a response.
-* Write detailed commit messages in the past tense, not present tense.
+* Write detailed commit messages in the past tense, not present tense, and
+ end the subject line with a period.
- * Good: "Fixed Unicode bug in RSS API."
- * Bad: "Fixes Unicode bug in RSS API."
- * Bad: "Fixing Unicode bug in RSS API."
+ * Correct: "Fixed Unicode bug in RSS API."
+ * Incorrect: "Fixes Unicode bug in RSS API." (present tense)
+ * Incorrect: "Fixing Unicode bug in RSS API." ("-ing" form)
+ * Incorrect: "Fixed Unicode bug in RSS API" (missing trailing period)
The commit message should be in lines of 72 chars maximum. There should be
a subject line, separated by a blank line and then paragraphs of 72 char
- lines. The limits are soft. For the subject line, shorter is better. In the
- body of the commit message more detail is better than less:
+ lines. The limits are soft. For the subject line, shorter is better.
+
+ In the body of the commit message more detail is better than less, and should
+ explain *why* the change was made, not *what* was changed or *how*. The code
+ itself shows what changed; the commit message should provide the context and
+ reasoning that the code cannot.
+
+ Credit the contributors in the commit message: "Thanks A for the report and B
+ for review." Use git's `Co-Authored-By`_ as appropriate.
+
+ For example:
.. code-block:: none
@@ -138,8 +151,7 @@ Django's Git repository:
specific tasks. Added guidelines of how to use Git, GitHub, and
how to use pull request together with Trac instead.
- Credit the contributors in the commit message: "Thanks A for the report and B
- for review." Use git's `Co-Authored-By`_ as appropriate.
+ Thanks to Full Name for the report, and to Reviewer for reviews.
.. _Co-Authored-By: https://docs.github.com/en/pull-requests/committing-changes-to-your-project/creating-and-editing-commits/creating-a-commit-with-multiple-authors
diff --git a/docs/internals/contributing/writing-code/working-with-git.txt b/docs/internals/contributing/writing-code/working-with-git.txt
index 15ab7054aa..3691b9cf2f 100644
--- a/docs/internals/contributing/writing-code/working-with-git.txt
+++ b/docs/internals/contributing/writing-code/working-with-git.txt
@@ -111,7 +111,7 @@ necessary:
.. code-block:: shell
- git commit -m 'Added two more tests for edge cases'
+ git commit -m 'Added two more tests for edge cases.'
Publishing work
---------------
@@ -163,11 +163,46 @@ will deal with your pull request has only two options: merge it or close it.
For this reason, it isn't useful to make a pull request until the code is ready
for merging -- or sufficiently close that a merger will finish it themselves.
+.. _editing-commit-messages:
+
+Editing commit messages
+-----------------------
+
+To change the message of the most recent commit, run:
+
+.. code-block:: shell
+
+ git commit --amend
+
+This opens an editor with the current commit message. Edit it, save, and close
+to update the commit.
+
+To change the message of an earlier commit, use the "reword" option in
+interactive rebase. For example, to reword one of the last three commits:
+
+.. code-block:: shell
+
+ git rebase -i HEAD~3
+
+This opens an editor listing the three commits, each prefixed with the word
+"pick". Change "pick" to "reword" (or "r") on the line of the commit you want
+to change, then save and close. A new editor will open for each commit marked
+as "reword", allowing you to update the message.
+
+See :ref:`committing-guidelines` for the required commit message format.
+
+After rewriting a commit that has already been pushed to GitHub, you will need
+to force-push your branch:
+
+.. code-block:: shell
+
+ git push --force-with-lease origin ticket_xxxxx
+
Rebasing branches
-----------------
-In the example above, you created two commits, the "Fixed ticket_xxxxx" commit
-and "Added two more tests" commit.
+In the example above, you created two commits, the "Fixed #xxxxx -- ..."
+commit and the "Added two more tests ..." commit.
We do not want to have the entire history of your working process in your
repository. Your commit "Added two more tests" would be unhelpful noise.
@@ -208,7 +243,7 @@ the changes:
.. code-block:: shell
- git push -f origin ticket_xxxxx
+ git push --force-with-lease origin ticket_xxxxx
Note that this will rewrite history of ticket_xxxxx - if you check the commit
hashes before and after the operation at GitHub you will notice that the commit
@@ -264,10 +299,10 @@ of:
.. code-block:: text
- Made changes asked in review by <reviewer>
+ Made changes asked in review by <reviewer>.
- - Fixed whitespace errors in foobar
- - Reworded the docstring of bar()
+ - Fixed whitespace errors in foobar.
+ - Reworded the docstring of bar().
Finally, push your work back to your GitHub repository. Since you didn't touch
the public commits during the rebase, you should not need to force-push: