{"thread":{"id":"33724","subject":"Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","startedAt":"2013-05-04T07:34:55Z","lastAt":"2013-05-07T20:39:19Z","messageCount":10,"participants":["Dimitar Bonev","Thomas Rast","Jonathan Nieder","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"216404","messageId":"CADeMBooSZA4D7YctRpRf+axjcUhkMBaJhkd89nssxZYFKph5sA@mail.gmail.com","threadId":"33724","inReplyTo":null,"subject":"Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Dimitar Bonev","fromEmail":"dsbonev@gmail.com","sentAt":"2013-05-04T07:34:55Z","receivedAt":"2013-05-04T07:34:55Z","isPatch":false,"sender":{"key":"dsbonev@gmail.com","avatar":"https://gravatar.com/avatar/16a8ff5cfed1ff3c7566550817f3e2caad02b539c0ed9b2e019cf0588f739c5a?d=mp&s=160"},"body":"Hi,\n\nI have been looking for such a command/option and no one gave me\nsufficient answer. So this message should be considered as a feature\nrequest. I had a situation where I had staged a file with a problem\nsolution in it, then I wanted to experiment with a different solution\nso I had to revert the file to its HEAD state and I couldn't find a\nway that preserves the staged state of that file. More discussions:\n\nhttps://groups.google.com/forum/?fromgroups=#!topic/git-users/nYiN-rE_3i0\n\nhttp://stackoverflow.com/questions/16335799/git-porcelain-command-to-revert-a-single-file-to-its-head-state-but-keep-its-sta\n\nRegards,\nDimitar Bonev\n"},{"id":"216410","messageId":"87obcryvcw.fsf@hexa.v.cablecom.net","threadId":"33724","inReplyTo":"CADeMBooSZA4D7YctRpRf+axjcUhkMBaJhkd89nssxZYFKph5sA@mail.gmail.com","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-05-04T08:58:39Z","receivedAt":"2013-05-04T08:58:39Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Dimitar Bonev <dsbonev@gmail.com> writes:\n\n> I have been looking for such a command/option and no one gave me\n> sufficient answer. So this message should be considered as a feature\n> request. I had a situation where I had staged a file with a problem\n> solution in it, then I wanted to experiment with a different solution\n> so I had to revert the file to its HEAD state and I couldn't find a\n> way that preserves the staged state of that file. More discussions:\n>\n> https://groups.google.com/forum/?fromgroups=#!topic/git-users/nYiN-rE_3i0\n>\n> http://stackoverflow.com/questions/16335799/git-porcelain-command-to-revert-a-single-file-to-its-head-state-but-keep-its-sta\n\nIs that a common enough issue to warrant a better solution than\n\n  git show HEAD:targetfile > targetfile\n\nwhich is how we would do it?\n\nOr more likely,\n\n  git commit -m WIP\n  git revert -n HEAD\n\nwhich is safer anyway, since it doesn't lose the formerly-staged state\nso easily (you have the reflog in case of any mistakes).\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"216411","messageId":"CADeMBopNestsZT4maGr3+tdOBf_Q0ukUbRCbXyucOiZZeHx6nQ@mail.gmail.com","threadId":"33724","inReplyTo":"87obcryvcw.fsf@hexa.v.cablecom.net","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Dimitar Bonev","fromEmail":"dsbonev@gmail.com","sentAt":"2013-05-04T11:13:25Z","receivedAt":"2013-05-04T11:13:25Z","isPatch":false,"sender":{"key":"dsbonev@gmail.com","avatar":"https://gravatar.com/avatar/16a8ff5cfed1ff3c7566550817f3e2caad02b539c0ed9b2e019cf0588f739c5a?d=mp&s=160"},"body":"I think if there was such a command, it could well be common, at least\nfor me. I am somewhat surprised that  from the three combinations of\nresetting index and working dir's states of a file this is the one\nthat is missing (it is missing at commit level also for what is\nworth). Summary table of resetting commands is present at the end of\nthis article: http://www.progit.org/blog/2011/07/11/reset.html\n\nHere is how I see the workflow for a file: you start with a state that\nmatches the HEAD state, you modify the file until reaching the point\nof a sufficient solution, you mark it as finished work by staging it\nfor the next commit, now that you have a solution you can start over\nfrom the HEAD state of the file and try to improve it by choosing a\ndifferent path of implementation.\n\nMy initial thought was to checkout the file, but surprisingly this\nreset the staged state also in addition the working dir's state.\nGenerally git-checkout modifies the working tree, but indeed if you\nuse its form for a single file and specify a treeish argument it will\n\"update the index for the given paths before updating the working\ntree\". I am curious which are the valid use cases for this behavior of\ngit-checkout and if it was the right thing to do to implement it this\nway. In its current form git-checkout does more work than expected by\nme:\n\ngit checkout HEAD -- targetfile\n\nThe above command should have been implemented to reset the working\ndir' state of the file only and if one wants to reset its staged state\nhe could use 'git reset HEAD targetfile'. This gives you more\nflexibility (reset one state, the other state or both states),\ngit-checkout has more consistent behavior (git-checkout a file and\ngit-checkout a branch keeps your staged changes), and makes harder to\nlose your staged changes (there is a reason for a change to be staged\nso it should not be so easy to lose it). As the current behavior is\nreleased I guess it couldn't not be (or it should not be at all)\naccommodated to the one described above, so at least another\ncommand/option should be added to implement it.\n\n@ThomasRast: 'git show HEAD:targetfile > targetfile' was proposed in\nthe both links that I provided in the email that your replied to, but\nthis introduces external dependency to the command interpreter to\noutput the file unmodified but not every interpreter does this.\nPowerShell in particular modifies the encoding of the file, so I get\nstrange behavior: 'git diff' states that html files are binary ones\nand it does not show me the differences; 'git apply' prints 'fatal:\nunrecognized input'. I tried your second suggestion 'git commit'\nfollowed by 'git revert', but this reverses the states of all\ncommitted files. I prefer something that applies to a single file,\nlike git-checkout and git-reset do. Here is a set of commands more\nclose to what I wish:\n\ngit commit -m 'a provisional stable solution'\ngit checkout HEAD~1 -- targetfile\ngit commit  --amend -am 'add solution to problem x'\n\nThis requires more commands, makes assumptions about making a commit\nto a branch, deviates from the rest of git commands about resetting a\nfile's state (inconsistent git API).\n\nOn Sat, May 4, 2013 at 11:58 AM, Thomas Rast <trast@inf.ethz.ch> wrote:\n> Dimitar Bonev <dsbonev@gmail.com> writes:\n>\n>> I have been looking for such a command/option and no one gave me\n>> sufficient answer. So this message should be considered as a feature\n>> request. I had a situation where I had staged a file with a problem\n>> solution in it, then I wanted to experiment with a different solution\n>> so I had to revert the file to its HEAD state and I couldn't find a\n>> way that preserves the staged state of that file. More discussions:\n>>\n>> https://groups.google.com/forum/?fromgroups=#!topic/git-users/nYiN-rE_3i0\n>>\n>> http://stackoverflow.com/questions/16335799/git-porcelain-command-to-revert-a-single-file-to-its-head-state-but-keep-its-sta\n>\n> Is that a common enough issue to warrant a better solution than\n>\n>   git show HEAD:targetfile > targetfile\n>\n> which is how we would do it?\n>\n> Or more likely,\n>\n>   git commit -m WIP\n>   git revert -n HEAD\n>\n> which is safer anyway, since it doesn't lose the formerly-staged state\n> so easily (you have the reflog in case of any mistakes).\n>\n> --\n> Thomas Rast\n> trast@{inf,student}.ethz.ch\n"},{"id":"216417","messageId":"20130504184857.GC25863@elie.Belkin","threadId":"33724","inReplyTo":"CADeMBopNestsZT4maGr3+tdOBf_Q0ukUbRCbXyucOiZZeHx6nQ@mail.gmail.com","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2013-05-04T18:48:57Z","receivedAt":"2013-05-04T18:48:57Z","isPatch":false,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Dimitar Bonev wrote:\n\n> @ThomasRast: 'git show HEAD:targetfile > targetfile' was proposed in\n> the both links that I provided in the email that your replied to, but\n> this introduces external dependency to the command interpreter to\n> output the file unmodified but not every interpreter does this.\n> PowerShell in particular modifies the encoding of the file\n\nThat would suggest that \"git show\" (along with similar commands like\n\"git diff\") should learn an --output= option to avoid its output being\ncorrupted.  It doesn't leave me very happy.\n\nIs there no way to convince PowerShell to treat the output of a\ncommand as binary data with no particular encoding?\n"},{"id":"216421","messageId":"7va9oawmbp.fsf@alter.siamese.dyndns.org","threadId":"33724","inReplyTo":"87obcryvcw.fsf@hexa.v.cablecom.net","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-04T19:56:42Z","receivedAt":"2013-05-04T19:56:42Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Thomas Rast <trast@inf.ethz.ch> writes:\n\n>> I have been looking for such a command/option and no one gave me\n>> sufficient answer. So this message should be considered as a feature\n>> request. I had a situation where I had staged a file with a problem\n>> solution in it, then I wanted to experiment with a different solution\n>> so I had to revert the file to its HEAD state and I couldn't find a\n>> way that preserves the staged state of that file.\n> ...\n\n\"I have something worth saving, better than HEAD in some way\n(e.g. contains fixes), in my index. I want to keep it while I\nexperiment an approach that is unrelated to it, so I want a clean\nslate in the working tree from HEAD without disturbing the index\".\n\nAt the first glance, that looks like a reasonable thing to ask, but\nafter thinking about it a bit more, I am not sure if it really is,\nprimarily because it is unclear what you can productively do to the\nend result next.\n\nSuppose you matched the working tree to HEAD while keeping a\nvaluable change in the index, and after working for a while, now\nhave finished the experiment and have something in your working\ntree.\n\nWhat is your next move?\n\nIf the end result in the working tree were \"Nah, this other approach\ndoes not work, trash it\", you can checkout the working tree from the\nindex, so nothing is lost.\n\nBut if your result is _also_ something worth saving, what would you\ndo?  \"git add\" to update the index will trash the work that was in\nthe index, and that is by definition unrelated to what you worked on\nin the working tree (you wanted to start from the version in the\nHEAD, not from the version in the index, so the end result is likely\nto lack the work you saved in the index).\n\nThat makes me think that \"match working tree from HEAD bypassing\nindex\" is not a very useful strategy, unless you are expecting a\nfailed experiment from the start.\n\nAs Thomas said, I think a more reasonable workflow would begin by\nsaving the \"somewhat worth saving\" state you have in your index as a\nWIP commit, i.e.\n\n\tgit commit -m wip\n\nWhen I experiment starting from a clean slate (after saving away\nsuch a WIP commit), I would then do this:\n\n        git checkout HEAD^\n\nto start at the state before the WIP commit and hack away.  As I do\nnot know how the experiment would go when I do this, I often do not\nbother giving the experiment its own branch.\n\nIf the experiment does not seem to go in a productive direction, I\ncan simply \"git reset --hard && git checkout -\" to get rid of it.\n\nOn the other hand, if its direction shows promise but turns out to\nbe more involved than a quick hack, I can at that point decide to\ngive it its own branch with \"git checkout -b newbranch\".  Then I can\nchoose to keep working on it, or switch to other tasks after making\na wip commit on that new branch.\n\nOr if the experiment results in a series of good and straightforward\nchanges that should come _before_ that original wip (which happens\nvery often), then I could do:\n\n\tgit commit ;# maybe more commits.\n        git cherry-pick @{-1} ;# the one stashed away\n        git co -B @{-1}\n\nto update the original branch and come back to it.  The state in the\noriginal index may be a WIP, so I may then reset with\n\n\tgit reset HEAD^\n\nafter the above.\n\n> Is that a common enough issue to warrant a better solution than\n>\n>   git show HEAD:targetfile > targetfile\n>\n> which is how we would do it?\n\nOr \"git diff HEAD <paths> | git apply -R\", which is a good trick to\nlearn.  You can inspect \"git diff HEAD <paths>\" to check what you\nwill lose and then add \"| git apply -R\" to actually revert it.\n"},{"id":"216422","messageId":"7v61yywm49.fsf@alter.siamese.dyndns.org","threadId":"33724","inReplyTo":"7va9oawmbp.fsf@alter.siamese.dyndns.org","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-04T20:01:10Z","receivedAt":"2013-05-04T20:01:10Z","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> \"I have something worth saving, better than HEAD in some way\n> (e.g. contains fixes), in my index. I want to keep it while I\n> experiment an approach that is unrelated to it, so I want a clean\n> slate in the working tree from HEAD without disturbing the index\".\n>\n> At the first glance, that looks like a reasonable thing to ask, but\n> after thinking about it a bit more, I am not sure if it really is,\n> primarily because it is unclear what you can productively do to the\n> end result next.\n>\n> Suppose you matched the working tree to HEAD while keeping a\n> valuable change in the index, and after working for a while, now\n> have finished the experiment and have something in your working\n> tree.\n>\n> What is your next move?\n>\n> If the end result in the working tree were \"Nah, this other approach\n> does not work, trash it\", you can checkout the working tree from the\n> index, so nothing is lost.\n>\n> But if your result is _also_ something worth saving, what would you\n> do?  \"git add\" to update the index will trash the work that was in\n> the index, and that is by definition unrelated to what you worked on\n> in the working tree (you wanted to start from the version in the\n> HEAD, not from the version in the index, so the end result is likely\n> to lack the work you saved in the index).\n>\n> That makes me think that \"match working tree from HEAD bypassing\n> index\" is not a very useful strategy, unless you are expecting a\n> failed experiment from the start.\n>\n> As Thomas said, I think a more reasonable workflow would begin by\n> saving the \"somewhat worth saving\" state you have in your index as a\n> WIP commit, i.e.\n>\n> \tgit commit -m wip\n>\n> When I experiment starting from a clean slate (after saving away\n> such a WIP commit), I would then do this:\n>\n>         git checkout HEAD^\n>\n> to start at the state before the WIP commit and hack away.  As I do\n> not know how the experiment would go when I do this, I often do not\n> bother giving the experiment its own branch.\n>\n> If the experiment does not seem to go in a productive direction, I\n> can simply \"git reset --hard && git checkout -\" to get rid of it.\n>\n> On the other hand, if its direction shows promise but turns out to\n> be more involved than a quick hack, I can at that point decide to\n> give it its own branch with \"git checkout -b newbranch\".  Then I can\n> choose to keep working on it, or switch to other tasks after making\n> a wip commit on that new branch.\n>\n> Or if the experiment results in a series of good and straightforward\n> changes that should come _before_ that original wip (which happens\n> very often), then I could do:\n>\n> \tgit commit ;# maybe more commits.\n>       git cherry-pick @{-1} ;# the one stashed away\n>       git co -B @{-1}\n>\n> to update the original branch and come back to it.\n\nAlso, if the alternative experiment was really to replace what you\noriginally did to your index, as a natural extension to the above\nworkflow, you would omit \"cherry-pick\" step in the above.  Your\nperfected alternative solution will become the true history of the\noriginal branch, discarding the tentative solution in the index.\n"},{"id":"216426","messageId":"CADeMBopBvCmb4cz8p8vf-jXaOhfzP3GZKF94Efgsh-NOBs+d3Q@mail.gmail.com","threadId":"33724","inReplyTo":"7v61yywm49.fsf@alter.siamese.dyndns.org","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Dimitar Bonev","fromEmail":"dsbonev@gmail.com","sentAt":"2013-05-04T22:46:28Z","receivedAt":"2013-05-04T22:46:28Z","isPatch":false,"sender":{"key":"dsbonev@gmail.com","avatar":"https://gravatar.com/avatar/16a8ff5cfed1ff3c7566550817f3e2caad02b539c0ed9b2e019cf0588f739c5a?d=mp&s=160"},"body":"On Sat, May 4, 2013 at 9:48 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Is there no way to convince PowerShell to treat the output of a\n> command as binary data with no particular encoding?\n\nThe best I could find out is to pipe the output to set-content:\n\ngit show HEAD:targetfile | set-content targetfile\n\nThe default console output redirection pipes the output to Out-File\nwhich encodes the resulting file by default with little endian unicode\nencoding, but it can be overridden by providing an argument:\n\ngit show HEAD:targetfile | Out-File -encoding utf8 targetfile\n\nAlso if I provide 'default' encoding to Out-File it produces the exact\nsame result as set-content command:\n\ngit show HEAD:targetfile | Out-File -encoding default targetfile\n\nThe API docs state that \"Default\" uses the encoding of the system's\ncurrent ANSI code page. So I guess it is system dependent, it could be\nthe case for set-content also, but at the very least set-content is\nshorter to write.\n\nOn Sat, May 4, 2013 at 11:01 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n>> But if your result is _also_ something worth saving, what would you\n>> do?  \"git add\" to update the index will trash the work that was in\n>> the index, and that is by definition unrelated to what you worked on\n>> in the working tree (you wanted to start from the version in the\n>> HEAD, not from the version in the index, so the end result is likely\n>> to lack the work you saved in the index).\n>>\n>> As Thomas said, I think a more reasonable workflow would begin by\n>> saving the \"somewhat worth saving\" state you have in your index as a\n>> WIP commit, i.e.\n>>\n>>       git commit -m wip\n>>\n>> When I experiment starting from a clean slate (after saving away\n>> such a WIP commit), I would then do this:\n>>\n>>         git checkout HEAD^\n>>\n\nActually this is not the case as I tried to explain with the 'git\ncommit' followed by 'git checkout HEAD~1 -- targetfile' followed by\n'git commit --amend' example. The index and the working dir states are\nvery well related. Lets imagine that I am adding an MVC feature X - it\ncould be implemented with 3 or more files. If I stage the files and\ncame up with an idea that requires a major rewrite of one of these\nfiles - lets say the controller one - then it is more convenient to\ncheckout the file's HEAD state and build on top of it - I had been\ndoing just that right before staging - building the previous\nimplementation so this is so familiar and still recent in time. If the\nnew controller implementation is less acceptable than the old one I\njust commit, otherwise I stage the new implementation and just commit.\nSo simple, so common workflow.\n\nOne more argument against the suggestion of doing a commit ahead of\ntime is that I like to think in separation to reduce complexity - in\nparticular I like to think only for the working dir and index states,\ncommits - I treat them as finished work. If I have to amend a commit,\nit is about fixing a mistake - adding/removing a wrong file, fixing a\ntypo, that sort of things and not for actual work to be done.\n"},{"id":"216479","messageId":"87r4hkigg4.fsf@linux-k42r.v.cablecom.net","threadId":"33724","inReplyTo":"CADeMBopBvCmb4cz8p8vf-jXaOhfzP3GZKF94Efgsh-NOBs+d3Q@mail.gmail.com","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Thomas Rast","fromEmail":"trast@inf.ethz.ch","sentAt":"2013-05-06T09:51:55Z","receivedAt":"2013-05-06T09:51:55Z","isPatch":false,"sender":{"key":"tr@thomasrast.ch","avatar":"https://avatars.githubusercontent.com/u/153510?v=4"},"body":"Dimitar Bonev <dsbonev@gmail.com> writes:\n\n> One more argument against the suggestion of doing a commit ahead of\n> time is that I like to think in separation to reduce complexity - in\n> particular I like to think only for the working dir and index states,\n> commits - I treat them as finished work. If I have to amend a commit,\n> it is about fixing a mistake - adding/removing a wrong file, fixing a\n> typo, that sort of things and not for actual work to be done.\n\nAside from what's been said already, there's a fundamental problem with\nyour approach: it doesn't scale in any direction.  You cannot use it if\nyou want to do the same dance with more than one version \"set aside\",\nbecause the index gives you exactly one more storage area.  And it does\nnot generalize in any useful way, whereas using temporary commits is\nuseful also if you want to briefly leave a branch with unfinished work\nto do something else.  Furthermore, knowing how to work with temporary\ncommits (in the plural), and clean them up using 'rebase -i', *is* a\npart of \"work to be done\" in most git workflows.  Namely, it is used to\nreshape your branch from a \"how did I hack this up\" angle into a \"how do\nI explain this to others\" angle.\n\nSo I hope I'm not misconstruing what Junio and Jonathan said, but I\nthink you can sum up our position as: your proposal is a very specific\nsolution to a very narrow problem -- that is only needed because your\nenvironment (PowerShell) is arguably broken.  All the while, there are\nseveral existing solutions that we consider more natural, and that\ngeneralize to other use-cases.\n\n-- \nThomas Rast\ntrast@{inf,student}.ethz.ch\n"},{"id":"216502","messageId":"7vbo8otb29.fsf@alter.siamese.dyndns.org","threadId":"33724","inReplyTo":"CADeMBopBvCmb4cz8p8vf-jXaOhfzP3GZKF94Efgsh-NOBs+d3Q@mail.gmail.com","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-05-06T14:52:46Z","receivedAt":"2013-05-06T14:52:46Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dimitar Bonev <dsbonev@gmail.com> writes:\n\n[administrivia: please do not drop people out of Cc list]\n\n> Actually this is not the case as I tried to explain with the 'git\n> commit' followed by 'git checkout HEAD~1 -- targetfile' followed by\n> 'git commit --amend' example. The index and the working dir states are\n> very well related.\n\nThat invites another question: if it is very well related, why isn't\nit an option to start from the state you have in the working tree\n(i.e. doing nothing), or in the index (i.e. \"git checkout\ncontroller\")?\n\nBut the answer does not matter that much in the end.\n\n> Lets imagine that I am adding an MVC feature X - it\n> could be implemented with 3 or more files. If I stage the files and\n> came up with an idea that requires a major rewrite of one of these\n> files - lets say the controller one - then it is more convenient to\n> checkout the file's HEAD state and build on top of it - I had been\n> doing just that right before staging\n\nSo you have satisfactory changes for view and model in the index,\nand changes to the controller that maybe is OK but you think it\ncould be improved, and you want to go back to the clean slate to\nrethink the approach only for the controller part?\n\nI think the story is essentially the same.  Let's say you did\n\n    git diff HEAD controller | git apply -R\n    edit controller\n\nto get rid of the changes in the working tree, further worked on the\ncontroller part, and came up with a different implementation.  Then\nyou would presumably do\n\n    git add controller\n\nbut at that point you would lose the \"maybe OK\" version you had in\nthe index.  What if you think the version in the working tree might\nend up being better than \"maybe OK\" but can still be improved\nfurther?  You never \"git add\" until the working tree version gets\ninto truly a better shape?\n\nWhat happens fairly often is that you end up having more than _one_\nversions that are both better than the version from the HEAD but\ncannot immediately say one is clearly better than the others in all\ncounts, and at some point, you would need more than one intermediate\nstates (while the index can have only one), to keep these competing\nversions. The next thing you would want to do is to take a deep\nbreath and pick better parts from these good versions to come up\nwith the single final version. Keeping one good version in the index\ndoes not let you do so.\n\n> ... commits - I treat them as finished work.\n\nI think people should learn to take the biggest advantage of using a\ndistributed source control system, which is that commits do not have\nto be \"finished work\", until you choose to declare they are done and\npush them out for others to see.\n\nFear of commitment is a disease we do not have to suffer once we\ngraduated centralized systems ;-).\n"},{"id":"216641","messageId":"CADeMBopOQP099WwoQwq8bbNbaE55foUzRri4CcHPnJa2L-baFQ@mail.gmail.com","threadId":"33724","inReplyTo":"7vbo8otb29.fsf@alter.siamese.dyndns.org","subject":"Re: Add porcelain command to revert a single staged file to its HEAD state while preserving its staged state","fromName":"Dimitar Bonev","fromEmail":"dsbonev@gmail.com","sentAt":"2013-05-07T20:39:19Z","receivedAt":"2013-05-07T20:39:19Z","isPatch":false,"sender":{"key":"dsbonev@gmail.com","avatar":"https://gravatar.com/avatar/16a8ff5cfed1ff3c7566550817f3e2caad02b539c0ed9b2e019cf0588f739c5a?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n> Dimitar Bonev <dsbonev@gmail.com> writes:\n>\n> [administrivia: please do not drop people out of Cc list]\n>\n> That invites another question: if it is very well related, why isn't\n> it an option to start from the state you have in the working tree\n> (i.e. doing nothing), or in the index (i.e. \"git checkout\n> controller\")?\n>\n> But the answer does not matter that much in the end.\n>\n\nIt isn't an option to start from the staged state, because the staged\nimplementation modified code that is present in the HEAD state. So the\nnew implementation that I have in my mind requires to add its own kind\nof modifications which are incompatible with the staged\nimplementation. It is much easier to start from HEAD state when both\nimplementations require modifying 10% HEAD code and adding 90% new\ncode. If I start from staged state I have to drop 90% new code and to\nfigure out if the 10% modified state can work without the 90% dropped\ncode. At the same time I know HEAD state is stable working code. There\nis no doubt that I have to start from HEAD state of the controller\nfile for the described MVC example\n\n>\n> I think the story is essentially the same.  Let's say you did\n>\n>     git diff HEAD controller | git apply -R\n>     edit controller\n>\n> to get rid of the changes in the working tree, further worked on the\n> controller part, and came up with a different implementation.  Then\n> you would presumably do\n>\n>     git add controller\n>\n> but at that point you would lose the \"maybe OK\" version you had in\n> the index.  What if you think the version in the working tree might\n> end up being better than \"maybe OK\" but can still be improved\n> further?  You never \"git add\" until the working tree version gets\n> into truly a better shape?\n>\n\nYes, I 'git add' only what is to become part of the next commit so at\nleast it has to be stable code (that passes some smoke tests or\nsomething similar).\n\n> What happens fairly often is that you end up having more than _one_\n> versions that are both better than the version from the HEAD but\n> cannot immediately say one is clearly better than the others in all\n> counts, and at some point, you would need more than one intermediate\n> states (while the index can have only one), to keep these competing\n> versions. The next thing you would want to do is to take a deep\n> breath and pick better parts from these good versions to come up\n> with the single final version. Keeping one good version in the index\n> does not let you do so.\n>\n\nMy case was not like that but if it was I would have made a commit to\npreserve the old implementation while working on the new one.\n\n>\n> I think people should learn to take the biggest advantage of using a\n> distributed source control system, which is that commits do not have\n> to be \"finished work\", until you choose to declare they are done and\n> push them out for others to see.\n>\n> Fear of commitment is a disease we do not have to suffer once we\n> graduated centralized systems ;-).\n\nI used the wrong words - I meant 'stable state' instead of 'finished\nwork'. If every commit was finished work then all my branches would\nhave contain one specific commit. My branches are built from more than\none commit and every commit adds a subfeature and the commit should be\nstable in sense that it should run without throwing exceptions - like\ntrying to load some file that would be created in a future commit. One\nshould be able to checkout a random commit and be able to run,\ninspect, write tests against, add new subfeature on top of that\ncommit.\n"}]}