{"thread":{"id":"52223","subject":"Change behavior of git add --patch on newly added file?","startedAt":"2019-11-08T22:50:44Z","lastAt":"2019-11-13T01:47:47Z","messageCount":7,"participants":["Emily Shaffer","Junio C Hamano","Jeff King","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"385820","messageId":"20191108225035.GA60198@google.com","threadId":"52223","inReplyTo":null,"subject":"Change behavior of git add --patch on newly added file?","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2019-11-08T22:50:35Z","receivedAt":"2019-11-08T22:50:44Z","isPatch":false,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"Should 'git add -p <newly-added-file>' do the same thing as 'git add -N\n<newly-added-file && git add -p <newly-added-file>'?\n\nTo demonstrate:\n  git init .\n  printf \"%s\\n\" {1..10} >newfile\n  git add -p newfile\n\nThis outputs \"No changes.\" 'git status' shows that 'newfile' is\nuntracked.\n\nHowever, since I want each of my commits to be atomic, I want only lines\n1-5 in my first commit. (Or more realistically, maybe I only want\nfunction stubs.)\n\nI *can* do:\n  git add -N newfile\n  git add -p newfile\n\nBut, why doesn't 'git add -p' just do that on its own? At the very\nleast, \"No changes\" is a pretty cryptic output - there ARE changes,\nright here in my workspace! (I think it means \"there isn't a 'newfile' in\nthe index, so we can't say whether there is a difference between\n'newfile' in the index and 'newfile' in your working tree\".)\n\nAnd if I reason to myself, \"I can only add --patch a file which is\ntracked, so I need to track this file first\" and go skimming through the\ndocumentation for \"git add\", -N doesn't jump out very much:\n\n  -N, --intent-to-add   record only the fact that the path will be added later\n\nor,\n\n  -N, --intent-to-add\n      Record only the fact that the path will be added later. An entry for the path is placed in\n      the index with no content. This is useful for, among other things, showing the unstaged\n      content of such files with git diff and committing them with git commit -a.\n\nConsidering that other parts of the add documentation talk about\ntracked or untracked files, I personally miss the upshot that we are\ntracking a file which was previously untracked with '-N'. (My gut\nguess is that while many Git users are familiar with \"tracked\" or\n\"untracked\" but less Git users are familiar with what it means to \"place\nin the index\".)\n\nInterestingly, in the whole-file deletion case, I *do* get interactive\nsupport....kind of.\n\n  rm trackedfile\n  git add -p trackedfile\n\n  diff --git a/trackedfile b/trackedfile\n  index f00c965..0000000\n  --- a/trackedfile\n  +++ /dev/null\n  deleted file mode 100644\n  @@ -1,10 +0,0 @@\n  -1\n  -2\n  -3\n  -4\n  -5\n  -6\n  -7\n  -8\n  -9\n  -10\n  (1/1) Stage deletion [y,n,q,a,d,?]? e\n  Sorry, cannot edit this hunk\n\n\nIs there a reason that git add -p can't do whole-file support this way?\nWhile I'm less sure about what I'd like to see for copied files, I do\nfeel like there's a strong argument for patch adding new or deleted\nfiles.\n\n - Emily\n"},{"id":"385823","messageId":"xmqq5zjtn07v.fsf@gitster-ct.c.googlers.com","threadId":"52223","inReplyTo":"20191108225035.GA60198@google.com","subject":"Re: Change behavior of git add --patch on newly added file?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-11-09T04:27:16Z","receivedAt":"2019-11-09T04:27:24Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n> Should 'git add -p <newly-added-file>' do the same thing as 'git add -N\n> <newly-added-file && git add -p <newly-added-file>'?\n\nProbably.  \n\nI originally wrote \"git add -i\" with the intention that the\ninteractive mode is _the_ primary interface to the machinery, so the\nexpected way to work with a new file was \"git add -i\", tell the\ncommand to add that <newly-added-file>, and do the \"patch\" thing\nusing the interactive subcommand to do so within the \"git add -i\"\nsession.\n\nLater people liked (only) the patch part, and \"git add -p\" (and\nvarious \"--patch\" options that invoke \"add -p\" internally from other\ncommands like \"checkout\", \"reset\" were added) was born.  I think\nnobody thought things through when they did so.\n\nIf I were designing \"git add -p\" from scratch and explicitly asked\nnot to do the other parts of the \"--interactive\" feature, I would\nimagine \"add -N && add -p\" combination is what I would make it\nmimic.\n\nPatches welcome, but you may want to check with Dscho as there is an\neffort going on to reimplement the entire \"add -i\" machinery in C.\n\nThanks.\n"},{"id":"385827","messageId":"xmqqpni1ldw2.fsf@gitster-ct.c.googlers.com","threadId":"52223","inReplyTo":"xmqq5zjtn07v.fsf@gitster-ct.c.googlers.com","subject":"Re: Change behavior of git add --patch on newly added file?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-11-09T07:14:53Z","receivedAt":"2019-11-09T07:14:59Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Emily Shaffer <emilyshaffer@google.com> writes:\n>\n>> Should 'git add -p <newly-added-file>' do the same thing as 'git add -N\n>> <newly-added-file && git add -p <newly-added-file>'?\n> ...\n> Patches welcome, but you may want to check with Dscho as there is an\n> effort going on to reimplement the entire \"add -i\" machinery in C.\n\nOh, having said all that, for a newly added file, all you have is a\nhunk that is full of added lines and nothing else, so even 's'plit\ninteractive subcommand of \"add -p\" interface would not do anything.\n\nSo I am not sure if performing an implicit \"add -N\" upfront would\nhelp your use case that much.  For that, you'd need to extend hunk\nsplitting UI a bit more, so that the user can split a hunk that only\nadds lines into two at a desired point in the hunk.\n"},{"id":"385866","messageId":"20191111034111.GB5912@sigill.intra.peff.net","threadId":"52223","inReplyTo":"20191108225035.GA60198@google.com","subject":"Re: Change behavior of git add --patch on newly added file?","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2019-11-11T03:41:11Z","receivedAt":"2019-11-11T03:41:13Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Nov 08, 2019 at 02:50:35PM -0800, Emily Shaffer wrote:\n\n> Is there a reason that git add -p can't do whole-file support this way?\n> While I'm less sure about what I'd like to see for copied files, I do\n> feel like there's a strong argument for patch adding new or deleted\n> files.\n\nI have been mildly annoyed by trying to \"add -p\" an untracked file\nbefore, too. But there is some complexity with broader pathspecs, I\nthink. For instance, imagine I have a subdirectory in my repo with three\nfiles:\n\n  - subdir/tracked -- this one is a real tracked file with modifications\n\n  - subdir/new -- this is a new file I've just added\n\n  - subdir/cruft -- this is some junk I wrote while debugging\n\nThen what should:\n\n  git add -p subdir\n\ndo? Obviously it should ask about \"tracked\". And we'd want it to do the\n\"add -N\" thing on \"new\", but not on \"cruft\".\n\nI don't mind being _asked_ about the \"cruft\" file if I can just say \"n\"\nto ignore it. But I wouldn't want it left in the index as intent-to-add.\nSo just pretending that it was the same as:\n\n  git add -N \"$@\" && git add -p \"$@\"\n\nseems poor. But it would be fine if instead we tentatively consider\nfiles matching the pathspec as tracked (assuming they're not\n.gitignored), and then the end result for each path is either that it\nhas content staged by \"-p\", or it's left unchanged (including untracked\nif it was not previously tracked).\n\nI'm not sure when you intended for this to kick in. The case of \"git add\n-p an-actual-file\", where the pathspec matches exactly one file, is an\nobvious one. But because the shell expands wildcards, too, I don't know\nif it's a good heuristic for \"the user really meant to mention this\nfile\". I.e., if I do:\n\n  git add -p *.c\n\nGit will see individual filenames on the command-line, but the user may\nnot have wanted to include all of them.\n\nThere's also a question of what \"git add -p\" without any pathspecs\nshould do. I'd think you would probably want no change from the current\nbehavior (i.e., not even asking about untracked files).\n\n-Peff\n"},{"id":"386033","messageId":"20191112184720.GB38770@google.com","threadId":"52223","inReplyTo":"xmqq5zjtn07v.fsf@gitster-ct.c.googlers.com","subject":"Re: Change behavior of git add --patch on newly added file?","fromName":"Emily Shaffer","fromEmail":"emilyshaffer@google.com","sentAt":"2019-11-12T18:47:20Z","receivedAt":"2019-11-12T18:47:29Z","isPatch":false,"sender":{"key":"nasamuffin@google.com","avatar":"https://avatars.githubusercontent.com/u/1606826?v=4"},"body":"On Sat, Nov 09, 2019 at 01:27:16PM +0900, Junio C Hamano wrote:\n> Emily Shaffer <emilyshaffer@google.com> writes:\n> \n> > Should 'git add -p <newly-added-file>' do the same thing as 'git add -N\n> > <newly-added-file && git add -p <newly-added-file>'?\n> \n> Probably.  \n> \n> I originally wrote \"git add -i\" with the intention that the\n> interactive mode is _the_ primary interface to the machinery, so the\n> expected way to work with a new file was \"git add -i\", tell the\n> command to add that <newly-added-file>, and do the \"patch\" thing\n> using the interactive subcommand to do so within the \"git add -i\"\n> session.\n> \n> Later people liked (only) the patch part, and \"git add -p\" (and\n> various \"--patch\" options that invoke \"add -p\" internally from other\n> commands like \"checkout\", \"reset\" were added) was born.  I think\n> nobody thought things through when they did so.\n> \n> If I were designing \"git add -p\" from scratch and explicitly asked\n> not to do the other parts of the \"--interactive\" feature, I would\n> imagine \"add -N && add -p\" combination is what I would make it\n> mimic.\n> \n> Patches welcome, but you may want to check with Dscho as there is an\n> effort going on to reimplement the entire \"add -i\" machinery in C.\n\nAh, this is a compelling point. I imagine the landscape will be fairly\ndifferent when that effort is finished.\n\n\nFrom the replies, it sounds like it's a favorable change, but it makes\nsense to wait on it considering the refactor to use C. Thanks, all.\n\n - Emily\n"},{"id":"386043","messageId":"nycvar.QRO.7.76.6.1911122114380.46@tvgsbejvaqbjf.bet","threadId":"52223","inReplyTo":"20191112184720.GB38770@google.com","subject":"Re: Change behavior of git add --patch on newly added file?","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2019-11-12T20:16:31Z","receivedAt":"2019-11-12T20:16:53Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Emily,\n\nOn Tue, 12 Nov 2019, Emily Shaffer wrote:\n\n> On Sat, Nov 09, 2019 at 01:27:16PM +0900, Junio C Hamano wrote:\n> > Emily Shaffer <emilyshaffer@google.com> writes:\n> >\n> > > Should 'git add -p <newly-added-file>' do the same thing as 'git add -N\n> > > <newly-added-file && git add -p <newly-added-file>'?\n> >\n> > Probably.\n> >\n> > I originally wrote \"git add -i\" with the intention that the\n> > interactive mode is _the_ primary interface to the machinery, so the\n> > expected way to work with a new file was \"git add -i\", tell the\n> > command to add that <newly-added-file>, and do the \"patch\" thing\n> > using the interactive subcommand to do so within the \"git add -i\"\n> > session.\n> >\n> > Later people liked (only) the patch part, and \"git add -p\" (and\n> > various \"--patch\" options that invoke \"add -p\" internally from other\n> > commands like \"checkout\", \"reset\" were added) was born.  I think\n> > nobody thought things through when they did so.\n> >\n> > If I were designing \"git add -p\" from scratch and explicitly asked\n> > not to do the other parts of the \"--interactive\" feature, I would\n> > imagine \"add -N && add -p\" combination is what I would make it\n> > mimic.\n> >\n> > Patches welcome, but you may want to check with Dscho as there is an\n> > effort going on to reimplement the entire \"add -i\" machinery in C.\n>\n> Ah, this is a compelling point. I imagine the landscape will be fairly\n> different when that effort is finished.\n>\n>\n> From the replies, it sounds like it's a favorable change, but it makes\n> sense to wait on it considering the refactor to use C. Thanks, all.\n\nThe patch series can already be viewed at PRs #170-175 on\nhttps://github.com/gitgitgadget/git; maybe you want to have a look at\nimplementing this feature on top of\nhttps://github.com/dscho/git/tree/add-p-in-c-config-settings?\n\nCiao,\nDscho\n"},{"id":"386080","messageId":"xmqqv9roczt2.fsf@gitster-ct.c.googlers.com","threadId":"52223","inReplyTo":"20191112184720.GB38770@google.com","subject":"Re: Change behavior of git add --patch on newly added file?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-11-13T01:47:37Z","receivedAt":"2019-11-13T01:47:47Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Emily Shaffer <emilyshaffer@google.com> writes:\n\n>> Patches welcome, but you may want to check with Dscho as there is an\n>> effort going on to reimplement the entire \"add -i\" machinery in C.\n>\n> Ah, this is a compelling point. I imagine the landscape will be fairly\n> different when that effort is finished.\n>\n>\n> From the replies, it sounds like it's a favorable change, but it makes\n> sense to wait on it considering the refactor to use C. Thanks, all.\n\nPeff's \"how would you tell between genuinely untracked ones and\nthose you would want to add\" and \"should 'add -p' with no pathspec\nattempt to 'add -N' everything under the sun?\" are both quite valid\npoints.  I already raised \"'add -N && add -p' would give you a\nsingle hunk that adds everything. Are you willing to manually split,\nand how well would it work?\" in a separate message.  These design\nissues can be resolved without coding, and should be resolved before\nyou start randomly typing ;-)\n\nThanks.\n"}]}