{"thread":{"id":"45150","subject":"[PATCH v3] reset: add an example of how to split a commit into two","startedAt":"2017-02-16T00:22:31Z","lastAt":"2017-02-16T21:27:01Z","messageCount":4,"participants":["Jacob Keller","Junio C Hamano"],"isPatch":true,"patchVersion":3,"patchTotal":null},"messages":[{"id":"311711","messageId":"20170216002212.31088-1-jacob.e.keller@intel.com","threadId":"45150","inReplyTo":null,"subject":"[PATCH v3] reset: add an example of how to split a commit into two","fromName":"Jacob Keller","fromEmail":"jacob.e.keller@intel.com","sentAt":"2017-02-16T00:22:12Z","receivedAt":"2017-02-16T00:22:31Z","isPatch":true,"sender":{"key":"jacob.e.keller@intel.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"From: Jacob Keller <jacob.keller@gmail.com>\n\nIt is often useful to break a commit into multiple parts that are more\nlogical separations. This can be tricky to learn how to do without the\nbrute-force method if re-writing code or commit messages from scratch.\n\nAdd a section to the git-reset documentation which shows an example\nprocess for how to use git add -p and git commit -c HEAD@{1} to\ninteractively break a commit apart and re-use the original commit\nmessage as a starting point when making the new commit message.\n\nSigned-off-by: Jacob Keller <jacob.keller@gmail.com>\nSigned-off-by: Junio C Hamano <gitster@pobox.com>\n---\nThe interdiff between v2 and v3 is not really worth showing since I\nbasically re-wrote the entire section a bit. I reworded the descriptions\nand steps to indicate that you can break a commit apart into an\narbitrary number of separate commits. I also added a bit more\nexplanation to each step, and separately numbered the \"repeat some steps\nmultiple times\" portion.\n\n Documentation/git-reset.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++\n 1 file changed, 48 insertions(+)\n\ndiff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt\nindex 25432d9257f9..67a63574092d 100644\n--- a/Documentation/git-reset.txt\n+++ b/Documentation/git-reset.txt\n@@ -292,6 +292,54 @@ $ git reset --keep start                    <3>\n <3> But you can use \"reset --keep\" to remove the unwanted commit after\n     you switched to \"branch2\".\n \n+Split a commit apart into a sequence of commits::\n++\n+Suppose that you have create lots of logically separate changes and commit them\n+together. Then, later you decide that it might be better to have each logical\n+chunk associated with its own commit. You can use git reset to rewind history\n+without changing the contents of your local files, and then successively use\n+git add -p to interactively select which hunks to include into each commit,\n+using git commit -c to pre-populate the commit message.\n++\n+------------\n+$ git reset -N HEAD^                        <1>\n+$ git add -p                                <2>\n+$ git diff --cached                         <3>\n+$ git commit -c HEAD@{1}                    <4>\n+...                                         <5>\n+$ git add ...                               <6>\n+$ git diff --cached                         <7>\n+$ git commit ...                            <8>\n+------------\n++\n+<1> First, reset the history back one commit so that we remove the original\n+    commit, but leave the working tree with all the changes. The -N ensures\n+    that any new files added with HEAD are still marked so that git add -p\n+    will find them.\n+<2> Next, we interactively select diff hunks to add using the git add -p\n+    facility. This will ask you about each diff hunk in sequence and you can\n+    use simple commands such as \"yes, include this\", \"No don't include this\"\n+    or even the very powerful \"edit\" facility.\n+<3> Once satisfied with the hunks you want to include, you should verify what\n+    has been prepared for the first commit by using git diff --cached. This\n+    shows all the changes that have been moved into the index and are about\n+    to be committed.\n+<4> Next, commit the changes stored in the index. The -c option specifies to\n+    pre-populate the commit message from the original message that you started\n+    with in the first commit. This is helpful to avoid retyping it. The HEAD@{1}\n+    is a special notation for the commit that HEAD used to be at prior to the\n+    original reset commit (1 change ago). See linkgit:git-reflog[1] for more\n+    details. You may also use any other valid commit reference.\n+<5> You can repeat steps 2-4 multiple times to break the original code into\n+    any number of commits.\n+<6> Now you've split out many of the changes into their own commits, and might\n+    no longer use the patch mode of git add, in order to select all remaining\n+    uncommitted changes.\n+<7> Once again, check to verify that you've included what you want to. You may\n+    also wish to verify that git diff doesn't show any remaining changes to be\n+    committed later.\n+<8> And finally create the final commit.\n+\n \n DISCUSSION\n ----------\n-- \n2.12.0.rc0.177.g63172abf21d0\n\n"},{"id":"311797","messageId":"xmqq4lzux7sc.fsf@gitster.mtv.corp.google.com","threadId":"45150","inReplyTo":"20170216002212.31088-1-jacob.e.keller@intel.com","subject":"Re: [PATCH v3] reset: add an example of how to split a commit into two","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-02-16T19:19:47Z","receivedAt":"2017-02-16T19:19:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jacob Keller <jacob.e.keller@intel.com> writes:\n\n> The interdiff between v2 and v3 is not really worth showing since I\n> basically re-wrote the entire section a bit.\n\nCould this be made into an incremental, now that v2 has been in\n'next' for about 10 days, please?\n\n> +Split a commit apart into a sequence of commits::\n> ++\n> +Suppose that you have create lots of logically separate changes and commit them\n\ns/create/&d/; s/commit/&ed/\n\n> +together. Then, later you decide that it might be better to have each logical\n> +chunk associated with its own commit. You can use git reset to rewind history\n> +without changing the contents of your local files, and then successively use\n> +git add -p to interactively select which hunks to include into each commit,\n> +using git commit -c to pre-populate the commit message.\n> ++\n> +------------\n> +$ git reset -N HEAD^                        <1>\n> +$ git add -p                                <2>\n> +$ git diff --cached                         <3>\n> +$ git commit -c HEAD@{1}                    <4>\n> +...                                         <5>\n> +$ git add ...                               <6>\n> +$ git diff --cached                         <7>\n> +$ git commit ...                            <8>\n> +------------\n> ++\n> +<1> First, reset the history back one commit so that we remove the original\n> +    commit, but leave the working tree with all the changes. The -N ensures\n> +    that any new files added with HEAD are still marked so that git add -p\n> +    will find them.\n> +<2> Next, we interactively select diff hunks to add using the git add -p\n> +    facility. This will ask you about each diff hunk in sequence and you can\n> +    use simple commands such as \"yes, include this\", \"No don't include this\"\n> +    or even the very powerful \"edit\" facility.\n> +<3> Once satisfied with the hunks you want to include, you should verify what\n> +    has been prepared for the first commit by using git diff --cached. This\n> +    shows all the changes that have been moved into the index and are about\n> +    to be committed.\n> +<4> Next, commit the changes stored in the index. The -c option specifies to\n> +    pre-populate the commit message from the original message that you started\n> +    with in the first commit. This is helpful to avoid retyping it. The HEAD@{1}\n> +    is a special notation for the commit that HEAD used to be at prior to the\n> +    original reset commit (1 change ago). See linkgit:git-reflog[1] for more\n> +    details. You may also use any other valid commit reference.\n> +<5> You can repeat steps 2-4 multiple times to break the original code into\n> +    any number of commits.\n> +<6> Now you've split out many of the changes into their own commits, and might\n> +    no longer use the patch mode of git add, in order to select all remaining\n> +    uncommitted changes.\n> +<7> Once again, check to verify that you've included what you want to. You may\n> +    also wish to verify that git diff doesn't show any remaining changes to be\n> +    committed later.\n> +<8> And finally create the final commit.\n> +\n\nNicely done.  We could talk more \"best practice\" things in this\nsequence (e.g. \"'stash --keep' then test in isolation\"), but it is\nalready sufficiently long, so extending it may hurt the readability\nmore than it helps by guiding the readers to better ways.\n\n"},{"id":"311801","messageId":"xmqqpoihx6f4.fsf@gitster.mtv.corp.google.com","threadId":"45150","inReplyTo":"xmqq4lzux7sc.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v3] reset: add an example of how to split a commit into two","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-02-16T19:49:19Z","receivedAt":"2017-02-16T19:49:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Jacob Keller <jacob.e.keller@intel.com> writes:\n>\n>> The interdiff between v2 and v3 is not really worth showing since I\n>> basically re-wrote the entire section a bit.\n>\n> Could this be made into an incremental, now that v2 has been in\n> 'next' for about 10 days, please?\n\nNah, I think it is easier to read \"log -p\" if I just revert v2 out\nof existence from 'next', and queue this (with a minor typofixes) as\na different topic to be merged later to 'master'.\n\nSo no need to resend and certainly no need to make it incremental.\n\n>> +Split a commit apart into a sequence of commits::\n>> ++\n>> +Suppose that you have create lots of logically separate changes and commit them\n>\n> s/create/&d/; s/commit/&ed/\n\nI'd do this myself while queuing.\n\nThanks.\n\n>\n>> +together. Then, later you decide that it might be better to have each logical\n>> +chunk associated with its own commit. ...\n"},{"id":"311811","messageId":"CA+P7+xr4a+NK8Ye5DK7=EdDfZTSwuZsp3kG3DMHabCu5z+sbCQ@mail.gmail.com","threadId":"45150","inReplyTo":"xmqqpoihx6f4.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v3] reset: add an example of how to split a commit into two","fromName":"Jacob Keller","fromEmail":"jacob.keller@gmail.com","sentAt":"2017-02-16T21:26:35Z","receivedAt":"2017-02-16T21:27:01Z","isPatch":true,"sender":{"key":"jacob.keller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/874719?v=4"},"body":"On Thu, Feb 16, 2017 at 11:49 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> Jacob Keller <jacob.e.keller@intel.com> writes:\n>>\n>>> The interdiff between v2 and v3 is not really worth showing since I\n>>> basically re-wrote the entire section a bit.\n>>\n>> Could this be made into an incremental, now that v2 has been in\n>> 'next' for about 10 days, please?\n>\n> Nah, I think it is easier to read \"log -p\" if I just revert v2 out\n> of existence from 'next', and queue this (with a minor typofixes) as\n> a different topic to be merged later to 'master'.\n>\n\nOk. Yea, I didn't even realize it was put into next because of the\nvarious comments I'd received. I guess I could have checked, but the\ndiff really is bad when seeing incrementally.\n\n> So no need to resend and certainly no need to make it incremental.\n>\n>>> +Split a commit apart into a sequence of commits::\n>>> ++\n>>> +Suppose that you have create lots of logically separate changes and commit them\n>>\n>> s/create/&d/; s/commit/&ed/\n>\n> I'd do this myself while queuing.\n>\n> Thanks.\n\nThanks,\nJake\n"}]}