{"thread":{"id":"26715","subject":"git stash: add --index-only, or --keep-index should not stash index?","startedAt":"2011-03-11T18:47:19Z","lastAt":"2011-03-16T23:06:36Z","messageCount":7,"participants":["Piotr Krukowiecki","Neal Kreitzinger","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"163241","messageId":"4D7A6E37.8080104@gmail.com","threadId":"26715","inReplyTo":null,"subject":"git stash: add --index-only, or --keep-index should not stash index?","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-03-11T18:47:19Z","receivedAt":"2011-03-11T18:47:19Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"Hi,\n\nI wanted to do something like \"Testing partial commits\" described in\ngit-stash documentation (see end of mail for reference). I think this\nis a common scenario: you start working on some feature, then discover\na bug, start fixing it, but realize it needs more work. So now you have\ntwo features that needs more work (both are not ready for committing). \n\nThe documentation says to use --keep-index in this case.\n\nThe problem is that --keep-index leaves changes in index intact, but at\nthe same time it saves them in stash. So if I edit those changes I'm likely\nto get conflicts when applying the stash.\n\nFor example:\n\n$ git init && echo a > a && git add . && git commit -m a\n$ echo x > a && git add a && git stash save --keep-index\n$ echo y > a && git add a && git commit -m y\n$ git stash pop\nAuto-merging a\nCONFLICT (content): Merge conflict in a\n\nMaybe --keep-index should not stash staged changes? This would fix this\nproblem. And I can't  think of a situation when would want to stash changes\nand at the same time keep them.\n\nIf --keep-index works correctly maybe a new option, for example --index-only\n(or --cached-only?) could be introduced?\n\n\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTesting partial commits::\n\nYou can use `git stash save --keep-index` when you want to make two or\nmore commits out of the changes in the work tree, and you want to test\neach change before committing:\n+\n----------------------------------------------------------------\n# ... hack hack hack ...\n$ git add --patch foo            # add just first part to the index\n$ git stash save --keep-index    # save all other changes to the stash\n$ edit/build/test first part\n$ git commit -m 'First part'     # commit fully tested change\n$ git stash pop                  # prepare to work on all other changes\n# ... repeat above five steps until one commit remains ...\n$ edit/build/test remaining parts\n$ git commit foo -m 'Remaining parts'\n----------------------------------------------------------------\n\n\n-- \nPiotr Krukowiecki\n"},{"id":"163350","messageId":"4D7E9502.4060502@gmail.com","threadId":"26715","inReplyTo":"4D7A6E37.8080104@gmail.com","subject":"Re: git stash: add --index-only, or --keep-index should not stash index?","fromName":"Neal Kreitzinger","fromEmail":"nkreitzinger@gmail.com","sentAt":"2011-03-14T22:21:54Z","receivedAt":"2011-03-14T22:21:54Z","isPatch":false,"sender":{"key":"nkreitzinger@gmail.com","avatar":null},"body":"On 3/11/2011 12:47 PM, Piotr Krukowiecki wrote:\n> Hi,\n>\n> I wanted to do something like \"Testing partial commits\" described in\n> git-stash documentation (see end of mail for reference). I think this\n> is a common scenario: you start working on some feature, then discover\n> a bug, start fixing it, but realize it needs more work. So now you have\n> two features that needs more work (both are not ready for committing).\n>\n> The documentation says to use --keep-index in this case.\n>\n> The problem is that --keep-index leaves changes in index intact, but at\n> the same time it saves them in stash. So if I edit those changes I'm likely\n> to get conflicts when applying the stash.\n>\n> For example:\n>\n> $ git init&&  echo a>  a&&  git add .&&  git commit -m a\n> $ echo x>  a&&  git add a&&  git stash save --keep-index\n> $ echo y>  a&&  git add a&&  git commit -m y\n> $ git stash pop\n> Auto-merging a\n> CONFLICT (content): Merge conflict in a\n>\n> Maybe --keep-index should not stash staged changes? This would fix this\n> problem. And I can't  think of a situation when would want to stash changes\n> and at the same time keep them.\n>\n> If --keep-index works correctly maybe a new option, for example --index-only\n> (or --cached-only?) could be introduced?\n>\n>\n> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n>\n> Testing partial commits::\n>\n> You can use `git stash save --keep-index` when you want to make two or\n> more commits out of the changes in the work tree, and you want to test\n> each change before committing:\n> +\n> ----------------------------------------------------------------\n> # ... hack hack hack ...\n> $ git add --patch foo            # add just first part to the index\n> $ git stash save --keep-index    # save all other changes to the stash\n> $ edit/build/test first part\n> $ git commit -m 'First part'     # commit fully tested change\n> $ git stash pop                  # prepare to work on all other changes\n> # ... repeat above five steps until one commit remains ...\n> $ edit/build/test remaining parts\n> $ git commit foo -m 'Remaining parts'\n> ----------------------------------------------------------------\n>\n>\nbehind-the-scenes, git stash saves your working tree as a commit and \nyour index as another commit.  \"git-stash apply\" and \"git-stash pop\" \nonly apply your stashed-index if you do \"git-stash-apply --index\".  The \ndefault is to only apply your stashed-work-tree.  You can create new \nbranches from your stashes with \"git-stash branch\".  You may find that \nmuch better to deal with for managing your work.  Stashes aren't really \nintended to be the primary way to manage your work, but instead are a \nsupplement.  Branches are a better main tool for managing work.  You can \ncreate a branch from your stash and when the branch is ready you can \nmerge it into your other branch.\n\nv/r,\nneal\n"},{"id":"163405","messageId":"AANLkTikU0xCBzDya3vyfoH4PwzmRi6qmotxNoVc61b=W@mail.gmail.com","threadId":"26715","inReplyTo":"4D7E9502.4060502@gmail.com","subject":"Re: git stash: add --index-only, or --keep-index should not stash index?","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-03-15T19:48:20Z","receivedAt":"2011-03-15T19:48:20Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"On Mon, Mar 14, 2011 at 11:21 PM, Neal Kreitzinger\n<nkreitzinger@gmail.com> wrote:\n> On 3/11/2011 12:47 PM, Piotr Krukowiecki wrote:\n>>\n>> Hi,\n>>\n>> I wanted to do something like \"Testing partial commits\" described in\n>> git-stash documentation (see end of mail for reference). I think this\n>> is a common scenario: you start working on some feature, then discover\n>> a bug, start fixing it, but realize it needs more work. So now you have\n>> two features that needs more work (both are not ready for committing).\n>>\n>> The documentation says to use --keep-index in this case.\n>>\n>> The problem is that --keep-index leaves changes in index intact, but at\n>> the same time it saves them in stash. So if I edit those changes I'm\n>> likely\n>> to get conflicts when applying the stash.\n>>\n>> For example:\n>>\n>> $ git init&&  echo a>  a&&  git add .&&  git commit -m a\n>> $ echo x>  a&&  git add a&&  git stash save --keep-index\n>> $ echo y>  a&&  git add a&&  git commit -m y\n>> $ git stash pop\n>> Auto-merging a\n>> CONFLICT (content): Merge conflict in a\n>>\n>> Maybe --keep-index should not stash staged changes? This would fix this\n>> problem. And I can't  think of a situation when would want to stash\n>> changes\n>> and at the same time keep them.\n>>\n>> If --keep-index works correctly maybe a new option, for example\n>> --index-only\n>> (or --cached-only?) could be introduced?\n>>\n>>\n>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n>>\n>> Testing partial commits::\n>>\n>> You can use `git stash save --keep-index` when you want to make two or\n>> more commits out of the changes in the work tree, and you want to test\n>> each change before committing:\n>> +\n>> ----------------------------------------------------------------\n>> # ... hack hack hack ...\n>> $ git add --patch foo            # add just first part to the index\n>> $ git stash save --keep-index    # save all other changes to the stash\n>> $ edit/build/test first part\n>> $ git commit -m 'First part'     # commit fully tested change\n>> $ git stash pop                  # prepare to work on all other changes\n>> # ... repeat above five steps until one commit remains ...\n>> $ edit/build/test remaining parts\n>> $ git commit foo -m 'Remaining parts'\n>> ----------------------------------------------------------------\n>>\n>>\n> behind-the-scenes, git stash saves your working tree as a commit and your\n> index as another commit.  \"git-stash apply\" and \"git-stash pop\" only apply\n> your stashed-index if you do \"git-stash-apply --index\".  The default is to\n> only apply your stashed-work-tree.  You can create new branches from your\n> stashes with \"git-stash branch\".  You may find that much better to deal with\n> for managing your work.  Stashes aren't really intended to be the primary\n> way to manage your work, but instead are a supplement.  Branches are a\n> better main tool for managing work.  You can create a branch from your stash\n> and when the branch is ready you can merge it into your other branch.\n\nThanks for explanation, I understand there is not much pressure on improving it.\n\nBut it still does not explain how leaving code in index (with\n--keep-index) while\nstill stashing it might be helpful?\n\nI would understand the use of --index-only (I gave an example of use case),\nor even --workdir-only, but not --keep-index. If I'm missing something please\ncorrect me.\n\n\n-- \nPiotr Krukowiecki\n"},{"id":"163496","messageId":"4D80F9F4.9090304@gmail.com","threadId":"26715","inReplyTo":"AANLkTikU0xCBzDya3vyfoH4PwzmRi6qmotxNoVc61b=W@mail.gmail.com","subject":"Re: git stash: add --index-only, or --keep-index should not stash index?","fromName":"Neal Kreitzinger","fromEmail":"nkreitzinger@gmail.com","sentAt":"2011-03-16T17:57:08Z","receivedAt":"2011-03-16T17:57:08Z","isPatch":false,"sender":{"key":"nkreitzinger@gmail.com","avatar":null},"body":"On 3/15/2011 2:48 PM, Piotr Krukowiecki wrote:\n> On Mon, Mar 14, 2011 at 11:21 PM, Neal Kreitzinger\n> <nkreitzinger@gmail.com>  wrote:\n>> On 3/11/2011 12:47 PM, Piotr Krukowiecki wrote:\n>>>\n>>> Hi,\n>>>\n>>> I wanted to do something like \"Testing partial commits\" described in\n>>> git-stash documentation (see end of mail for reference). I think this\n>>> is a common scenario: you start working on some feature, then discover\n>>> a bug, start fixing it, but realize it needs more work. So now you have\n>>> two features that needs more work (both are not ready for committing).\n>>>\n>>> The documentation says to use --keep-index in this case.\n>>>\n>>> The problem is that --keep-index leaves changes in index intact, but at\n>>> the same time it saves them in stash. So if I edit those changes I'm\n>>> likely\n>>> to get conflicts when applying the stash.\n>>>\n>>> For example:\n>>>\n>>> $ git init&&    echo a>    a&&    git add .&&    git commit -m a\n>>> $ echo x>    a&&    git add a&&    git stash save --keep-index\n>>> $ echo y>    a&&    git add a&&    git commit -m y\n>>> $ git stash pop\n>>> Auto-merging a\n>>> CONFLICT (content): Merge conflict in a\n>>>\n>>> Maybe --keep-index should not stash staged changes? This would fix this\n>>> problem. And I can't  think of a situation when would want to stash\n>>> changes\n>>> and at the same time keep them.\n>>>\n>>> If --keep-index works correctly maybe a new option, for example\n>>> --index-only\n>>> (or --cached-only?) could be introduced?\n>>>\n>>>\n>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n>>>\n>>> Testing partial commits::\n>>>\n>>> You can use `git stash save --keep-index` when you want to make two or\n>>> more commits out of the changes in the work tree, and you want to test\n>>> each change before committing:\n>>> +\n>>> ----------------------------------------------------------------\n>>> # ... hack hack hack ...\n>>> $ git add --patch foo            # add just first part to the index\n>>> $ git stash save --keep-index    # save all other changes to the stash\n>>> $ edit/build/test first part\n>>> $ git commit -m 'First part'     # commit fully tested change\n>>> $ git stash pop                  # prepare to work on all other changes\n>>> # ... repeat above five steps until one commit remains ...\n>>> $ edit/build/test remaining parts\n>>> $ git commit foo -m 'Remaining parts'\n>>> ----------------------------------------------------------------\n>>>\n>>>\n>> behind-the-scenes, git stash saves your working tree as a commit and your\n>> index as another commit.  \"git-stash apply\" and \"git-stash pop\" only apply\n>> your stashed-index if you do \"git-stash-apply --index\".  The default is to\n>> only apply your stashed-work-tree.  You can create new branches from your\n>> stashes with \"git-stash branch\".  You may find that much better to deal with\n>> for managing your work.  Stashes aren't really intended to be the primary\n>> way to manage your work, but instead are a supplement.  Branches are a\n>> better main tool for managing work.  You can create a branch from your stash\n>> and when the branch is ready you can merge it into your other branch.\n>\n> Thanks for explanation, I understand there is not much pressure on improving it.\n>\n> But it still does not explain how leaving code in index (with\n> --keep-index) while\n> still stashing it might be helpful?\n>\n> I would understand the use of --index-only (I gave an example of use case),\n> or even --workdir-only, but not --keep-index. If I'm missing something please\n> correct me.\n>\n>\nKeep in mind that a key to his workflow is \"git-add --patch\" method \n(which you did not include in your example).  The workflow of the \nmanpage assumes you will have to resolve conflicts in such a case.  If \nyou look at the \"Pulling into a dirty tree\" workflow of the same manpage \nits obvious that this workflow will almost always get conflicts, but \nthey don't explicitly include conflict resolution in the example.  You \ncould resolve the conflicts for \"Testing partial commits\" in this way:\n\nNeal's Version of Testing partial commits::\n----------------------------------------------------------------\n# ... hack hack hack ...\n$ git add --patch foo            # add just first part to the index\n$ git stash save --keep-index    # save all other changes to the stash\n$ edit/build/test first part\n$ git commit -m 'First part'     # commit fully tested change\n$ git stash pop                  # prepare to work on all other changes\n    (conflict resolution)\n    $ edit conflicted file        # keep new version of the hunk already\n                                  # committed in prior iteration\n    $ git reset HEAD -- foo       # clear conflict from index\n    $ git reset HEAD -- foo       # (again) reset index to match HEAD\n# ... repeat above five (or eight) steps until one commit remains ...\n$ edit/build/test remaining parts\n$ git commit foo -m 'Remaining parts'\n----------------------------------------------------------------\n\nMaybe there's a better way to do this.  Hope this helps.\n\nv/r,\nneal\n"},{"id":"163517","messageId":"AANLkTing5ZQKF4PXtX1peynx2uuc8s+aeBP=fbJWXvWw@mail.gmail.com","threadId":"26715","inReplyTo":"4D80F9F4.9090304@gmail.com","subject":"Re: git stash: add --index-only, or --keep-index should not stash index?","fromName":"Piotr Krukowiecki","fromEmail":"piotr.krukowiecki@gmail.com","sentAt":"2011-03-16T21:37:01Z","receivedAt":"2011-03-16T21:37:01Z","isPatch":false,"sender":{"key":"piotr.krukowiecki@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3259959?v=4"},"body":"On Wed, Mar 16, 2011 at 6:57 PM, Neal Kreitzinger\n<nkreitzinger@gmail.com> wrote:\n> On 3/15/2011 2:48 PM, Piotr Krukowiecki wrote:\n>>\n>> On Mon, Mar 14, 2011 at 11:21 PM, Neal Kreitzinger\n>> <nkreitzinger@gmail.com>  wrote:\n>>>\n>>> On 3/11/2011 12:47 PM, Piotr Krukowiecki wrote:\n>>>>\n>>>> Hi,\n>>>>\n>>>> I wanted to do something like \"Testing partial commits\" described in\n>>>> git-stash documentation (see end of mail for reference). I think this\n>>>> is a common scenario: you start working on some feature, then discover\n>>>> a bug, start fixing it, but realize it needs more work. So now you have\n>>>> two features that needs more work (both are not ready for committing).\n>>>>\n>>>> The documentation says to use --keep-index in this case.\n>>>>\n>>>> The problem is that --keep-index leaves changes in index intact, but at\n>>>> the same time it saves them in stash. So if I edit those changes I'm\n>>>> likely\n>>>> to get conflicts when applying the stash.\n>>>>\n>>>> For example:\n>>>>\n>>>> $ git init&&    echo a>    a&&    git add .&&    git commit -m a\n>>>> $ echo x>    a&&    git add a&&    git stash save --keep-index\n>>>> $ echo y>    a&&    git add a&&    git commit -m y\n>>>> $ git stash pop\n>>>> Auto-merging a\n>>>> CONFLICT (content): Merge conflict in a\n>>>>\n>>>> Maybe --keep-index should not stash staged changes? This would fix this\n>>>> problem. And I can't  think of a situation when would want to stash\n>>>> changes\n>>>> and at the same time keep them.\n>>>>\n>>>> If --keep-index works correctly maybe a new option, for example\n>>>> --index-only\n>>>> (or --cached-only?) could be introduced?\n>>>>\n>>>>\n>>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n>>>>\n>>>> Testing partial commits::\n>>>>\n>>>> You can use `git stash save --keep-index` when you want to make two or\n>>>> more commits out of the changes in the work tree, and you want to test\n>>>> each change before committing:\n>>>> +\n>>>> ----------------------------------------------------------------\n>>>> # ... hack hack hack ...\n>>>> $ git add --patch foo            # add just first part to the index\n>>>> $ git stash save --keep-index    # save all other changes to the stash\n>>>> $ edit/build/test first part\n>>>> $ git commit -m 'First part'     # commit fully tested change\n>>>> $ git stash pop                  # prepare to work on all other changes\n>>>> # ... repeat above five steps until one commit remains ...\n>>>> $ edit/build/test remaining parts\n>>>> $ git commit foo -m 'Remaining parts'\n>>>> ----------------------------------------------------------------\n>>>>\n>>>>\n>>> behind-the-scenes, git stash saves your working tree as a commit and your\n>>> index as another commit.  \"git-stash apply\" and \"git-stash pop\" only\n>>> apply\n>>> your stashed-index if you do \"git-stash-apply --index\".  The default is\n>>> to\n>>> only apply your stashed-work-tree.  You can create new branches from your\n>>> stashes with \"git-stash branch\".  You may find that much better to deal\n>>> with\n>>> for managing your work.  Stashes aren't really intended to be the primary\n>>> way to manage your work, but instead are a supplement.  Branches are a\n>>> better main tool for managing work.  You can create a branch from your\n>>> stash\n>>> and when the branch is ready you can merge it into your other branch.\n>>\n>> Thanks for explanation, I understand there is not much pressure on\n>> improving it.\n>>\n>> But it still does not explain how leaving code in index (with\n>> --keep-index) while\n>> still stashing it might be helpful?\n>>\n>> I would understand the use of --index-only (I gave an example of use\n>> case),\n>> or even --workdir-only, but not --keep-index. If I'm missing something\n>> please\n>> correct me.\n>>\n>>\n> Keep in mind that a key to his workflow is \"git-add --patch\" method (which\n> you did not include in your example).\n\nI did - in my first mail.\n\n\n> The workflow of the manpage assumes\n> you will have to resolve conflicts in such a case.  If you look at the\n> \"Pulling into a dirty tree\" workflow of the same manpage its obvious that\n> this workflow will almost always get conflicts, but they don't explicitly\n> include conflict resolution in the example.\n\nok, for this workflow, when you stash away your changes to do a pull,\nyou can't do anything to avoid conflicts.\n\nI mean this case:\n\n> You could resolve the conflicts\n> for \"Testing partial commits\" in this way:\n>\n> Neal's Version of Testing partial commits::\n> ----------------------------------------------------------------\n> # ... hack hack hack ...\n> $ git add --patch foo            # add just first part to the index\n> $ git stash save --keep-index    # save all other changes to the stash\n> $ edit/build/test first part\n> $ git commit -m 'First part'     # commit fully tested change\n> $ git stash pop                  # prepare to work on all other changes\n>   (conflict resolution)\n>   $ edit conflicted file        # keep new version of the hunk already\n>                                 # committed in prior iteration\n>   $ git reset HEAD -- foo       # clear conflict from index\n>   $ git reset HEAD -- foo       # (again) reset index to match HEAD\n> # ... repeat above five (or eight) steps until one commit remains ...\n> $ edit/build/test remaining parts\n> $ git commit foo -m 'Remaining parts'\n> ----------------------------------------------------------------\n>\n> Maybe there's a better way to do this.  Hope this helps.\n\nHow about following workflow?\n\n   # ... hack hack hack ...\n   $ git add --patch foo\n   $ git stash save --keep-index\n   $ build/test first part         # note I have removed the \"edit\" part\n\nThere are two possibilities now:\n\n1. You're happy with the result - you commit your changes:\n\n   $ git commit -m 'First part'\n   $ git stash pop\n\nImportant: there will be no conflicts in this case, and committed\nchanges won't be reverted/applied/conflicted, because you have\nnot edited them!\n\nI wasn't fully aware of this before (looks like I'm still new to git).\n\n\n2. You're not happy with the result - maybe something does not\nbuild and you need to stage more changes, or maybe fix is not\nworking yet.\n\nYou should first pop your stashed changes! This way you'll avoid\nconflicts, you'll be able to stage/modify other changes. So the\nnext steps are like this:\n\n   $ git stash pop\n   $ edit/add -p\n   $ git stash save --keep-index\n\nand now you're back to the \"build/test\" part.\n\n\n>   (conflict resolution)\n>   $ edit conflicted file        # keep new version of the hunk already\n>                                 # committed in prior iteration\n>   $ git reset HEAD -- foo       # clear conflict from index\n>   $ git reset HEAD -- foo       # (again) reset index to match HEAD\n\nI'm not really sure why/how this works :/\n\n-- \nPiotr Krukowiecki\n"},{"id":"163520","messageId":"7vsjum66co.fsf@alter.siamese.dyndns.org","threadId":"26715","inReplyTo":"AANLkTing5ZQKF4PXtX1peynx2uuc8s+aeBP=fbJWXvWw@mail.gmail.com","subject":"Re: git stash: add --index-only, or --keep-index should not stash index?","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-03-16T22:36:07Z","receivedAt":"2011-03-16T22:36:07Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Piotr Krukowiecki <piotr.krukowiecki@gmail.com> writes:\n\n> How about following workflow?\n>\n>    # ... hack hack hack ...\n>    $ git add --patch foo\n>    $ git stash save --keep-index\n>    $ build/test first part         # note I have removed the \"edit\" part\n>\n> There are two possibilities now:\n>\n> 1. You're happy with the result - you commit your changes:\n>\n>    $ git commit -m 'First part'\n>    $ git stash pop\n>\n> Important: there will be no conflicts in this case, and committed\n> changes won't be reverted/applied/conflicted, because you have\n> not edited them!\n\nExactly; I won't take _any_ credit for --keep-index (I wasn't involved\ndeeply in \"git stash\"), but the above matches my understanding of its\nprimary intended use case.  For this to work well, the stash should record\nthe index that is going to be committed and the work tree you had before\nstashing.\n\n> 2. You're not happy with the result - maybe something does not\n> build and you need to stage more changes, or maybe fix is not\n> working yet.\n>\n> You should first pop your stashed changes! This way you'll avoid\n> conflicts, you'll be able to stage/modify other changes. So the\n> next steps are like this:\n>\n>    $ git stash pop\n>    $ edit/add -p\n>    $ git stash save --keep-index\n>\n> and now you're back to the \"build/test\" part.\n\nYes.\n"},{"id":"163524","messageId":"4D81427C.1020603@gmail.com","threadId":"26715","inReplyTo":"AANLkTing5ZQKF4PXtX1peynx2uuc8s+aeBP=fbJWXvWw@mail.gmail.com","subject":"Re: git stash: add --index-only, or --keep-index should not stash index?","fromName":"Neal Kreitzinger","fromEmail":"nkreitzinger@gmail.com","sentAt":"2011-03-16T23:06:36Z","receivedAt":"2011-03-16T23:06:36Z","isPatch":false,"sender":{"key":"nkreitzinger@gmail.com","avatar":null},"body":"On 3/16/2011 4:37 PM, Piotr Krukowiecki wrote:\n> On Wed, Mar 16, 2011 at 6:57 PM, Neal Kreitzinger\n> <nkreitzinger@gmail.com>  wrote:\n>> On 3/15/2011 2:48 PM, Piotr Krukowiecki wrote:\n>>>\n>>> On Mon, Mar 14, 2011 at 11:21 PM, Neal Kreitzinger\n>>> <nkreitzinger@gmail.com>    wrote:\n>>>>\n>>>> On 3/11/2011 12:47 PM, Piotr Krukowiecki wrote:\n>>>>>\n>>>>> Hi,\n>>>>>\n>>>>> I wanted to do something like \"Testing partial commits\" described in\n>>>>> git-stash documentation (see end of mail for reference). I think this\n>>>>> is a common scenario: you start working on some feature, then discover\n>>>>> a bug, start fixing it, but realize it needs more work. So now you have\n>>>>> two features that needs more work (both are not ready for committing).\n>>>>>\n>>>>> The documentation says to use --keep-index in this case.\n>>>>>\n>>>>> The problem is that --keep-index leaves changes in index intact, but at\n>>>>> the same time it saves them in stash. So if I edit those changes I'm\n>>>>> likely\n>>>>> to get conflicts when applying the stash.\n>>>>>\n>>>>> For example:\n>>>>>\n>>>>> $ git init&&      echo a>      a&&      git add .&&      git commit -m a\n>>>>> $ echo x>      a&&      git add a&&      git stash save --keep-index\n>>>>> $ echo y>      a&&      git add a&&      git commit -m y\n>>>>> $ git stash pop\n>>>>> Auto-merging a\n>>>>> CONFLICT (content): Merge conflict in a\n>>>>>\n>>>>> Maybe --keep-index should not stash staged changes? This would fix this\n>>>>> problem. And I can't  think of a situation when would want to stash\n>>>>> changes\n>>>>> and at the same time keep them.\n>>>>>\n>>>>> If --keep-index works correctly maybe a new option, for example\n>>>>> --index-only\n>>>>> (or --cached-only?) could be introduced?\n>>>>>\n>>>>>\n>>>>> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n>>>>>\n>>>>> Testing partial commits::\n>>>>>\n>>>>> You can use `git stash save --keep-index` when you want to make two or\n>>>>> more commits out of the changes in the work tree, and you want to test\n>>>>> each change before committing:\n>>>>> +\n>>>>> ----------------------------------------------------------------\n>>>>> # ... hack hack hack ...\n>>>>> $ git add --patch foo            # add just first part to the index\n>>>>> $ git stash save --keep-index    # save all other changes to the stash\n>>>>> $ edit/build/test first part\n>>>>> $ git commit -m 'First part'     # commit fully tested change\n>>>>> $ git stash pop                  # prepare to work on all other changes\n>>>>> # ... repeat above five steps until one commit remains ...\n>>>>> $ edit/build/test remaining parts\n>>>>> $ git commit foo -m 'Remaining parts'\n>>>>> ----------------------------------------------------------------\n>>>>>\n>>>>>\n>>>> behind-the-scenes, git stash saves your working tree as a commit and your\n>>>> index as another commit.  \"git-stash apply\" and \"git-stash pop\" only\n>>>> apply\n>>>> your stashed-index if you do \"git-stash-apply --index\".  The default is\n>>>> to\n>>>> only apply your stashed-work-tree.  You can create new branches from your\n>>>> stashes with \"git-stash branch\".  You may find that much better to deal\n>>>> with\n>>>> for managing your work.  Stashes aren't really intended to be the primary\n>>>> way to manage your work, but instead are a supplement.  Branches are a\n>>>> better main tool for managing work.  You can create a branch from your\n>>>> stash\n>>>> and when the branch is ready you can merge it into your other branch.\n>>>\n>>> Thanks for explanation, I understand there is not much pressure on\n>>> improving it.\n>>>\n>>> But it still does not explain how leaving code in index (with\n>>> --keep-index) while\n>>> still stashing it might be helpful?\n>>>\n>>> I would understand the use of --index-only (I gave an example of use\n>>> case),\n>>> or even --workdir-only, but not --keep-index. If I'm missing something\n>>> please\n>>> correct me.\n>>>\n>>>\n>> Keep in mind that a key to his workflow is \"git-add --patch\" method (which\n>> you did not include in your example).\n>\n> I did - in my first mail.\n>\n>\n>> The workflow of the manpage assumes\n>> you will have to resolve conflicts in such a case.  If you look at the\n>> \"Pulling into a dirty tree\" workflow of the same manpage its obvious that\n>> this workflow will almost always get conflicts, but they don't explicitly\n>> include conflict resolution in the example.\n>\n> ok, for this workflow, when you stash away your changes to do a pull,\n> you can't do anything to avoid conflicts.\n>\n> I mean this case:\n>\n>> You could resolve the conflicts\n>> for \"Testing partial commits\" in this way:\n>>\n>> Neal's Version of Testing partial commits::\n>> ----------------------------------------------------------------\n>> # ... hack hack hack ...\n>> $ git add --patch foo            # add just first part to the index\n>> $ git stash save --keep-index    # save all other changes to the stash\n>> $ edit/build/test first part\n>> $ git commit -m 'First part'     # commit fully tested change\n>> $ git stash pop                  # prepare to work on all other changes\n>>    (conflict resolution)\n>>    $ edit conflicted file        # keep new version of the hunk already\n>>                                  # committed in prior iteration\n>>    $ git reset HEAD -- foo       # clear conflict from index\n>>    $ git reset HEAD -- foo       # (again) reset index to match HEAD\n>> # ... repeat above five (or eight) steps until one commit remains ...\n>> $ edit/build/test remaining parts\n>> $ git commit foo -m 'Remaining parts'\n>> ----------------------------------------------------------------\n>>\n>> Maybe there's a better way to do this.  Hope this helps.\n>\n> How about following workflow?\n>\n>     # ... hack hack hack ...\n>     $ git add --patch foo\n>     $ git stash save --keep-index\n>     $ build/test first part         # note I have removed the \"edit\" part\n>\n> There are two possibilities now:\n>\n> 1. You're happy with the result - you commit your changes:\n>\n>     $ git commit -m 'First part'\n>     $ git stash pop\n>\n> Important: there will be no conflicts in this case, and committed\n> changes won't be reverted/applied/conflicted, because you have\n> not edited them!\n>\n> I wasn't fully aware of this before (looks like I'm still new to git).\n>\n>\n> 2. You're not happy with the result - maybe something does not\n> build and you need to stage more changes, or maybe fix is not\n> working yet.\n>\n> You should first pop your stashed changes! This way you'll avoid\n> conflicts, you'll be able to stage/modify other changes. So the\n> next steps are like this:\n>\n>     $ git stash pop\n>     $ edit/add -p\n>     $ git stash save --keep-index\n>\n> and now you're back to the \"build/test\" part.\n>\n>\n>>    (conflict resolution)\n>>    $ edit conflicted file        # keep new version of the hunk already\n>>                                  # committed in prior iteration\n>>    $ git reset HEAD -- foo       # clear conflict from index\n>>    $ git reset HEAD -- foo       # (again) reset index to match HEAD\n>\n> I'm not really sure why/how this works :/\n>\nexample:\n(1) I've added this code:\nif me then\n   echo me\nendif\nif you then\n   echo you\nendif\nif them then\n   echo them\nendif\n\n(2) via git-add --patch I only add the first \"if\" to the index:\nif me then\n   echo me\nendif\n\n(3) git stash --keep-index:\nputs all 3 \"if\" statements in stash, but keeps only the first \"if\" in my \nworking-tree and index.\n\n(4) I test the first \"If\" and decide to modify it:\nif me or mine then\n   echo \"all mine\"\nendif\n\n(5) I add and commit this change.\n\n(6) git stash pop: generates conflict on the first \"if\".\n\n(7) I edit the file and keep the new version of the first \"if\" and \ndelete the old version of the first \"if\":\nif me or mine then\n   echo \"all mine\"\nendif\nif you then\n   echo you\nendif\nif them then\n   echo them\nendif\n\n(8) git status still shows this file as conflicted, because I haven't \n\"added\" it yet.  However, I don't want to add the whole thing, but just \na patch of the second \"if\".  I'm not ready for the 3rd \"if\" yet.  I \ncan't do git-add --patch on a conflicted item.  So I clear the conflict \nwith \"git reset HEAD --foo\".\n\n(9) the first git reset only cleared the conflict -- it did not actually \nreset the foo in index to match the foo in HEAD.  therefore, git status \nstill shows foo as being modified.  therefore, i do another git-reset to \nreset the index foo to match the HEAD foo.\n\n(10) now i can do git-add --patch and add the second \"if\":\nif me or mine then\n   echo \"all mine\"\nendif\nif you then\n   echo you\nendif\n\n(repeat steps 3 thru 10)\n\nIf you are new to git then maybe some clarification about the index will \nbe helpful.  In a nutshell, the index is the staging area in-between \nyour working-tree and the object-store.  Changes in your working-tree \nfirst go to the index and then to the commit (object store).  The index \nholds what is going to be committed.  It also is the go-between in the \nopposite direction.  In order to get an object from the object-store to \nyour work-tree it goes from the object-store to your index and then to \nyour worktree.  when you checkout out a commit from the object-store it \ngoes into your index and then from the index into the working tree.  The \nmain thing to remember is that you have to put stuff in the index before \nyou can commit it.  Another thing to remember is that in order to put \nstuff from the object-store into your working-tree, git first has to put \nin in the index.  the index is the middle-man between the work-tree and \nobject-store, AND between the object-store and the work-tree.\n\nv/r,\nneal\n"}]}