If an older commit contains an unwanted change to one file, you can reverse that file’s change against your current branch and save the result in a new commit. This keeps later commits in place and preserves their edits when the reverse patch still fits. On macOS, use Terminal from the repository; review the patch first, especially if later work touched the same lines.
Choose the right history change
This procedure adds a commit that cancels the target commit’s change to one path. It does not erase that file from the old commit, so the old version remains in history. That approach avoids rewriting branch history and is usually appropriate when the commit has already been shared or later commits depend on it. Git describes git revert as recording a new commit that reverses an earlier commit, but it does not offer a built-in option to revert only one path from an existing commit. Instead, the steps below generate that path’s patch and apply it in reverse. Git: git-revert Documentation
If the file change must be removed from the historical commit itself, that is a history-rewrite task, typically handled with an interactive rebase. Rewriting changes commit identities and can disrupt collaborators who have based work on the old commits. This guide covers the safer, additive approach.
Reverse the target commit’s change to one file
Open Terminal, go to the repository, and check the working tree before changing anything. Replace TARGET with the commit ID and path/to/file with the path relative to the repository root. The example uses a temporary patch file in macOS’s /tmp directory; choose a different temporary name if that file already exists.
git status --short
git show --stat --oneline TARGET
git diff TARGET^ TARGET -- "path/to/file" > /tmp/remove-file-change.patch
The diff compares the target commit with its first parent and limits the result to the named path. For a normal, non-merge commit, this represents that commit’s change to the file. Confirm the summary identifies the intended commit and that the patch is non-empty. You can inspect it with less /tmp/remove-file-change.patch; press q to exit. Git documents commit-to-commit diffs with an optional path limit. Git: git-diff Documentation
Before applying it, make sure you have no unrelated staged or unstaged edits in the target file. The reverse patch changes the working copy, so a clean working tree is the simplest starting point. If you have useful local work, commit or safely set it aside first; do not overwrite it with a restore command.
Check whether the reverse patch fits, then apply it:
git apply --reverse --check /tmp/remove-file-change.patch
git apply --reverse /tmp/remove-file-change.patch
--reverse applies the diff backward, while --check checks whether it applies without changing files. By default, git apply fails the entire patch if some hunks do not fit, rather than applying only the parts that do. If the check fails, stop and inspect the file and patch. Later edits may overlap with the target change, so Git cannot safely determine what should be removed. Resolve the intended content manually, or use a history-rewrite workflow if preserving a precisely edited historical sequence is essential. Do not add --reject casually: it can apply only matching pieces and leave rejected hunks behind. Git: git-apply Documentation
Review and commit the result
Inspect exactly what changed before staging. git diff shows the working-tree edits; use the path again to focus the review. If the result is right, stage that file and check the staged diff before creating a new commit.
git diff -- "path/to/file"
git add -- "path/to/file"
git diff --cached -- "path/to/file"
git status --short
git commit -m "Remove file change from earlier commit"
The quotes protect the path from shell interpretation, and -- marks the end of options. They are especially useful for names containing spaces or shell metacharacters. The commit records the staged index; reviewing git diff --cached verifies the exact content about to be committed. Git: git-commit Documentation
After committing, check git status --short and inspect the new commit with git show --stat --oneline HEAD. If the original commit added the file, reversing its patch may delete it—this is expected if no later content needs to remain. If later commits added useful content to that file, those additions should remain when the reverse patch applies cleanly; review the final file and diff to confirm.
Cases that need extra care
A merge commit has multiple parents, and its change depends on which parent you compare against. TARGET^ means the first parent; it may not represent the change you intended to remove. Identify the correct parent and compare against it explicitly before applying anything. Renames, binary files, and files that have since moved may also make a path-limited patch unsuitable; check the diff and stop if it does not describe the intended file change. For merge-specific reversals, Git’s revert documentation explains the mainline parent choice and its consequences. Git: git-revert Documentation
The reliable checkpoint is the reviewed patch: it should show only the target commit’s change to the intended path. If it cannot apply cleanly to today’s file, do not force it. Reconstruct the desired current file carefully, then stage and commit only after reviewing the complete result.