Home / Alt manpages / git-commit(1)

  • git-commit(1)
  • User command
  • linux

Stage, Review and Safely Record Changes with git commit

You will finish with a repeatable workflow for reviewing the index, creating a focused commit, and correcting the last commit without losing work. The examples use Git 2.43.0 from the installed git-man package, version 1:2.43.0-1ubuntu7.3. Allow about fifteen minutes. You need an existing Git working tree with a change you are prepared to record.

This guide changes repository history when you run the commit commands. Work on a branch, check the staged diff first, and do not amend a commit that has already been shared unless your team has agreed how the rewritten history will be handled.

1. Check what Git sees

Start with status. It separates changes in the working tree, changes already in the index, and untracked files:

$ git status
$ git diff
$ git diff --cached

The first diff is not staged. The second, with --cached, is the content the next ordinary git commit will record. Treat that second command as the review checkpoint. If it is empty, there is nothing staged for a normal commit.

Checkpoint: every file you intend to record appears in git diff --cached, and no unrelated secret, build output or debugging change appears there.

2. Stage only the intended change

Add a known file, or select changes interactively when one file contains more than one logical change:

$ git add path/to/changed-file
$ git add --patch path/to/changed-file
$ git diff --cached

Use one of the two git add commands, not both for the same change. The index is a deliberate buffer: editing a file does not put its modification into the next commit until it is staged.

If you staged too much, remove a file from the index while keeping its working-tree edits:

$ git restore --staged path/to/file
$ git diff -- path/to/file
$ git diff --cached

This is an undo for staging, not a deletion. The file's edits remain in the working tree.

3. Preview the proposed commit

Run the commit in dry-run mode before creating history:

$ git commit --dry-run --short
M  path/to/changed-file

The exact list depends on your tree. Dry-run reports paths that would be committed, local changes that would remain, and untracked files. It does not create a commit. For the final content, use git diff --cached; for the message, write a short subject that says what changed.

4. Create the focused commit

When the index is correct, provide the message explicitly:

$ git commit -m "Add health check to worker"
[feature/health-check 7f3a2c1] Add health check to worker
 1 file changed, 8 insertions(+)

The hash and summary vary. A successful command creates a new commit from the current index, makes it a child of HEAD, and moves the current branch to it. By default, Git also runs the pre-commit and commit-msg hooks. A hook can reject the commit, so a non-zero exit status does not mean the commit was created.

Verify the result without relying on the printed summary:

$ git show --stat --oneline --summary HEAD
$ git status --short
7f3a2c1 Add health check to worker

A clean status has no output. If other work was left unstaged, it remains in the working tree for a later commit.

5. Understand the shortcut that can sweep too broadly

git commit -a -m "..." automatically stages modifications and deletions of tracked files before committing. It does not stage new, untracked files. That combination is convenient only when you have reviewed every tracked change:

$ git commit --dry-run --short -a
$ git commit -a -m "Update worker configuration"

Prefer explicit git add when the working tree contains unrelated work. The most common mistake here is assuming -a means all files; a new file can be silently left out, while an unrelated tracked edit can be included.

6. Commit one path without consuming the rest of the index

If several changes are staged but one tracked path is ready first, a path argument makes Git commit that path's current contents. Other staged paths stay staged:

$ git commit --dry-run --short -- path/to/ready-file
$ git commit -m "Record parser fix" -- path/to/ready-file
$ git status --short

This is a useful boundary, but do not confuse it with an ordinary staged commit. When a path is given, Git records the current contents of the named path and ignores staged changes for other paths in that commit. The held-back changes are not lost and can be committed later with no path argument.

7. Correct the last commit carefully

If the last commit has a typo in its message or needs a small immediate correction, stage the correction and amend:

$ git add path/to/correction
$ git diff --cached
$ git commit --amend -m "Add health check to worker"
$ git show --stat --oneline --summary HEAD

Amending replaces the tip with a new commit. It normally keeps the original author and starts with the old message unless you provide another message. The commit ID changes even when the message appears unchanged.

Warning: amending a published commit rewrites history. Stop if other people may have based work on the old ID. If the mistake is already shared, make a new corrective commit instead, or follow your project's documented history-repair process. If an amend goes wrong immediately, inspect git reflog before taking recovery action; the previous tip is normally still discoverable there, but reflog retention is not a substitute for a backup.

8. Recover from an unwanted local commit

If you committed too soon and want to keep the changes available for another arrangement, move the branch back while preserving the working tree. First record the current ID:

$ git rev-parse HEAD
7f3a2c1...
$ git reset --soft HEAD^

This is a history-changing command. It moves the branch back one parent and leaves the changes staged, ready for a new commit. Check the result before doing anything else:

$ git status --short
$ git diff --cached

If the commit was shared, do not run this reset on the shared branch merely to make its history prettier. A new commit is usually the safer correction.

Done means

  • git diff --cached contained exactly the change you meant to record.
  • You used dry-run or an equivalent review before creating the commit.
  • The commit message identifies the change, and git show HEAD verifies the result.
  • You know whether unstaged and untracked files were deliberately left behind.
  • You treated --amend and reset as local history changes, not routine cleanup of shared history.