Subject: Re: [RFC PATCH 0/1] add -p: support discarding hunks

From: Junio C Hamano <[email-masked]>
Date: Wed, 25 Mar 2026 11:03:27 -0700

Luiz Campos <[email-masked]> writes:

> Hi,
>
> This is an RFC for adding a 'discard hunk' action to `git add -p`.
>
> Currently, when using `git add -p`, users can stage or skip hunks,
> but cannot discard unwanted changes directly from the working tree.
> This often leads to repeatedly skipping the same hunks across
> multiple passes.
>
> This patch introduces a new 'x' action to discard the current hunk
> by reverse-applying it to the working tree.
>
> This idea was previously discussed on the mailing list:
> https://lore.kernel.org/git/[email-masked]/t/#m0576e6f3c6375e11cc4693b9dca3c1fc57baadd0
>
> Open questions:
> - Should discard happen immediately or be deferred until patch application?
> - Are there edge cases involving overlapping hunks or edited hunks?

After reading the discussion (by the way, I do not recall seeing it,
so thank you very much for having a link to it), I agree with what
Peff said back then.  "add -p" that touches the working tree feels
quite weird.

In addition to that, letting it make destructive change makes the
idea even less appetizing.  Once you remove the changes introduced
by the hunk, it is forever gone.  A "discard" in "add -p" would not
solve your problem without adding many unhappy users who lost their
work by mistake.  I do not want to see people trigger "discard" by
mistake in "add -p" session _and_ find that there is no way to undo
that mistaken discard.

"stash -p" followed by "add -p" is probably the best we can do that
is safe.  When the unwanted change is truly unwanted garbage that
you would never ever want to see again, "restore -p" followed by
"add -p" would be an alternative.

One reason why they are not satisfying is because during the later
"add -p" session, we will notice that some unwanted things we failed
to notice and get rid of (either by sending them to stash or restoring
it away) are still there, reminding us that we are imperfect human,
and at that point, it is not easy to switch back to the "stash -p"
or "restore -p" from there.

What you want is probably a _single_ command that lets you inspect
the differences among the HEAD, the index, and the working tree, and
allows you to move things hunk-by-hunk in different directions.

 * You can go through the "git diff --cached" (i.e., changes already in
   the index), and selectively undo/revert the changes to the index,
   similar to "git reset -p".

 * You can go through the "git diff" (i.e., changes between the
   index and the working tree), and selectively apply the changes to
   the index, similar to "git add -p".

 * You can go through the "git diff HEAD" (i.e. changes since your
   last commit), and selectively send the changes to a stash entry,
   similar to "git stash -p".  This is not destructive.

And if the single command lets you switch among working with these
modes, you no longer need to worry about forgetting to send
some changes to stash to concentrate on working on the rest.

In addition, optionally you can also have this in the same command:

 * You can go through the "git diff", and selectively revert the
   changes to the working tree, similar to "git restore -p".

This additional mode *is* destructive, but if you know from the hunk
that you will never need the change in it, it would be a right tool
for it.