git commit: How to Make a Commit

By
Bosko Marijan
Published:
May 22, 2025
Topics:

Git is a version control system that allows users to record snapshots of their work, known as commits, which makes it easier to review progress, fix mistakes, and understand when and why changes were made.

Regular commits are important because they keep a project history organized and allow you to revert to previous versions if something goes wrong. It also helps your team stay aligned, as everyone can see what's been changed, by whom, and for what purpose.

In this tutorial, you will learn what a Git commit is, how to create, undo, and update a commit.

git commit: How to Make a Commit

Prerequisites

What Is git commit?

The git commit command creates a saved snapshot of your project's tracked files at a specific point in time. Each commit records the exact state of those files and the metadata, such as:

  • The commit author.
  • The timestamp.
  • Parent commit(s).
  • A descriptive message that states what changes were made and why.

Commits are identified by a unique SHA-1 hash. Once created, they are immutable unless you explicitly rewrite Git history, ensuring every recorded state remains intact and verifiable.

In practice, users first stage changes with git add, and then make a commit to capture those staged changes in a new snapshot. This workflow builds a safe, chronological history that you can traverse to inspect or restore earlier versions, collaborate by branching and merging without overwriting others' work, and revert problematic changes if needed.

Thoughtful, focused commits with clear messages form a human-readable narrative of your project's evolution and make tracking, collaboration, and debugging far more efficient.

How Does git commit Work?

At its core, a Git commit captures a snapshot (a complete record of the current state) of your project's tracked files in the local repository. Snapshots are the primary building blocks of Git's timeline.

To create a commit, you must first stage changes with git add, followed by the git commit command to write a new commit object that contains:

  • A tree pointer to the snapshot of file contents.
  • Parent commit hash(es).
  • Author and timestamp metadata.
  • Your descriptive commit message.

Unlike centralized systems (e.g., SVN), Git's commits never touch the central repository until you explicitly push them. This enables the user to create small commits and clean up the local history before sharing, while still benefiting from isolation and deferred integration.

Internally, Git organizes commits as a right-to-left singly linked list. The branch's HEAD pointer always references the latest commit.

Creating a new commit involves the following actions:

  • Git creates a commit object and assigns it a unique SHA-1 hash.
  • The new object links to its parent (the previous HEAD).
  • Git moves HEAD to point at the new commit.

Subsequent commits repeat this process, advancing HEAD along the chain. Such a structure preserves immutability (since existing commits never change) and makes operations like branching, merging, and rolling back both efficient and reliable.

How to Use git commit

This section covers the essential workflows around the git commit command: creating new commits, undoing mistakes, updating existing commits, and inspecting history.

Knowing the commands allows users to manage their project timeline reliably and confidently.

How to Make a Git Commit

To record changes in Git, first stage them with git add and then create a commit using the syntax below:

git commit -m "Your descriptive message"

For example:

git commit example

The command above does the following:

  • Packages the contents of the staging area into a new commit object, linking it to its parent via a SHA-1 hash.
  • Stores a tree pointer to the snapshot of files and metadata (author, timestamp, parent hashes, and message).
  • Advances HEAD to point at this new commit, preserving the immutability of earlier commits.

How to Undo a Git Commit

Undoing commits allows users to undo changes that they have made to a repository. You can undo a commit if you have made a mistake or want to go back to a previous version of the code.

There are several ways to undo a commit, as shown in the sections below.

Local (Unpublished) Commits

Use git reset to move HEAD and optionally rewrite the index or working directory. Depending on your needs, the options are:

  • Undo the last commit, but keep changes staged:
git reset --soft HEAD^
git reset --mixed HEAD^
  • Undo the last commit and discard changes:
git reset --hard HEAD^

The --soft, --mixed, and --hard flags correspond to undoing in the commit history, staging area, and working tree, respectively.

In the example below, we undid the last commit and kept the changes staged, which can be seen from the git status output:

git status output after undoing a commit

Important: Only use git reset on private branches because rewriting shared history can confuse collaborators.

Public (Shared) Commits

To reverse a commit without altering history, use:

git revert [commit_hash]

The command creates a new commit that inverses the specified commit's changes and preserves a clean, forward-moving history. If you don't know the commit hash, find it with:

git log --oneline
find commit hash

The first seven characters represent each commit's hash.

Note: See how to squash commits in Git.

How to Update a Git Commit

Use the --amend flag to amend the latest commit (its message or contents) and stage any additional changes. Instead of creating a new commit, Git adds the staged changes to the previous commit, opens the system's configured text editor, and prompts the user to change the previously specified commit message.

The command is:

git commit --amend
update git commit

Amending incorporates the staged changes into the previous snapshot and replaces the original commit with a new SHA-1.

git commit Options 

The table below contains a summary of the most common and important git commit options. Use the flags that best fit your workflow to control staging behavior, message entry, hooks, signing, and more.

OptionDescription
-a, --allAutomatically stage modified and deleted files before commit.
-p, --patchInteractively select hunks from changed files to stage for commit.
-m [msg], --message=Use [msg] as the commit message.
-F [file], --file=Read the commit message from [file] (use - for STDIN).
-C [commit]Reuse the message and authorship from [commit] without editing.
-c [commit]Like -C, but opens the editor to reedit the reused message.
--amendReplace the tip of the current branch with a new commit that reuses the previous message/tree.
--allow-emptyCreate a commit even if it has the same tree as its parent (no changes).
--allow-empty-messagePermit an empty commit message.
--author=[author]Override the author name/email (e.g. Name [email]).
--date=[date]Override the author timestamp (e.g. --date="2025-05-01T12:00").
-s, --signoffAdd a "Signed-off-by" trailer line at the end of the commit message.
-S, --gpg-sign[=<key>]GPG-sign the commit; optional <key> specifies the signing key.
-v, --verboseShow unified diff of changes in the editor when crafting the commit message.
-q, --quietSuppress the commit summary output.
--dry-runShow what would be committed without actually doing it.
--statusInclude git status output in the editor.
--no-statusExclude git status output from the editor.
--shortUse short-format status output.
--porcelainUse a stable, machine-readable status output format.
--longUse long-format status output.
--nullOutput entries terminated with a null character (used in scripts).

The sections below explain each option in more detail and provide a usage example.

Automatically Stage Changes (-a, --all)

The -a flag automatically stages all modified and deleted files (excluding untracked files) before creating the commit. This option is useful for routine cleanup or small bugfixes. However, avoid it when you have untracked files to add selectively or when you need fine-grained control over what goes into your commit.

For example:

git commit -a -m "Fix typo in documentation"

The command stages all changes to tracked files and commits them with the given message.

Interactive Patch Selection (-p, --patch)

The -p flag launches an interactive hunk selector so you can choose which changes to stage and commit. This option is useful when you need to split a large change into multiple focused commits.

The command is:

git commit -p

Git prompts you, hunk by hunk, to stage or skip each change. After selecting, Git opens the default editor for the commit message.

Create Commit Message (-m, --message; -F, --file)

The -m and -F flags control how you supply the commit message, directly inline or via a file.

  • The syntax to create the commit message inline is:
git commit -m "Commit message"

For example:

git commit -m "Add OAuth login" -m "Supports token refresh workflow"

Note: Use multiple -m flags to add multiple paragraphs to your commit message. In the example above, the first -m becomes the commit title (the subject line), while the second -m flag becomes the message body.

  • To specify the commit message with a file, use the syntax below:
git commit -F [file_path]

For example:

git commit -F commit-message.txt

Git reads the entire commit message from the specified commit-message.txt file.

Reuse or Re-edit Messages (-C, --reuse-message; -c, --reedit-message)

The -C or -c flags save time and ensure consistency by allowing you to reuse an existing commit message (and authorship), identified by its hash or reference.

  • Use -C to reuse the message exactly as is, including the author information:
git commit -C HEAD~1

The command reuses the message (and author) from the second-to-last commit without prompting for any edits.

  • Use -c to reuse the message with the option to edit it in your configured text editor before committing. For example:
git commit -c [commit_hash]

The command above opens your editor with the commit message from the specified commit, allowing you to edit it before saving the new commit.

Amending Previous Commits (--amend)

The --amend flag modifies the most recent commit by adding staged changes, updating the commit message, or both. When you finish, the command replaces the last commit with a new one. Use it to fix typos, add tests, or tweak code you just committed.

For example, if you want to add a new file to the commit and keep the existing message, run the commands below:

git add forgotten-file.txt
git commit --amend

The --amend flag adds forgotten-file.txt to the previous commit without changing its message.

However, if you want to change the commit message as well, run:

git commit --amend -m "Improve setup instructions"

The command amends the latest commit and changes the commit message to the one specified above.

Warning: Do not amend commits that have been pushed to a shared branch because rewriting public history can disrupt collaborators.

Create Empty or No-Message Commits (--allow-empty; --allow-empty-message)

These options override Git's safeguards to create commits without changes or a message. This option is useful in CI pipelines, for tagging specific points/marking milestones, or for integrating with scripts.

For example, to mark a release point with no file changes, run:

git commit --allow-empty -m "Mark v2.0 release"
make no-message commit

Or, to create a commit with an empty message, enter:

git commit --allow-empty-message --no-edit

Override Author and Date (--author; --date)

Use the --author and --date flags to override your Git config and manually specify commit metadata or timestamp. The options are useful for imported patches or chronological accuracy in testing.

To set a custom commit author, use the syntax below:

git commit --author="Name <[email protected]>" -m "Message"

For example:

git commit --author="Alice <[email protected]>" -m "Adjust credit"

Alternatively, to set a custom date, use the following syntax:

git commit --date=" YYYY-MM-DDTHH:MM:SS" -m "Message"

For example:

git commit --date="2025-05-01T12:00:00" -m "Backdate test results"

You can also combine the two flags to set a custom author and date in the same command.

Signing and Sign-off (-s, --signoff; -S, --gpg-sign)

Use the -s and -S flags to certify your commit with a DCO sign-off trailer or GPG signature. Doing so ensures legal compliance or authenticity. The -s flag appends a "Signed-off-by: Name <email>" line, while the -S flag attaches a cryptographic signature under your key. They are often used in projects that require DCO compliance (Linux kernel, etc.) or when verifying commit integrity.

Use the syntax below to add a Developer Certificate of Origin sign-off:

git commit -s -m "Implement API endpoint"

Alternatively, use the -S flag for a GPG-signed commit:

git commit -S -m "Secure sensitive data"

Verbose and Quiet Modes (-v, --verbose; -q, --quiet)

The -v (--verbose) and -q (--quiet) flags control how much feedback and context you see when making a commit. Use -v as a reminder of staged changes when writing detailed commit messages, and -q for cleaner output in scripts or automated hooks.

To show staged diff inside the editor, run:

git commit -v
git commit verbose

The command appends a unified diff of staged changes to your commit message template.

Alternatively, to suppress summarizing output after commit, run:

git commit -q -m "Commit message"

The command suppresses the output success message notice.

Dry-run and Status Output (--dry-run; --status; --no-status; --short; --porcelain; --long; -z, --null)

Use the dry-run and status output flags to preview and format what Git would commit, without changing the history. The options are useful for scripting CI checks, generating reports, or automated commit tooling.

The options are:

  • --dry-run. List files that would be committed.
  • --status / --no-status. Include or omit git status in the message template.
  • --short, --porcelain, --long. Control listing format (machine-readable vs. human).
  • --null. Terminate filenames with NULs for safe parsing in scripts.

Conclusion

This guide showed how to make, modify, and undo commits, an essential skill for maintaining a clean and organized Git history. By following best practices and using the appropriate commands, you can keep your project history clear, meaningful, and easy to navigate.

Next, learn how to use Git or see how to push large files using Git LFS.

Was this article helpful?
YesNo