# Re: Revert option for git add --patch

5 messages from 2012-11-08 to 2012-11-09. Participants: Jonathon Mah, Nguyen Thai Ngoc Duy, Jeff King, Bogolisk.
Thread: https://gitlist.dev/t/32038

## Jonathon Mah, 2012-11-08 08:57

Subject: Re: Revert option for git add --patch
Message-ID: <EE89F0A1-1C07-4597-B654-035F657AD09F@me.com>
URL: https://gitlist.dev/e/EE89F0A1-1C07-4597-B654-035F657AD09F%40me.com

```
Nathan,

I find myself performing similar actions to you: using git add -p to stage hunks, sometimes editing the staged patch; and keeping mental notes of things I wanted to revert, sometimes changing them in the editor in another window, and sometimes reverting them after the add session with git checkout -p).

The interactive staging-and-editing tool could be improved, but I'm not sure that tool should be called 'git add -p'. git add doesn't touch the working tree — at least I hope not, because I wouldn't expect it.

But I eagerly support more discussion. If someone does want to add this feature to "git add -p" (or named differently), I'll add a request for another letter (perhaps '!')  to edit the hunk in the working tree.
	


Jonathon Mah
me@JonathonMah.com

```

## Nguyen Thai Ngoc Duy, 2012-11-08 12:00

Subject: Re: Revert option for git add --patch
Message-ID: <CACsJy8CXV=TPWPkNnF7rPRvuObRH=m6RY0KXVXkCaum1EovDCQ@mail.gmail.com>
URL: https://gitlist.dev/e/CACsJy8CXV%3DTPWPkNnF7rPRvuObRH%3Dm6RY0KXVXkCaum1EovDCQ%40mail.gmail.com
In-Reply-To: <EE89F0A1-1C07-4597-B654-035F657AD09F@me.com>

```
On Thu, Nov 8, 2012 at 3:57 PM, Jonathon Mah <jmah@me.com> wrote:
> Nathan,
>
> I find myself performing similar actions to you: using git add -p to stage hunks, sometimes editing the staged patch; and keeping mental notes of things I wanted to revert, sometimes changing them in the editor in another window, and sometimes reverting them after the add session with git checkout -p).

I agree. I'd be really nice to have an interactive command about hunk
manipulation between HEAD (or some other ref), index and worktree in
both directions (except writing to HEAD, of course). This reminds me
of the "git put" discussion a while ago, which also moves code between
different locations..
-- 
Duy

```

## Jeff King, 2012-11-08 15:15

Subject: Re: Revert option for git add --patch
Message-ID: <20121108151501.GB15560@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20121108151501.GB15560%40sigill.intra.peff.net
In-Reply-To: <EE89F0A1-1C07-4597-B654-035F657AD09F@me.com>

```
On Thu, Nov 08, 2012 at 12:57:19AM -0800, Jonathon Mah wrote:

> I find myself performing similar actions to you: using git add -p to
> stage hunks, sometimes editing the staged patch; and keeping mental
> notes of things I wanted to revert, sometimes changing them in the
> editor in another window, and sometimes reverting them after the add
> session with git checkout -p).

Yeah, I often use a similar workflow. A related one is:

  (1) Make lots of unrelated changes in the working tree.

      $ hack hack hack

  (2) Pick out hunks for the first commit.

      $ git add -p

  (3) Put the rest of the changes aside.

      $ git stash -k

  (4) Test (and possibly tweak) the result, then commit.

      $ make test
      $ git commit -m "topic 1"

  (5) Bring back the stashed changes.

      $ git stash pop

  (6) If there are still interesting changes, goto step 2.

  (7) Otherwise, discard with "git reset --hard" or "git checkout -p".

I.e., iterating on the changes to put them into several different
commits (and achieving a clean, testable state before making each
commit).

The downside of these workflows is that you have to say "no" to hunks
multiple times (one per iteration) instead of just sorting them in a
single pass. This works OK in practice, but it might be nice to have a
tool that makes a single pass and lets you drop hunks into buckets
(topic 1 vs topic 2 vs discard), and then apply the buckets in order,
stopping to test, tweak, and commit after each one.

> The interactive staging-and-editing tool could be improved, but I'm
> not sure that tool should be called 'git add -p'. git add doesn't
> touch the working tree — at least I hope not, because I wouldn't
> expect it.

Right. I think the idea of one-pass tool is a good one, but it should
not be called "git add -p".

-Peff

```

## Jeff King, 2012-11-08 20:04

Subject: Re: Revert option for git add --patch
Message-ID: <20121108200449.GA3018@sigill.intra.peff.net>
URL: https://gitlist.dev/e/20121108200449.GA3018%40sigill.intra.peff.net
In-Reply-To: <CAPXHQbPrjZ_Ezi3RkHny-fW0=mQCTmX9NVJfgUh7P-Xx9pgBcg@mail.gmail.com>

```
On Fri, Nov 09, 2012 at 08:42:33AM +1300, Nathan Broadbent wrote:

> It sounds like we want a tool that combines the functionality of 'git add
> --patch', 'git checkout --patch', and other features, so that we can
> perform various actions on 'hunks' without switching context. What do you
> think about naming this command 'git patch'?

I think it would be a slightly confusing name, given that it is not
related to the usual Unix "patch" command (git's analog to that is "git
apply").

I was thinking something like "git organize" because it is about
organizing muddled changes. Duy mentioned my earlier "git put", which is
based around the same ideas. This could be thought of as "git put
--patch", I suppose.

> I'm not sure how dropping hunks into 'buckets' would work, but the main
> idea is to be able to stage, discard or edit hunks in a single pass.

Buckets are really just patches you are building up from hunks. So I
think you are dealing with two buckets either way: a to-stage bucket and
a to-discard bucket. Adding more buckets isn't hard; you just turn the
to-stage bucket into an array of buckets.

The tricky part is figuring out how to keep the state persistent across
multiple invocations. The simplest program flow for the 2-bucket case
would be something like:

  for h in hunks
  do
          show hunk to user
          ask user what they want to do
          if they want to stage
             append to to-stage patch
          else if they want to discard
             append to to-discard patch
          else
             ignore the hunk
  done
  feed to-stage patch to "git apply --cached"
  feed to-discard patch to "git apply -R"

Modifying the loop to have more buckets is easy. But the end is probably
something like:

  feed to-discard patch to "git apply -R"
  feed bucket[0] to "git apply --cached"
  save bucket[1..n] somewhere
  exit

Then the user gets control back, builds, tests, commits, whatever, and
then runs "git organize --continue" to apply bucket[1], and so on. And
since we don't know what the user did in between, we have to be ready
for conflicts in applying the buckets.  Hmm, this is sounding a lot like
how "rebase --interactive" works.

One way to implement this would be to store each bucket as a commit
against HEAD (i.e., stage it into a temporary index, then run "git
write-tree" and "git commit-tree"), and then make a "rebase -i"
instruction sheet like:

  pick $sha1_of_bucket_1_commit
  edit
  pick $sha1_of_bucket_2_commit
  edit

and so forth, except that we would not want our picks to actually commit
(just pull the changes into the working tree and/or index).

That's just me thinking off the top of my head. Obviously what you are
proposing is way simpler, and it is probably sane to start with the
simple thing, and then build the more complex thing on top. But it might
be worth keeping in mind the complex case when building out the
infrastructure for the simple case.

-Peff

```

## Bogolisk, 2012-11-09 14:09

Subject: Re: Revert option for git add --patch
Message-ID: <loom.20121109T150732-186@post.gmane.org>
URL: https://gitlist.dev/e/loom.20121109T150732-186%40post.gmane.org
In-Reply-To: <EE89F0A1-1C07-4597-B654-035F657AD09F@me.com>

```
Jonathon Mah <jmah <at> me.com> writes:

> 
> Nathan,
> 
> I find myself performing similar actions to you: using git add -p to stage 
hunks, sometimes editing the
> staged patch; and keeping mental notes of things I wanted to revert, sometimes 
changing them in the editor
> in another window, and sometimes reverting them after the add session with git 
checkout -p).

Other front-ends like Egg and Magit has been providing the ability to move hunks 
back and forth, for a long time.

```
