{"thread":{"id":"38055","subject":"Extended splitting for \"git add --interactive\"","startedAt":"2014-11-26T14:55:19Z","lastAt":"2014-11-27T15:46:37Z","messageCount":6,"participants":["Ulrich Windl","Junio C Hamano","Johan Herland","Brandon McCaig"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"252582","messageId":"5475F7E7020000A100018050@gwsmtp1.uni-regensburg.de","threadId":"38055","inReplyTo":null,"subject":"Extended splitting for \"git add --interactive\"","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2014-11-26T14:55:19Z","receivedAt":"2014-11-26T14:55:19Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"Hi!\n\nThis is for git-1.7.12 (an older version from the SLES11 SP3 SDK). If the issue is solved meanwhile, I'll be happy, and I apologize for being too lazy to find out.\n\nCurrently Git cannot split a block of changes like\n\n-AAA\n-BBB\n+CCC\n+DDD\n\nInto\n-AAA\n+CCC\nand\n-BBB\n+DDD\n\nSo you'll have to edit it and waste me extra time (People probably use split if they know what they are doing, so maybe allow that).\n\nAnother split that is not possible is a split across an empty line, like:\n\n+AAA\n+     <empty line (in reality)>\n+BBB\n\nOne could split that either into two parts with the empty lines belonging to one of AAA or BBB, or into three parts where the empty line is just another junk to accept or refuse. See comment above on why I'd like that.\n\nRegards,\nUlrich Windl\n"},{"id":"252593","messageId":"xmqq3895rdr1.fsf@gitster.dls.corp.google.com","threadId":"38055","inReplyTo":"5475F7E7020000A100018050@gwsmtp1.uni-regensburg.de","subject":"Re: Extended splitting for \"git add --interactive\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-26T18:57:38Z","receivedAt":"2014-11-26T18:57:38Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de> writes:\n\n> This is for git-1.7.12 (an older version from the SLES11 SP3 SDK). If\n> the issue is solved meanwhile, I'll be happy, and I apologize for\n> being too lazy to find out.\n\nThe answer is no ;-).\n\n> Currently Git cannot split a block of changes like\n>\n> -AAA\n> -BBB\n> +CCC\n> +DDD\n>\n> Into\n> -AAA\n> +CCC\n> and\n> -BBB\n> +DDD\n\nAnd it is unlikely to do so ever, because it is a wrong thing to do.\n\nWhat makes the user happy to see above split when the user is\nexpecting this instead?\n\n-AAA\nand\n-BBB\n+CCC\n+DDD\n\n> Another split that is not possible is a split across an empty line, like:\n>\n> +AAA\n> +     <empty line (in reality)>\n> +BBB\n\nLikewise.  An empty line is not that special.  AAA may be adding one\nblock of lines \"if (condition) { ... }\" and BBB may be another, and\nit often happens that you would want to separate these into two\nchanges, with or without an empty line in between.\n\n   +if (foo) {\n   +  do foo thing\n   +}\n   +if (bar) {\n   +  do bar thing\n   +}\n   \nHaving said all that, I am not opposed to a usable idea to allow the\nuser to specify where in a contiguous block of -*+* to break a hunk\nand how.\n"},{"id":"252600","messageId":"xmqqtx1lpv50.fsf@gitster.dls.corp.google.com","threadId":"38055","inReplyTo":"xmqq3895rdr1.fsf@gitster.dls.corp.google.com","subject":"Re: Extended splitting for \"git add --interactive\"","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-11-26T20:24:59Z","receivedAt":"2014-11-26T20:24: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> \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de> writes:\n>\n>> Another split that is not possible is a split across an empty line, like:\n>>\n>> +AAA\n>> +     <empty line (in reality)>\n>> +BBB\n>\n> Likewise.  An empty line is not that special.  AAA may be adding one\n> block of lines \"if (condition) { ... }\" and BBB may be another, and\n> it often happens that you would want to separate these into two\n> changes, with or without an empty line in between.\n>\n>    +if (foo) {\n>    +  do foo thing\n>    +}\n>    +if (bar) {\n>    +  do bar thing\n>    +}\n>    \n> Having said all that, I am not opposed to a usable idea to allow the\n> user to specify where in a contiguous block of -*+* to break a hunk\n> and how.\n\nOf course, splitting at blank or at any arbitrary point that the\nimplementor of this new feature decides to be good is not end of the\nworld.  If the split at that chosen point is undesirable, the user\ncan join them back.  But then the feature did not help such a user\nvery much.  So that selection of \"any arbitrary point\" has to be\nfairly a good heuristic, making majority of users happy, to be worth\nfor users to try.  If they try splitting with the heuristics and get\na good result 80% of times, 20% of time they instead may need to\njoin the wrong splits back, but overall it will be a win.\n\nIn an extreme case, we could have an option to split a run of zero\nor more \"-\" lines followed by zero or more \"+\" lines into one line\nper hunk, and let the user pick the line they want, which would\nsolve your original issue of turning \"-A-B+C+D\" into \"-A+C\" and\n\"-B+D\", while allowing them to be commited with a different\nsplitting, e.g. \"-A\" and \"-B+C+D\".\n\nBut at that point, I suspect most people may choose to (e)dit the\npatch themselves instead.  I dunno.\n"},{"id":"252637","messageId":"5476F4FA020000A100018078@gwsmtp1.uni-regensburg.de","threadId":"38055","inReplyTo":"xmqq3895rdr1.fsf@gitster.dls.corp.google.com","subject":"Antw: Re: Extended splitting for \"git add --interactive\"","fromName":"Ulrich Windl","fromEmail":"ulrich.windl@rz.uni-regensburg.de","sentAt":"2014-11-27T08:55:06Z","receivedAt":"2014-11-27T08:55:06Z","isPatch":false,"sender":{"key":"ulrich.windl@rz.uni-regensburg.de","avatar":null},"body":"I probably forgot to mention the obvious: My enhancement request was for cases where git would reject so split a junk. I don't want to change the default split (if it finds a point to split).\nSo maybe call it a \"2nd-level-split\". Only if split refuses to split, you could avoid using \"edit\" to manually split.\nIknow that in gerneral such things can't be right, but you can eith reject the new junks or use \"edit\". I just guessed the feature could save some time on the average.\n\n>>> Junio C Hamano <gitster@pobox.com> schrieb am 26.11.2014 um 19:57 in Nachricht\n<xmqq3895rdr1.fsf@gitster.dls.corp.google.com>:\n> \"Ulrich Windl\" <Ulrich.Windl@rz.uni-regensburg.de> writes:\n> \n>> This is for git-1.7.12 (an older version from the SLES11 SP3 SDK). If\n>> the issue is solved meanwhile, I'll be happy, and I apologize for\n>> being too lazy to find out.\n> \n> The answer is no ;-).\n> \n>> Currently Git cannot split a block of changes like\n>>\n>> -AAA\n>> -BBB\n>> +CCC\n>> +DDD\n>>\n>> Into\n>> -AAA\n>> +CCC\n>> and\n>> -BBB\n>> +DDD\n> \n> And it is unlikely to do so ever, because it is a wrong thing to do.\n> \n> What makes the user happy to see above split when the user is\n> expecting this instead?\n> \n> -AAA\n> and\n> -BBB\n> +CCC\n> +DDD\n> \n>> Another split that is not possible is a split across an empty line, like:\n>>\n>> +AAA\n>> +     <empty line (in reality)>\n>> +BBB\n> \n> Likewise.  An empty line is not that special.  AAA may be adding one\n> block of lines \"if (condition) { ... }\" and BBB may be another, and\n> it often happens that you would want to separate these into two\n> changes, with or without an empty line in between.\n> \n>    +if (foo) {\n>    +  do foo thing\n>    +}\n>    +if (bar) {\n>    +  do bar thing\n>    +}\n>    \n> Having said all that, I am not opposed to a usable idea to allow the\n> user to specify where in a contiguous block of -*+* to break a hunk\n> and how.\n"},{"id":"252639","messageId":"CALKQrgcHvjuynbmRZWAKWu-Ld1-h7eqEZEBqorPTHW9m8onDGg@mail.gmail.com","threadId":"38055","inReplyTo":"5476F4FA020000A100018078@gwsmtp1.uni-regensburg.de","subject":"Re: Re: Extended splitting for \"git add --interactive\"","fromName":"Johan Herland","fromEmail":"johan@herland.net","sentAt":"2014-11-27T10:14:45Z","receivedAt":"2014-11-27T10:14:45Z","isPatch":false,"sender":{"key":"johan@herland.net","avatar":"https://avatars.githubusercontent.com/u/547031?v=4"},"body":"On Thu, Nov 27, 2014 at 9:55 AM, Ulrich Windl\n<Ulrich.Windl@rz.uni-regensburg.de> wrote:\n> I probably forgot to mention the obvious: My enhancement request was\n> for cases where git would reject so split a hunk. I don't want to\n> change the default split (if it finds a point to split).\n> So maybe call it a \"2nd-level-split\". Only if split refuses to split,\n> you could avoid using \"edit\" to manually split.\n> I know that in general such things can't be right, but you can\n> either reject the new hunks or use \"edit\". I just guessed the feature\n> could save some time on the average.\n\nFWIW, I would very much like a \"2nd-level split\" where it simply splits\ninto individual lines. I think it's not worth trying to be extra clever\nabout it. For your example, I'd simply want the following behavior:\n\n  -AAA\n  -BBB\n  +CCC\n  +DDD\n  Stage this hunk? SPLIT\n\n  -AAA\n  Stage this hunk? YES\n\n  -BBB\n  Stage this hunk? NO\n\n  +CCC\n  Stage this hunk? YES\n\n  +DDD\n  Stage this hunk? NO\n\nThis would allow me to stage the following:\n\n  -AAA\n  +CCC\n\nand leave the following unstaged:\n\n  -BBB\n  +DDD\n\nbut would also allow any other combination.\n\n\n...Johan\n\n-- \nJohan Herland, <johan@herland.net>\nwww.herland.net\n"},{"id":"252641","messageId":"CANUGeEYrpduzwiUY3KuWbR8MDpfFpeBRva15+LxMsL1+W82mWg@mail.gmail.com","threadId":"38055","inReplyTo":"CALKQrgcHvjuynbmRZWAKWu-Ld1-h7eqEZEBqorPTHW9m8onDGg@mail.gmail.com","subject":"Re: Re: Extended splitting for \"git add --interactive\"","fromName":"Brandon McCaig","fromEmail":"bamccaig@gmail.com","sentAt":"2014-11-27T15:46:37Z","receivedAt":"2014-11-27T15:46:37Z","isPatch":false,"sender":{"key":"bamccaig@gmail.com","avatar":"https://gravatar.com/avatar/05b01f2b62a5ddbaa1946579266a8d9e970fed0c0b3c20e8d42aca973c31531c?d=mp&s=160"},"body":"Hello,\n\nOn Thu, Nov 27, 2014 at 5:14 AM, Johan Herland <johan@herland.net> wrote:\n> FWIW, I would very much like a \"2nd-level split\" where it simply splits\n> into individual lines. I think it's not worth trying to be extra clever\n> about it. For your example, I'd simply want the following behavior:\n>\n>   -AAA\n>   -BBB\n>   +CCC\n>   +DDD\n>   Stage this hunk? SPLIT\n>\n>   -AAA\n>   Stage this hunk? YES\n>\n>   -BBB\n>   Stage this hunk? NO\n>\n>   +CCC\n>   Stage this hunk? YES\n>\n>   +DDD\n>   Stage this hunk? NO\n>\n> This would allow me to stage the following:\n>\n>   -AAA\n>   +CCC\n>\n> and leave the following unstaged:\n>\n>   -BBB\n>   +DDD\n>\n> but would also allow any other combination.\n\nHaving (e)dited a lot of hunks manually I can see it being a bit\ndifficult to understand line-by-line (but then I rarely split as it\nrarely does what I need so I'm not sure what use cases this would\napply). I just had an idea about re-joining added lines in the output\neach time to show you what you're actually doing to the hunk with each\nprompt. I don't know if it's a good idea. Illustration:\n\n AAA\n BBB\n-CCC\n-DDD\n+EEE\n+FFF\n GGG\nStage this hunk? s\n\n  AAA\n  BBB\n- CCC\nStage this hunk? y\n\n  AAA\n  BBB\n -CCC\n- DDD\nStage this hunk? n\n\n  AAA\n  BBB\n -CCC\n  DDD\n+ EEE\nStage this hunk? y\n\n  AAA\n  BBB\n -CCC\n  DDD\n +EEE\n+ FFF\n  GGG\nStage this hunk? n\n\nIn any case, I find that editing the hunk is generally faster than\ntrying to figure out if split is going to do something useful (perhaps\nstudying the Git code would help in that regard).\n\nThat said, the key to making editing the hunk (or patches in general)\nefficient is adding keybindings to your favorite editor to edit\nunified diffs. In my Vim configuration I map ,, to a function that\nremoves the current line change (removes - line, deletes + line) and\n,. to add - to context lines. Both also always move down a line\nautomatically and center that line on the screen, and have no effect\non lines for which the chosen function has no meaning. So editing a\nhunk typically becomes ,, to remove unwanted changes from the current\nhunk or skip context lines and j to skip good lines to get to the next\nchanges. Occasionally I use ,. to remove a context line that was in my\noriginal source. And if I want to invent a + line it's just o or O.\nThe bit I'm editing remains in the middle of my screen with my whole\nscreen for context. My relevant vimrc:\n\nautocmd FileType diff\n            \\ nnoremap ,, :call UndoPatch()<CR>|\n            \\ nnoremap ,. :s/^ /-/e<CR>:nohl<CR>jzz\n\nfunction! UndoPatch()\n    normal! 0\n\n    if getline('.') =~ '^+'\n        delete\n        normal! zz\n        return\n    endif\n\n    if getline('.') =~ '^-'\n        s/^-/ /\n        nohlsearch\n    endif\n\n    normal! j\n    normal! ^\n    normal! zz\nendfunction\n\nMaybe that'll be useful for somebody else. Any editor suitable for a\nprogrammer will be able to do something similar. I suspect that\ncustomizing your editor will be time better spent.\n\nRegards,\n\n\n-- \nBrandon McCaig <bamccaig@gmail.com> <bamccaig@castopulence.org>\nCastopulence Software <https://www.castopulence.org/>\nBlog <http://www.bambams.ca/>\nperl -E '$_=q{V zrna gur orfg jvgu jung V fnl. }.\nq{Vg qbrfa'\\''g nyjnlf fbhaq gung jnl.};\ntr/A-Ma-mN-Zn-z/N-Zn-zA-Ma-m/;say'\n"}]}