0% прочитано

git restore -p in Practice: Cleaning a Diff Without Losing the Real Change

After pushing a small change, the diff also contained unrelated whitespace and formatting. I used git restore -p to restore only the unwanted hunks from production while keeping the actual change.

1 жовтня 2026 р. 7 хв читанняGit

Sometimes a task is very small, but after pushing it the pull request suddenly contains a much larger diff.

That happened to me recently. I changed spacing for one element on a page. The actual change was small, but during review I found unrelated whitespace, line breaks, and formatting mixed into the same files.

I could not simply restore the entire files from production, because those files also contained the change I needed to keep.

The real task became: remove only the accidental formatting changes while preserving the functional change.

git restore -p was exactly what I needed.

This is different from a normal rollback. I did not want to restore the whole file. I needed to restore only selected parts of it.

First I Inspected the Diff Again

BASH - Compare the target files with production
git diff origin/master -- \  resources/assets/css/styles/page.scss \  resources/views/front/model/page/show.blade.php

Before restoring anything, I inspected exactly what differed from the base branch.

The diff contained two different kinds of changes:

  • the change I actually needed;
  • unrelated formatting and whitespace.

That is why restoring the complete files was not appropriate. It would remove both the noise and the actual task.

Why Restoring the Whole File Does Not Fit

If a file contained only an accidental change, restoring the whole file from the base branch would be simple.

But in this case the same file contained both the correct change and unrelated formatting.

I therefore needed something more precise than choosing between "keep the file" and "restore the file". I needed to decide what to do with each individual diff hunk.

Selective Restore with git restore -p

BASH - Restore the files hunk by hunk
git restore -p \  --source=origin/master \  -- \  resources/assets/css/styles/page.scss \  resources/views/front/model/page/show.blade.php

The -p option means patch.

Git does not restore the complete file immediately. It shows the changes as separate hunks and asks what to do with each one.

Git asks about every hunk
Discard this hunk from worktree [y,n,q,a,d,s,e,?]?

The Important Part Is Not Mixing Up y and n

What y and n mean
y - yes, restore this hunk from origin/production    the current local change in this hunk will be removed n - no, do not restore this hunk    the current change will remain
With git restore -p, y does not mean "keep my change". It means restore that hunk from the source version. This is the easiest part to misread.

How I Decided What to Keep

When Git showed a hunk containing only accidental whitespace, line breaks, or formatting, I answered y.

That meant restoring that specific hunk from origin/production.

When Git reached the actual task change, I answered n so that change stayed in my working file.

Parts of the required change
&--withdrawn-gap lot__rate--withdrawn-gap

In my case, these names made the actual task change easy to recognize among unrelated hunks.

The decision became very simple:

  • only accidental formatting - y;
  • the change required by the task - n.

That is the main advantage of git restore -p: I was working with individual pieces of the diff, not treating the file as one indivisible change.

After the Restore I Checked the Diff Again

BASH - Verify the cleaned result
git diff git diff -w git diff --check git status -sb

After going through all hunks, I did not rely only on remembering my y and n answers. I inspected the result again.

A normal git diff shows the complete current diff.

git diff -w ignores whitespace changes. That is especially useful in this scenario because it lets me confirm that the functional change is still there after the formatting noise has been removed.

git diff --check provides another whitespace sanity check, while git status -sb gives me a concise view of the branch and changed files.

What Changes When the Code Was Already Pushed

In my case, the unrelated formatting became visible only after the original change had already been pushed.

git restore -p does not rewrite an existing remote commit. It only changes the current files in my working tree.

After cleaning the files and verifying the result, I staged them, created a new commit, and pushed it.

BASH - Create a cleanup commit
git add \  resources/assets/css/styles/page.scss \  resources/views/front/model/page/show.blade.php git commit -m "Restore unrelated whitespace" git push

The pull request then received another commit that removed the accidental changes without undoing the actual task.

If the history later needs to be reduced to one clean commit, that is a separate operation. At this stage, my priority was first to make the diff correct and understandable.

Why I Did Not Restore Everything Manually

Of course I could have opened every file and manually restored spaces and line breaks.

But when one file contains the required change, accidental formatting, and several independent hunks, manual editing creates another risk: accidentally touching the code that should remain.

git restore -p already has the information I need. Git shows the exact piece of the diff, and I only decide whether to restore it from the base version or keep it.

The Command I Want to Remember

BASH - Restore selected hunks from a file
git restore -p \  --source=origin/production \  -- \  path/to/file
Quick reminder
y - restore this hunk from the source versionn - keep my current change

When required and accidental changes are mixed in the same file, I do not have to choose between a noisy diff and restoring the whole file. I can restore only the specific hunks I do not want.

It is a small Git command, but it solved a very specific problem.

The required change had already been made and pushed. Restoring the whole file would have removed it together with the unrelated formatting. Manually fixing every whitespace change would have been slower and less reliable.

git restore -p let me walk through the diff piece by piece and make one decision at a time: restore this or keep this.

The result was exactly what I needed: only the changes that had accidentally entered the pull request were removed, while the real task remained intact.