commit Git Command Guide
The git commit command records changes to the repository by creating a new commit object that captures the current state of the index (staging area) along with a descriptive commit message. It serves as the fundamental operation for saving work and creating version history.
git commit Syntax:
Section titled “git commit Syntax:”git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend] [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|reword):]<commit>)] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] [--date=<date>] [--cleanup=<mode>] [--status | --no-status] [-S[<keyid>]] [--no-gpg-sign] [--] [<pathspec>...]Commit Message Options:
Section titled “Commit Message Options:”| Option | Description |
|---|---|
-m <msg>, --message=<msg> | Use given message as commit message |
-F <file>, --file=<file> | Read commit message from file |
-C <commit>, --reuse-message=<commit> | Reuse message from specified commit |
-c <commit>, --reedit-message=<commit> | Reuse and edit message from commit |
--squash=<commit> | Create squash commit message |
--fixup=<commit> | Create fixup commit message |
Staging Integration Options:
Section titled “Staging Integration Options:”| Option | Description |
|---|---|
-a, --all | Stage all modified/deleted files before commit |
--interactive | Interactively stage changes for commit |
--patch | Interactively choose hunks to commit |
--only | Commit only specified files (ignore staged changes) |
Commit Modification Options:
Section titled “Commit Modification Options:”| Option | Description |
|---|---|
--amend | Amend previous commit instead of creating new one |
--reset-author | Reset author information when amending |
--allow-empty | Allow empty commits with no changes |
--allow-empty-message | Allow commits with empty messages |
Output and Verification Options:
Section titled “Output and Verification Options:”| Option | Description |
|---|---|
-v, --verbose | Show diff of changes in commit |
--dry-run | Show what would be committed without committing |
--short | Show short status when doing dry run |
--porcelain | Machine-readable output format |
-q, --quiet | Suppress summary message |
--no-status | Don’t include status in commit message template |
Security and Signing Options:
Section titled “Security and Signing Options:”| Option | Description |
|---|---|
-S[<keyid>], --gpg-sign[=<keyid>] | GPG-sign the commit |
--no-gpg-sign | Don’t GPG-sign the commit |
-s, --signoff | Add Signed-off-by trailer |
--no-signoff | Don’t add Signed-off-by trailer |
Advanced Options:
Section titled “Advanced Options:”| Option | Description |
|---|---|
--author=<author> | Override commit author |
--date=<date> | Override author date |
--cleanup=<mode> | How to clean up commit message |
--no-verify | Skip pre-commit hooks |
-e, --edit | Force edit of commit message |
--pathspec-from-file=<file> | Read pathspecs from file |
--pathspec-file-nul | Use NUL as path separator |
Parameters:
Section titled “Parameters:”| Parameter | Description |
|---|---|
<pathspec> | Limit commit to specific files |
Understanding Commits:
Section titled “Understanding Commits:”Commit Structure:
Section titled “Commit Structure:”Git Commit Object:├── Tree: Snapshot of files at commit time├── Parent(s): Reference(s) to previous commit(s)├── Author: Who wrote the code (name, email, timestamp)├── Committer: Who created the commit (name, email, timestamp)├── Message: Description of changes└── Signature: Optional GPG signature
Commit Creation Process:1. Validate staged changes exist2. Create tree object from index3. Generate commit object with metadata4. Update current branch reference5. Run post-commit hooksCommit Types:
Section titled “Commit Types:”Commit Categories:├── Regular Commits: Normal commits with changes├── Merge Commits: Commits with multiple parents├── Empty Commits: Commits with no changes (--allow-empty)├── Signed Commits: GPG-signed for verification├── Fixup Commits: Auto-squashed commits (--fixup)└── Squash Commits: Combined commits (--squash)Commit Message Best Practices:
Section titled “Commit Message Best Practices:”Effective Commit Messages:├── Subject: Brief, imperative mood (<50 chars)├── Body: Detailed explanation (optional)├── Footer: Issue references, co-authors├── Format: Conventional commits (feat:, fix:, docs:)├── Clarity: Explain what and why, not how
Example Format:feat: add user authentication system
- Implement JWT token validation- Add password hashing with bcrypt- Create user registration endpoint
Closes #123Basic Commit Operations:
Section titled “Basic Commit Operations:”Standard Commits:
Section titled “Standard Commits:”# Commit staged changes with messagegit commit -m "Add user authentication feature"
# Commit with detailed messagegit commit -m "Fix database connection timeout
- Increase connection pool size- Add retry logic for failed connections- Update error handling"
# Commit all modified filesgit commit -a -m "Update documentation"
# Commit specific files onlygit commit file1.txt file2.py -m "Fix critical bug"Interactive Commits:
Section titled “Interactive Commits:”# Interactively stage and commitgit commit --interactive
# Patch mode for selective hunk committinggit commit --patch
# Verbose commit with diff reviewgit commit -vCommit Modification:
Section titled “Commit Modification:”# Amend last commit messagegit commit --amend -m "Updated commit message"
# Amend last commit with new changesgit add new-file.txtgit commit --amend --no-edit
# Change author informationgit commit --amend --reset-author --no-edit
# Amend with new authorgit commit --amend --author="New Author <new@example.com>"Advanced Commit Scenarios:
Section titled “Advanced Commit Scenarios:”Signed Commits:
Section titled “Signed Commits:”# GPG sign commitgit commit -S -m "Security fix"
# Sign with specific keygit commit -S<keyid> -m "Important change"
# Add signoff trailergit commit -s -m "Contributed change"
# Configure automatic signinggit config commit.gpgsign truegit config user.signingkey <keyid>Empty and Special Commits:
Section titled “Empty and Special Commits:”# Allow empty commitgit commit --allow-empty -m "Release version 1.0.0"
# Create annotated tag commitgit commit --allow-empty -m "Tag: v1.0.0"
# Fixup commit for later squashinggit commit --fixup HEAD~2
# Squash commit for later merginggit commit --squash HEAD~3Batch and Automated Commits:
Section titled “Batch and Automated Commits:”# Commit from file messageecho "Automated commit" > commit-msg.txtgit commit -F commit-msg.txt
# Batch commit with pathspecsgit commit --pathspec-from-file=files-to-commit.txt
# Automated commits in scriptsif git diff --quiet; then echo "No changes to commit"else git commit -a -m "Automated: $(date)"fiCommit Message Templates:
Section titled “Commit Message Templates:”# Use commit message templategit config commit.template ~/.git-commit-template
# Template file content:# [type]: [description]## [body]## [footer]
# Commit with templategit commit # Opens editor with templateConfiguration and Best Practices:
Section titled “Configuration and Best Practices:”Git Configuration for Commits:
Section titled “Git Configuration for Commits:”# Configure commit behaviorgit config commit.verbose true # Always show diffgit config commit.cleanup strip # Clean whitespacegit config commit.gpgsign true # Auto-sign commitsgit config commit.status true # Show status in editor
# Configure commit message templategit config commit.template ~/.git-commit-template
# Configure hooksgit config core.hooksPath ~/.git-hooks # Custom hooks locationCommit Best Practices:
Section titled “Commit Best Practices:”# Always review before committinggit status # Check staged changesgit diff --cached # Review changesgit diff --check # Check whitespace issues
# Use meaningful commit messagesgit commit -m "feat: add user login functionality
- Implement OAuth2 authentication- Add password reset feature- Create user session management
Fixes #456"
# Commit frequently but logicallygit add feature-file.pygit commit -m "feat: implement core algorithm"
git add tests/git commit -m "test: add comprehensive test suite"Recovery from Commit Mistakes:
Section titled “Recovery from Commit Mistakes:”# Undo last commit (keep changes staged)git reset --soft HEAD~1
# Undo last commit (keep changes unstaged)git reset HEAD~1
# Undo last commit (discard changes)git reset --hard HEAD~1
# Amend commit without changing messagegit commit --amend --no-edit
# Fix commit authorgit commit --amend --reset-author --no-editIntegration with Development Workflows:
Section titled “Integration with Development Workflows:”Feature Branch Workflow:
Section titled “Feature Branch Workflow:”#!/bin/bash# Feature branch commit workflow
feature_commit() { local feature_name="$1"
# Ensure on feature branch current_branch=$(git rev-parse --abbrev-ref HEAD) if [[ "$current_branch" != "feature/$feature_name" ]]; then echo "Not on feature branch" return 1 fi
# Stage all changes git add --all
# Check for issues if ! git diff --cached --quiet; then # Commit with conventional format git commit -m "feat: implement $feature_name
- Add core functionality - Include tests - Update documentation
Refs: #$feature_name" else echo "No changes to commit" fi}
feature_commit "user-dashboard"CI/CD Integration:
Section titled “CI/CD Integration:”# Automated commits in CI/CDci_commit() { echo "CI/CD automated commit"
# Stage all changes git add --all
# Configure git for CI git config user.name "CI Bot" git config user.email "ci@company.com"
# Create automated commit if git diff --cached --quiet; then echo "No changes to commit" else git commit -m "ci: automated commit $(date +%Y%m%d-%H%M%S)
Build: $BUILD_NUMBER Branch: $BRANCH_NAME Trigger: $COMMIT_MESSAGE" fi}
ci_commitCode Review Workflow:
Section titled “Code Review Workflow:”# Prepare commits for code reviewreview_commit() { echo "Preparing commits for code review"
# Ensure clean working tree if ! git diff --quiet || ! git diff --cached --quiet; then echo "Working tree not clean. Commit or stash changes first." return 1 fi
# Create fixup commits for review feedback echo "Creating fixup commits for review comments..."
# Example: Fix review comment about error handling git commit --fixup HEAD~2 -m "fixup: improve error handling"
# Example: Add missing tests git add test-file.py git commit -m "test: add missing test cases"
echo "Review preparation complete"}
review_commitTroubleshooting Common Issues:
Section titled “Troubleshooting Common Issues:”Commit Message Issues:
Section titled “Commit Message Issues:”# Fix commit messagegit commit --amend -m "Corrected commit message"
# Edit commit message in editorgit commit --amend
# Reuse message from another commitgit commit --reuse-message=HEAD~2
# Clean up messy commit messagegit commit --cleanup=stripStaged Changes Issues:
Section titled “Staged Changes Issues:”# Commit fails - check staged changesgit status
# Nothing staged - stage changes firstgit add file.txtgit commit -m "Add file"
# Too many changes - commit in partsgit add --patchgit commit -m "Partial commit"Hook Issues:
Section titled “Hook Issues:”# Skip hooks for urgent commitsgit commit --no-verify -m "Urgent fix"
# Debug hook issuesgit config core.hooksPath /dev/null # Temporarily disablegit commit -m "Test commit"
# Check hook permissionsls -la .git/hooks/pre-commitchmod +x .git/hooks/pre-commitAuthor and Date Issues:
Section titled “Author and Date Issues:”# Fix author informationgit commit --amend --author="Correct Name <correct@email.com>"
# Override commit dategit commit --date="2023-01-01 12:00:00" -m "Backdated commit"
# Reset author to current usergit commit --amend --reset-author --no-editMerge Conflict Resolution:
Section titled “Merge Conflict Resolution:”# Commit after resolving conflictsgit add resolved-file.txtgit commit -m "Resolve merge conflicts
- Fixed conflicts in file.txt- Updated merge strategy- Verified functionality"
# Empty merge commitgit commit --allow-empty -m "Merge branch 'feature'"Large Commit Issues:
Section titled “Large Commit Issues:”# Split large commitsgit reset HEAD~1 # Uncommit but keep changesgit add --patch # Stage in partsgit commit -m "Part 1 of large change"git commit -a -m "Part 2 of large change"
# Check commit sizegit show --stat HEADEncoding and Character Issues:
Section titled “Encoding and Character Issues:”# Handle encoding problemsexport LANG=en_US.UTF-8git commit -m "Message with special chars: àáâãäå"
# Fix encoding in existing commitgit commit --amend --no-edit # Re-commit with correct encodingDetached HEAD Issues:
Section titled “Detached HEAD Issues:”# Commit in detached HEAD stategit commit -m "Changes in detached HEAD"
# Create branch from detached HEADgit checkout -b temp-branchgit checkout maingit merge temp-branch
# Discard detached HEAD commitsgit checkout main # Returns to branchReal-World Usage Examples:
Section titled “Real-World Usage Examples:”Conventional Commits Workflow:
Section titled “Conventional Commits Workflow:”#!/bin/bash# Conventional commits implementation
conventional_commit() { local type="$1" local scope="$2" local description="$3"
# Validate commit type valid_types=("feat" "fix" "docs" "style" "refactor" "test" "chore" "perf" "ci" "build" "revert") if [[ ! " ${valid_types[@]} " =~ " ${type} " ]]; then echo "Invalid commit type: $type" echo "Valid types: ${valid_types[*]}" return 1 fi
# Format commit message if [ -n "$scope" ]; then message="$type($scope): $description" else message="$type: $description" fi
# Add breaking change indicator if needed if [[ "$description" == *"BREAKING CHANGE"* ]]; then message="$message
BREAKING CHANGE: ${description#*BREAKING CHANGE: }" fi
# Commit with formatted message git commit -m "$message"
echo "Committed: $message"}
# Usage examplesconventional_commit "feat" "auth" "add JWT token validation"conventional_commit "fix" "" "resolve memory leak in cache"conventional_commit "docs" "api" "update endpoint documentation"Release Management:
Section titled “Release Management:”# Release commit automationrelease_commit() { local version="$1" local changes="$2"
echo "Creating release commit for version $version"
# Ensure clean working tree if ! git diff --quiet --cached; then echo "Staged changes exist. Commit or reset first." return 1 fi
# Create release commit git commit --allow-empty -m "chore: release version $version
Release Notes:$changes
---Generated by release scriptVersion: $versionDate: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
# Tag the release git tag -a "v$version" -m "Release version $version
$changes"
echo "Release $version committed and tagged"}
release_commit "2.1.0" "- Added new API endpoints- Fixed authentication bug- Improved performance"Automated Changelog Generation:
Section titled “Automated Changelog Generation:”# Generate changelog from commitsgenerate_changelog() { local since_tag="$1" local output_file="${2:-CHANGELOG.md}"
echo "# Changelog" > "$output_file" echo "" >> "$output_file"
# Get commits since tag git log --pretty=format:"* %s (%h)" "$since_tag..HEAD" >> "$output_file"
echo "" >> "$output_file" echo "Generated from commits since $since_tag" >> "$output_file"
echo "Changelog generated: $output_file"}
generate_changelog "v1.0.0"Commit Message Linting:
Section titled “Commit Message Linting:”# Lint commit messageslint_commit_message() { local message="$1"
# Check length if [ ${#message} -gt 72 ]; then echo "Warning: Subject line too long (>72 chars)" fi
# Check format if [[ ! "$message" =~ ^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: ]]; then echo "Warning: Message doesn't follow conventional format" fi
# Check for empty message if [ -z "$message" ]; then echo "Error: Empty commit message" return 1 fi
echo "Commit message validation passed"}
# Pre-commit hook integrationcat > .git/hooks/commit-msg << 'EOF'#!/bin/bashlint_commit_message "$(cat $1)"EOFchmod +x .git/hooks/commit-msgBulk Commit Operations:
Section titled “Bulk Commit Operations:”# Bulk commit operationsbulk_commit() { local operation="$1"
case "$operation" in "squash") # Squash last N commits local count="$2" git reset --soft HEAD~"$count" git commit -m "Squash last $count commits" ;;
"fixup") # Create fixup commits for multiple commits local base_commit="$2" shift 2 local commits_to_fix=("$@")
for commit in "${commits_to_fix[@]}"; do git commit --fixup "$commit" done
# Auto-squash git rebase -i --autosquash "$base_commit" ;;
"reorder") # Reorder commits interactively git rebase -i HEAD~10 ;; esac}
bulk_commit "squash" 3bulk_commit "fixup" "main" "abc123" "def456"Repository Health Monitoring:
Section titled “Repository Health Monitoring:”# Monitor commit healthcommit_health_check() { echo "=== Commit Health Report ==="
# Check recent commits echo "Recent commits:" git log --oneline -10
# Check for large commits echo "Potentially large commits:" git rev-list --objects HEAD | \ git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' | \ awk '/^blob/ {print substr($0, 6)}' | \ sort -k2nr | \ head -10 | \ while read -r hash size path; do if [ "$size" -gt 1048576 ]; then # 1MB echo "Large file: $path ($size bytes)" fi done
# Check commit message quality echo "Commit message analysis:" git log --oneline -20 | while read -r line; do commit_msg=$(echo "$line" | cut -d' ' -f2-) if [ ${#commit_msg} -lt 10 ]; then echo "Short message: $commit_msg" fi done
# Check for signed commits signed_count=$(git log --show-signature -20 | grep -c "gpg:") echo "Signed commits in last 20: $signed_count"
echo "Health check complete"}
commit_health_checkWhat’s the difference between git commit -a and git commit?
Section titled “What’s the difference between git commit -a and git commit?”git commit -a automatically stages all modified and deleted files before committing; git commit only commits already staged changes.
How do I change the commit message after committing?
Section titled “How do I change the commit message after committing?”Use git commit —amend -m “new message” to change the last commit message.
Can I commit only part of a file’s changes?
Section titled “Can I commit only part of a file’s changes?”Yes, use git add —patch to stage specific hunks, then git commit to commit only those staged changes.
What’s the difference between —amend and creating a new commit?
Section titled “What’s the difference between —amend and creating a new commit?”—amend replaces the last commit instead of creating a new one, effectively rewriting history for that commit.
How do I commit without running pre-commit hooks?
Section titled “How do I commit without running pre-commit hooks?”Use git commit —no-verify to skip pre-commit hooks.
Can I commit with an empty message?
Section titled “Can I commit with an empty message?”Use git commit —allow-empty-message -m "" but this is generally not recommended.
How do I see what changes will be committed?
Section titled “How do I see what changes will be committed?”Use git diff —cached to see staged changes that will be committed.
What’s the difference between author and committer?
Section titled “What’s the difference between author and committer?”Author is who wrote the code; committer is who created the commit (usually the same person).
Can I commit with a future date?
Section titled “Can I commit with a future date?”Use git commit —date=“2024-01-01 12:00:00” to override the commit date.
How do I create a commit that doesn’t change anything?
Section titled “How do I create a commit that doesn’t change anything?”Use git commit —allow-empty -m “message” for commits with no file changes.
Can I sign commits with GPG?
Section titled “Can I sign commits with GPG?”Yes, use git commit -S to GPG-sign commits for verification.
How do I reuse a commit message?
Section titled “How do I reuse a commit message?”Use git commit -C
What’s —fixup used for?
Section titled “What’s —fixup used for?”—fixup creates a commit that will be automatically squashed with the specified commit during rebase —autosquash.
Can I commit specific files without staging others?
Section titled “Can I commit specific files without staging others?”Yes, use git commit
How do I change the author of a commit?
Section titled “How do I change the author of a commit?”Use git commit —amend —author=“New Author
What’s the —reset-author option for?
Section titled “What’s the —reset-author option for?”—reset-author updates the author information to match the current git config when amending commits.
Can I see a verbose diff when committing?
Section titled “Can I see a verbose diff when committing?”Yes, use git commit -v to show the diff of all changes in the commit message editor.
How do I create a dry run commit?
Section titled “How do I create a dry run commit?”Use git commit —dry-run to see what would be committed without actually creating the commit.
What’s the difference between -C and -c options?
Section titled “What’s the difference between -C and -c options?”-C reuses the commit message exactly; -c opens the editor to modify the reused message.
Can I commit with a custom cleanup mode?
Section titled “Can I commit with a custom cleanup mode?”Use git commit —cleanup=strip to clean up the commit message (remove trailing whitespace, etc.).
How do I add a signoff to commits?
Section titled “How do I add a signoff to commits?”Use git commit -s to add a “Signed-off-by:” trailer to the commit message.
Can I commit from a file containing the message?
Section titled “Can I commit from a file containing the message?”Yes, use git commit -F
What’s the —pathspec-from-file option for?
Section titled “What’s the —pathspec-from-file option for?”—pathspec-from-file allows reading file paths to commit from a file instead of command line arguments.
How do I create a squash commit?
Section titled “How do I create a squash commit?”Use git commit —squash=
Can I override the commit date?
Section titled “Can I override the commit date?”Yes, use git commit —date=
What’s the —porcelain option for?
Section titled “What’s the —porcelain option for?”—porcelain provides machine-readable output format for scripting purposes.
How do I suppress commit output?
Section titled “How do I suppress commit output?”Use git commit -q or —quiet to suppress the commit summary message.
Can I use commit templates?
Section titled “Can I use commit templates?”Yes, set git config commit.template
What’s the —untracked-files option for?
Section titled “What’s the —untracked-files option for?”—untracked-files shows untracked files in the commit message editor status.
How do I handle merge commits?
Section titled “How do I handle merge commits?”After resolving conflicts, use git commit without -m to get the default merge commit message.
Can I commit during a rebase?
Section titled “Can I commit during a rebase?”During interactive rebase, use git commit —amend to modify commits, or git rebase —continue after editing.
What’s the —short option for?
Section titled “What’s the —short option for?”—short provides shorter output format when doing dry runs.
How do I create an empty commit?
Section titled “How do I create an empty commit?”Use git commit —allow-empty -m “message” to create a commit with no changes.
Can I verify commits after creation?
Section titled “Can I verify commits after creation?”Use git verify-commit
Applications of the git commit command
Section titled “Applications of the git commit command”- Version Control: Recording project milestones and changes
- Collaboration: Preparing changes for code review and merging
- Documentation: Creating meaningful commit history with descriptive messages
- Release Management: Tagging releases and version points
- Bug Tracking: Associating commits with issue tracking systems
- Audit Trail: Maintaining verifiable history of code changes
- Continuous Integration: Automated commit creation in CI/CD pipelines
- Code Review: Preparing atomic, reviewable changes