threads / discuss / 29327

Re: Please support add -p with a new file, to add only part of the file

Subject: Re: Please support add -p with a new file, to add only part of the file

## tl;dr

7 messages between Jan 9, 2012 and Jan 10, 2012.

replies: 6people: 5as markdown or json

Jonathan Nieder· Jan 9, 2012, 20:47 UTC · lore
(+cc: Wincent who brought us the "add -p" shortcut --- thanks!; Thomas,
 who expanded its scope to git checkout et al; and Jeff, who has done
 some hacking on it)
Hi Josh,
Josh Triplett wrote:
Show 5 quoted lines
> I recently found myself with a new file that I needed to check in part
> of with several commits.  I wanted to use "git add -p newfile" and use
> 'e' to add and commit several times (along with corresponding bits in
> existing files).  However, "git add -p" does not work on a new file,
> only an existing file.

Yep. A workaround is to use "git add -N newfile" before running "git add -p newfile".

I imagine "git add -p '*.c'" should also offer to add hunks from source files that git doesn't know about yet, too.

Here's a quick demo (untested) that might _almost_ do the right thing. Unfortunately it leaves intent-to-add entries around even for files the operator rejects. Anyway, maybe it can be a good starting point for playing around.

Hope that helps, Jonathan

 git-add--interactive.perl |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/git-add--interactive.perl b/git-add--interactive.perl
index 8f0839d2..6e99ff1b 100755
--- a/git-add--interactive.perl
+++ b/git-add--interactive.perl
@@ -1619,6 +1619,10 @@ sub main_loop {
 process_args();
 refresh();
 if ($patch_mode) {
+	if ($patch_mode eq 'stage') {
+		# NEEDSWORK: should use "git update-index --intent-to-add"
+		system(qw(git add --intent-to-add --), @ARGV);
+	}
 	patch_update_cmd();
 }
 else {
-- 
1.7.8.2
Thomas Rast· Jan 10, 2012, 14:07 UTC · re: Jonathan Nieder · lore
Jonathan Nieder <jrnieder@gmail.com> writes:
Show 18 quoted lines
> Josh Triplett wrote:
>
>> I recently found myself with a new file that I needed to check in part
>> of with several commits.  I wanted to use "git add -p newfile" and use
>> 'e' to add and commit several times (along with corresponding bits in
>> existing files).  However, "git add -p" does not work on a new file,
>> only an existing file.
>
> Yep.  A workaround is to use "git add -N newfile" before running
> "git add -p newfile".
>
> I imagine "git add -p '*.c'" should also offer to add hunks from
> source files that git doesn't know about yet, too.
> 
> Here's a quick demo (untested) that might _almost_ do the right thing.
> Unfortunately it leaves intent-to-add entries around even for files
> the operator rejects.  Anyway, maybe it can be a good starting point
> for playing around.

I think a proper solution needs a way to generate a diff that includes all of the named files (even untracked). AFAICS there is no such feature in the diff-* commands right now.

A not-so-proper solution might of course start by looking at which files are untracked, and only run the 'git add -N' immediately before patch application.

-- 
Thomas Rast
trast@{inf,student}.ethz.ch
Junio C Hamano· Jan 10, 2012, 18:32 UTC · re: Thomas Rast · lore
Thomas Rast <trast@student.ethz.ch> writes:
> A not-so-proper solution might of course start by looking at which files
> are untracked, and only run the 'git add -N' immediately before patch
> application.

Isn't the real issue that we mistakenly gave an impression that "add -p" is the primary interface to the users, and forgot to tell them about the more general "add -i", which "add -p" is a small subset of?

Even if you start with "add -N", there won't be individual "hunks" you can pick and choose from diffing emptiness and the whole new file, so you end up using "edit hunk" interface.

Whatever you do, you should aim to make it easier to use than
	$ cp newfile.c newfile.c-saved
        $ edit newfile.c ;# delete all the things you do not want for now
        $ git add newfile.c
        $ mv newfile.c-saved newfile.c

Personally, I think it is a very tall order to tweak "add -p / edit" interface to make it easier to use than the above four command sequence, the second one among which is the most time and braincell consuming part of the process, especially when "add -p / edit" gives you has to be unnecessarily distracting by having '+' prefix.

Jeff King· Jan 10, 2012, 18:38 UTC · re: Junio C Hamano · lore
On Tue, Jan 10, 2012 at 10:32:20AM -0800, Junio C Hamano wrote:
Show 9 quoted lines
> Thomas Rast <trast@student.ethz.ch> writes:
> 
> > A not-so-proper solution might of course start by looking at which files
> > are untracked, and only run the 'git add -N' immediately before patch
> > application.
> 
> Isn't the real issue that we mistakenly gave an impression that "add -p"
> is the primary interface to the users, and forgot to tell them about the
> more general "add -i", which "add -p" is a small subset of?

Maybe it is just me, but I find "add -p" insanely useful, and the rest of "add -i" to be worthless clutter. The "add -p" functionality is not easily available anywhere else, but the rest of "add -i" can be easily (and often more efficiently) mimicked using existing git commands.

> Even if you start with "add -N", there won't be individual "hunks" you can
> pick and choose from diffing emptiness and the whole new file, so you end
> up using "edit hunk" interface.

I don't think the main impetus for this is that people necessarily want to pick and choose hunks from added files. I think it is simply a nice workflow to do:

  $ hack hack hack
  $ git add -p ;# inspect and add changes
  $ git commit
which is very similar to the traditional git workflow:
  $ hack hack hack
  $ git diff ;# inspect changes
  $ git add foo ;# add changes
  $ git commit

I find myself using "add -p" almost exclusively these days, as it combines the two middle steps (and even though I usually am just hitting "y" after inspection, when I _do_ want to make a change, I am right there in the hunk selection loop already).

-Peff
Junio C Hamano· Jan 10, 2012, 19:33 UTC · re: Jeff King · lore
Jeff King <peff@peff.net> writes:
Show 6 quoted lines
>> Even if you start with "add -N", there won't be individual "hunks" you can
>> pick and choose from diffing emptiness and the whole new file, so you end
>> up using "edit hunk" interface.
>
> I don't think the main impetus for this is that people necessarily want
> to pick and choose hunks from added files.
Well, read the subject of your e-mail and tell me what it says ;-)

And that is why I was contrasting an imaginary workflow to use the existing "add -p" with requested "allow it to be used with new files" with what somebody may "emulate" without help from "add -p" machinery, which is:

	$ cp newfile.c newfile.c-saved
        $ edit newfile.c ;# delete all the things you do not want for now
        $ git add newfile.c
        $ mv newfile.c-saved newfile.c

I just had to point the above out, even though I agree with the use case you shown below for final verification. They are quite different topic, as "git diff" won't be very useful for 'inspect changes' step in the "new file" case to begin with.

Show 15 quoted lines
>   $ hack hack hack
>   $ git add -p ;# inspect and add changes
>   $ git commit
>
> which is very similar to the traditional git workflow:
>
>   $ hack hack hack
>   $ git diff ;# inspect changes
>   $ git add foo ;# add changes
>   $ git commit
>
> I find myself using "add -p" almost exclusively these days, as it
> combines the two middle steps (and even though I usually am just hitting
> "y" after inspection, when I _do_ want to make a change, I am right
> there in the hunk selection loop already).
Jeff King· Jan 10, 2012, 19:38 UTC · re: Junio C Hamano · lore
On Tue, Jan 10, 2012 at 11:33:39AM -0800, Junio C Hamano wrote:
Show 10 quoted lines
> Jeff King <peff@peff.net> writes:
> 
> >> Even if you start with "add -N", there won't be individual "hunks" you can
> >> pick and choose from diffing emptiness and the whole new file, so you end
> >> up using "edit hunk" interface.
> >
> > I don't think the main impetus for this is that people necessarily want
> > to pick and choose hunks from added files.
> 
> Well, read the subject of your e-mail and tell me what it says ;-)
Heh. Oops.

Yes, I agree that "add -p" is not especially useful for that case, and the workflow I was describing is very different[1].

Sorry for the noise.
-Peff
[1] For the record, I _do_ find myself using "git add -N" so that new
    files can be part of my "git add -p" workflow. So that feature is
    working as intended. It would save me a little bit of effort,
    though, if I could tell git I also want to include untracked files
    during the "-p" session, and dispense with the earlier "add -N".
    I'd also find it useful to mark conflicts as resolved, but I think
    we discussed that once before and you brought up some ugly corner
    cases.
Josh Triplett· Jan 10, 2012, 22:29 UTC · re: Jeff King · lore
On Tue, Jan 10, 2012 at 02:38:57PM -0500, Jeff King wrote:
Show 17 quoted lines
> On Tue, Jan 10, 2012 at 11:33:39AM -0800, Junio C Hamano wrote:
> 
> > Jeff King <peff@peff.net> writes:
> > 
> > >> Even if you start with "add -N", there won't be individual "hunks" you can
> > >> pick and choose from diffing emptiness and the whole new file, so you end
> > >> up using "edit hunk" interface.
> > >
> > > I don't think the main impetus for this is that people necessarily want
> > > to pick and choose hunks from added files.
> > 
> > Well, read the subject of your e-mail and tell me what it says ;-)
> 
> Heh. Oops.
> 
> Yes, I agree that "add -p" is not especially useful for that case, and
> the workflow I was describing is very different[1].

I've gotten used to editing diffs directly, and when I just want to include subsets of a file on a chunk-by-chunk basis (for instance, one new function but not another new function), I'd find it a lot easier and less error-prone to "git add -p newfile" and edit a diff than to copy the file aside, edit the original to delete pieces I don't want, add, commit, and copy the file back.

Most importantly, I want to use "git add -p" because I know it'll *never* modify my working copy, only the index. I find that a useful safety property.

Apart from that, it also means I have less mental state to track ("remember to copy the original file back later").

- Josh Triplett

← back to recent threads