In the world of Git, COMMIT_EDITMSG is the temporary staging ground where your intentions meet the repository history. If you've ever run git commit without the -m flag and saw a text editor pop up, you were looking at this file. What is COMMIT_EDITMSG? COMMIT_EDITMSG is a temporary file stored in your .git/ directory. When you initiate a commit, Git generates this file to hold your commit message while you edit it. Once you save the file and close your editor, Git reads the content, finishes the commit, and then clears the file for the next time. Why You’ll See It The Default Behavior : Running git commit (without flags) automatically opens COMMIT_EDITMSG in your system's default editor (like Vim, Nano, or VS Code). A "Safety" Stop : If you forget to include a message using -m , Git forces this file open to ensure you don't leave an empty (and therefore invalid) commit message. Amending History : When you run git commit --amend , Git pulls your previous message back into this file so you can tweak it before finalizing. How to Master the Buffer While it might seem like a minor technical detail, COMMIT_EDITMSG is where you should practice good "Git hygiene" using the 50/72 Rule : Improving Your Commit Message with the 50/72 Rule - DEV Community
The Unsung Hero of Version Control: Mastering the COMMIT-EDITMSG File In the daily life of a developer using Git, few things are as simultaneously ubiquitous and ignored as the COMMIT-EDITMSG file. It flashes on your screen for a few seconds, you type a line, save, and move on. But beneath this transient text file lies a powerful, flexible tool that can transform your team’s collaboration, automate tedious tasks, and even serve as a referee for code quality. Most developers never look inside this file. They see the editor window pop up, assume it’s just a blank text box, and type git commit -m "fix bug" . They are missing the point entirely. If you want to master Git, you must first master the COMMIT-EDITMSG . This article will explore what it is, why it exists, how to customize it, and how to leverage its hidden features to become a more effective developer. What Exactly Is COMMIT-EDITMSG ? At its core, COMMIT-EDITMSG is a temporary text file that Git creates in your local .git directory. Specifically, you can find it at .git/COMMIT_EDITMSG . When you run a command like git commit (without the -m flag), Git opens your default text editor and loads the contents of this file. But here is the crucial insight: That file is not a message. It is a transaction. The COMMIT-EDITMSG represents the final step before a commit object is permanently written to your repository’s object database. You are not just "typing a message"; you are editing the metadata that will be cryptographically hashed and stored forever (or until a rebase). When you save and close your editor, Git reads the contents of .git/COMMIT_EDITMSG , validates it, creates the commit object using that text as the subject and body, and then deletes the temporary file. Anatomy of a Default COMMIT-EDITMSG Open a new terminal, navigate to a Git repository, and run git commit without any arguments. Your editor will open, and you will see something like this: # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # # On branch main # Your branch is up to date with 'origin/main'. # # Changes to be committed: # modified: src/main.py # new file: src/utils.py # # Changes not staged for commit: # modified: README.md # # Untracked files: # temp.log #
This is the default template. Notice a few critical features:
Comments ( # ) : Any line starting with # is ignored by Git. These are for your information only. The Blank First Line : The very first line of the file (before any # ) is the commit subject . The second line must be blank. The third line onward (non-commented) is the commit body . Status Context : Git automatically includes the output of git status (commented out) to remind you what you are committing. COMMIT-EDITMSG
The COMMIT_EDITMSG file is the only place where you can seamlessly write a multi-line, detailed commit message without using shell escape sequences or awkward string quoting. Why You Should Stop Using git commit -m The -m flag is convenient for tiny changes, but it actively works against best practices. Here’s why the COMMIT_EDITMSG workflow is superior: 1. The 50/72 Rule Conventional wisdom (and the Git project itself) recommends:
First line: 50 characters or less. Second line: Blank. Subsequent lines: Wrapped at 72 characters.
With git commit -m "short" -m "body" , you cannot easily see the character count or wrap text. In your editor, your .vimrc or VS Code settings can enforce these rules automatically. The COMMIT_EDITMSG file gives you a full editing environment. 2. Mental Context Switching Typing git commit -m "Fix the thing in the service layer that was causing the race condition between the producer and consumer threads..." is error-prone. You must craft the message before the editor opens. The COMMIT_EDITMSG workflow allows you to open the file, look at the diff (via git status comments), then write the perfect message. 3. Multi-Line Bodies Great commits tell a story. They explain why a change was made, not just what changed. Good commit bodies might contain multiple paragraphs, bullet points, Signed-off-by trailers, or references to issue trackers. Trying to format this in a shell is a nightmare. Hooks: The Secret Superpower of COMMIT-EDITMSG The COMMIT-EDITMSG file is not just static text. Git provides a hook system—scripts that run at specific points in the commit lifecycle. The most important hook for our keyword is the commit-msg hook . Located at .git/hooks/commit-msg (or in a shared template), this script runs after you have edited the COMMIT-EDITMSG file but before Git creates the commit. Why is this revolutionary? Because you can programmatically validate or modify the commit message. Example 1: Enforcing a Convention with commit-msg Let’s write a simple commit-msg hook that rejects any commit whose subject line does not start with a JIRA ticket number (e.g., PROJ-123: Fix the bug ): #!/bin/bash # .git/hooks/commit-msg COMMIT_MSG_FILE=$1 Read the first line of the COMMIT_EDITMSG file read -r subject < "$COMMIT_MSG_FILE" Regex pattern for a JIRA ticket pattern="^[A-Z]+-[0-9]+: .+" if [[ ! $subject =~ $pattern ]]; then echo "ERROR: Commit message subject must start with a JIRA ticket (e.g., PROJ-123: Your message)" exit 1 fi exit 0 In the world of Git, COMMIT_EDITMSG is the
Now, every time you save your COMMIT_EDITMSG , this script runs. If you forget the ticket number, Git aborts the commit. The file remains in .git/COMMIT_EDITMSG so you can edit it and retry. Example 2: Automatic Trailer Addition Perhaps you want every commit to include a Co-authored-by: trailer. Your commit-msg hook could append it automatically: #!/bin/bash COMMIT_MSG_FILE=$1 Append a trailer only if it doesn't already exist if ! grep -q "^Co-authored-by:" "$COMMIT_MSG_FILE"; then echo "" >> "$COMMIT_MSG_FILE" echo "Co-authored-by: Jane Doe <jane@example.com>" >> "$COMMIT_MSG_FILE" fi
You are directly manipulating the COMMIT_EDITMSG file. This is legal, safe, and incredibly powerful. Templates: Pre-Filling the COMMIT-EDITMSG You can also create a template file that Git will automatically copy into .git/COMMIT_EDITMSG every time you run git commit . This is great for team standards. Set a global template: git config --global commit.template ~/.gitmessage.txt
Now create ~/.gitmessage.txt : # <subject> (max 50 chars) # |<---- 50 chars ---->| # # <body> (wrap at 72 chars, explain what and why, not how) # |<---- 72 chars ---->| # # Issue: #<number> # Signed-off-by: <your name> COMMIT_EDITMSG is a temporary file stored in your
Here are the files you are about to commit:
Now, every time you run git commit , your COMMIT_EDITMSG is pre-populated with this scaffolding. You just fill in the blanks. This dramatically improves commit quality across a team. The Danger Zone: Manual Editing of .git/COMMIT_EDITMSG Because COMMIT_EDITMSG is just a text file, you can technically edit it directly without using git commit . For example: echo "Hotfix: Resolve null pointer exception" > .git/COMMIT_EDITMSG git commit --no-edit