Home / Alt manpages / git-commit(1)

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

Stage, Review and Record Changes with git commit

The moment before you type git commit is the last chance to catch a stray debug print or a secret you forgot was in the diff, so treat it that way. This guide gets you a repeatable workflow for reviewing the index, creating a focused commit, and correcting the last one 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 ready to record.

This guide changes repository history the moment 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 exactly what the next ordinary git commit will record: treat that one as the review checkpoint. If it comes back 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 is sitting in there with it.

2. Stage only the intended change

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

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

Use one of those two git add forms for a given change, not both. The index is a deliberate buffer: editing a file does not put its modification into the next commit until you actually stage it.

If you staged too much, pull a file back out of the index while keeping its working-tree edits:

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

That is an undo for staging, not a deletion. The file's edits stay right where they were in the working tree.

3. Preview the proposed commit

Run the commit in dry-run mode before you create any 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, but it creates nothing. For the actual content, use git diff --cached; for the message, write a short subject that says what changed.

4. Create the focused commit

When the index looks right, 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 will 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. Git also runs the pre-commit and commit-msg hooks by default, and a hook can reject the commit, so a non-zero exit status does not necessarily mean nothing happened. Verify the result rather than trusting the printed summary alone:

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

A clean status prints nothing. Anything left unstaged stays in the working tree, ready 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, but never new, untracked files. That combination is only convenient once you have reviewed every tracked change:

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

Prefer explicit git add whenever the working tree holds 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 slips in.

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

If several changes are staged but only one tracked path is actually ready, a path argument makes Git commit just that path's current contents, leaving everything else staged:

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

Do not confuse this with an ordinary staged commit. When you give a path, Git records only that path's current contents and ignores staged changes for everything else in this particular commit. The held-back changes are not lost, and you can commit them later with no path argument at all.

7. Correct the last commit carefully

If the last commit has a typo in its message, or needs a small immediate fix, 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 keeps the original author and starts with the old message unless you provide another one, but the commit ID changes even when the message looks identical.

Warning

Amending a published commit rewrites history. Stop if anyone else may already 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 straight away, check git reflog before taking any recovery action: the previous tip is normally still discoverable there, though reflog retention is not a substitute for a real backup.

8. Recover from an unwanted local commit

If you committed too soon and want to keep the changes available for a different arrangement, move the branch back while keeping the working tree intact. Record the current ID first:

$ 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 you do anything else:

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

If the commit was already shared, do not run this reset on the shared branch just to tidy the history. A new commit is usually the safer fix.

Done means

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