{"thread":{"id":"39511","subject":"Suggestion: make git checkout safer","startedAt":"2015-06-03T08:50:44Z","lastAt":"2015-06-05T18:46:41Z","messageCount":28,"participants":["Ed Avis","Jeff King","Junio C Hamano","Randall S. Becker","Stefan Beller","Torsten Bögershausen","Kevin Daudt","Philip Oakley","John Szakmeister","Duy Nguyen","Eric Sunshine"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"262850","messageId":"loom.20150603T104534-909@post.gmane.org","threadId":"39511","inReplyTo":null,"subject":"Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-03T08:50:44Z","receivedAt":"2015-06-03T08:50:44Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"Currently a plain 'git checkout .' will revert any local changes, e.g.\n\n    % mkdir test\n    % cd test\n    % git init\n    Initialized empty Git repository in /home/eda/test/.git/\n    % echo hello >foo\n    % git add foo\n    % git commit -m.\n    [master (root-commit) 34f6694] .\n     1 file changed, 1 insertion(+)\n     create mode 100644 foo\n    % echo goodbye >foo\n    % git checkout .\n    % cat foo\n    hello\n\nI suggest this is dangerous and by default 'git checkout' should only alter\nfiles which do not have local changes (as would be reported by 'git diff').\nOnly if --force is given should working tree differences be thrown away.\n\n    % git --version\n    git version 2.4.0\n\n-- \nEd Avis <eda@waniasset.com>\n"},{"id":"262851","messageId":"20150603090654.GD32000@peff.net","threadId":"39511","inReplyTo":"loom.20150603T104534-909@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-06-03T09:06:55Z","receivedAt":"2015-06-03T09:06:55Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 03, 2015 at 08:50:44AM +0000, Ed Avis wrote:\n\n> Currently a plain 'git checkout .' will revert any local changes, e.g.\n> \n>     % mkdir test\n>     % cd test\n>     % git init\n>     Initialized empty Git repository in /home/eda/test/.git/\n>     % echo hello >foo\n>     % git add foo\n>     % git commit -m.\n>     [master (root-commit) 34f6694] .\n>      1 file changed, 1 insertion(+)\n>      create mode 100644 foo\n>     % echo goodbye >foo\n>     % git checkout .\n>     % cat foo\n>     hello\n> \n> I suggest this is dangerous and by default 'git checkout' should only alter\n> files which do not have local changes (as would be reported by 'git diff').\n> Only if --force is given should working tree differences be thrown away.\n> \n>     % git --version\n>     git version 2.4.0\n\nThat's what \"git checkout <path>\" is designed for. I'm not clear on what\nyou expect \"git checkout .\" to do in this example, if not overwrite\n\"foo\". Can you elaborate?\n\n-Peff\n"},{"id":"262854","messageId":"loom.20150603T110826-777@post.gmane.org","threadId":"39511","inReplyTo":"20150603090654.GD32000@peff.net","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-03T09:21:59Z","receivedAt":"2015-06-03T09:21:59Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"I had expected that 'git checkout .' would fix up my working tree to make it\nmatch the repository (in this case, the current revision of the master\nbranch).  When I originally ran it I had deleted a couple of files from the\nworking tree and wanted to restore them.  However, I expected that if doing\nthe checkout operation would lose data currently on disk then git would\nprompt me first.\n\nTo compare, 'git pull' will not silently overwrite local changes; it will\nprompt you to commit or stash them first.  'git checkout .' is a fairly\ninnocuous-looking command; it doesn't contain any --force or --overwrite or\nother things that would make you think twice before typing it.  So I suggest\nit should be equally safe to run.\n\nThe user interface might be something like:\n\n% git checkout .\nerror: Your local changes to the following files would be overwritten:\n        foo\nYou may want to commit or stash these changes, or delete the files if you\ndon't want them.  Use 'git checkout --force' to proceed, throwing away\nlocal changes.\nAborting\n\nIf the checkout operation would only involve creating some files on disk\nwhich aren't currently there, then it would proceed without prompting.\n\n-- \nEd Avis <eda@waniasset.com>\n"},{"id":"262855","messageId":"20150603093514.GF32000@peff.net","threadId":"39511","inReplyTo":"loom.20150603T110826-777@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-06-03T09:35:15Z","receivedAt":"2015-06-03T09:35:15Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 03, 2015 at 09:21:59AM +0000, Ed Avis wrote:\n\n> I had expected that 'git checkout .' would fix up my working tree to make it\n> match the repository (in this case, the current revision of the master\n> branch).\n\nIt did. :)\n\n> The user interface might be something like:\n> \n> % git checkout .\n> error: Your local changes to the following files would be overwritten:\n>         foo\n> You may want to commit or stash these changes, or delete the files if you\n> don't want them.  Use 'git checkout --force' to proceed, throwing away\n> local changes.\n> Aborting\n> \n> If the checkout operation would only involve creating some files on disk\n> which aren't currently there, then it would proceed without prompting.\n\nThanks for explaining. I see where you are coming from, though I'm still\na bit lukewarm on the idea, if only because the vast majority of\ninvocations would involve \"--force\".\n\nIt also seems a bit special-cased to treat restoring deletions\nspecially.  I would say the more \"usual\" way to use checkout like this\nis to give specific paths. I.e., run \"git status\", say \"oh, I need to\nrestore the contents of 'foo', but not 'bar'\", and run \"git checkout\nfoo\". That works regardless of the type of change to \"foo\" and \"bar\".\n\nIf we want to introduce more safety here, I'd be inclined to perform the\noperation by default, but give a better escape hatch. For example, by\ncreating a loose object for any file we're about to overwrite, and\npossibly writing an entry into a log. That's a lot more work, but has a\nfew advantages:\n\n  1. It helps even when you just ran with \"--force\" followed by an\n     \"oops, why did I do that?\" moment.\n\n  2. It can help other commands like \"git clean\".\n\n  3. That log could form a basis for a \"git undo\" program to help with\n     \"oops\" moments in general (e.g., if you use \"git reset .\" to\n     overwrite what is in the index, we have all of the old file content\n     in objects, but it can sometimes be a pain to figure out _which_\n     objects went where.\n\n-Peff\n"},{"id":"262856","messageId":"loom.20150603T114527-151@post.gmane.org","threadId":"39511","inReplyTo":"20150603093514.GF32000@peff.net","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-03T09:55:05Z","receivedAt":"2015-06-03T09:55:05Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"Jeff King <peff <at> peff.net> writes:\n\n>I would say the more \"usual\" way to use checkout like this\n>is to give specific paths. I.e., run \"git status\", say \"oh, I need to\n>restore the contents of 'foo', but not 'bar'\", and run \"git checkout\n>foo\". That works regardless of the type of change to \"foo\" and \"bar\".\n\nThat seems fine - a specific file is named and you clearly want to alter\nthe contents of that file.  By analogy, 'rm foo' will silently delete it,\nbut if you specify a directory to delete recursively you need the -r flag.\nOK, it's not a perfect analogy because the purpose of rm is to delete data\nand nothing else ;-).\n\nIf my personal experience is anything to go by, newcomers may fall into the\nhabit of running 'git checkout .' to restore missing files.  In the old days\nI would often delete a file and then run 'cvs update' or 'svn update' to\nrestore it.  That would fetch a fresh copy from the repository, and while\nit might do some kind of diff/patch operation on modified files, it would\nnot simply throw away local changes.\n\n'git checkout .' seems like the analogous command, but it has much sharper\nedges.  I still think it should be safer by default, but if you decide\nagainst that then perhaps you need to create some way to restore missing\nfiles and not overwrite others.  'git checkout --no-overwrite'?  Then it\ncould even be added to .gitconfig as the default for those who like it.\n\nI have to say that as a newcomer to git I do not like the idea of creating\na special undo log for git.  It would just be yet another concept to learn\nand another thing to add to the list of 'where is git hiding my data this\ntime?'.  And the time when it would be useful - after some bungled operation\nthat lost data - is just the time when the user is already confused and\nadding another semi-hidden stash of objects to the mix would befuddle them\nfurther.  If there is to be a backup made of local changes that get lost,\nand I agree it is a good idea, then it should be something stupid and\ncompletely obvious, such as saving the old file as 'foo.before_checkout.1'.\n\n-- \nEd Avis <eda@waniasset.com>\n"},{"id":"262885","messageId":"xmqqlhg0y9xj.fsf@gitster.dls.corp.google.com","threadId":"39511","inReplyTo":"20150603093514.GF32000@peff.net","subject":"Re: Suggestion: make git checkout safer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-03T17:32:40Z","receivedAt":"2015-06-03T17:32:40Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> If we want to introduce more safety here, I'd be inclined to perform the\n> operation by default, but give a better escape hatch. For example, by\n> creating a loose object for any file we're about to overwrite, and\n> possibly writing an entry into a log.\n\nCan we borrow the ideas from other tools that have similar\ncharacteristics, I wonder.\n\n\"git checkout $paths\" (and you can give \".\" for $paths to mean\n\"everything\") is akin to \"cp -R $elsewhere/$path .\" to restore the\nworking tree copies from somewhere else.\n\n\"Ouch, 'git checkout .'  overwrote what was in my working tree\" is\nexactly the same kind of confusion as \"I ran 'cp -r ../saved .' and\nit overwrote everything\".  As you said in your initial response,\nthat is what the command is meant for.\n\nWhat does that similar command outside world, \"cp\", have for \"more\nsafety\"?  'cp -i' asks if the user wants to overwrite a file for\neach path; perhaps a behaviour similar to that was the original\nposter wanted to see?\n"},{"id":"262887","messageId":"xmqqh9qoy9sx.fsf@gitster.dls.corp.google.com","threadId":"39511","inReplyTo":"loom.20150603T114527-151@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-03T17:35:26Z","receivedAt":"2015-06-03T17:35:26Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Ed Avis <eda@waniasset.com> writes:\n\n> If my personal experience is anything to go by, newcomers may fall into the\n> habit of running 'git checkout .' to restore missing files.\n\nIs that really true?  It all depends on why you came to a situation\nto have \"missing files\" in the first place, I would think, but \"git\ncheckout $path\" is \"I messed up the version in the working tree at\n$path, and want to restore them\".  One particular kind of \"I messed\nup\" may be \"I deleted by mistake\" (hence making them \"missing\"), but\nis it so common to delete things by mistake, as opposed to editing,\nmaking a mess and realizing that the work so far was not improving\nthings and wanting to restart from scratch?\n"},{"id":"262891","messageId":"004801d09e25$a339b0f0$e9ad12d0$@nexbridge.com","threadId":"39511","inReplyTo":"xmqqh9qoy9sx.fsf@gitster.dls.corp.google.com","subject":"RE: Suggestion: make git checkout safer","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2015-06-03T17:49:27Z","receivedAt":"2015-06-03T17:49:27Z","isPatch":false,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"On June 3, 2015 1:35 PM Junio C Hamano wrote:\n> Ed Avis <eda@waniasset.com> writes:\n> > If my personal experience is anything to go by, newcomers may fall\n> > into the habit of running 'git checkout .' to restore missing files.\n> Is that really true?  It all depends on why you came to a situation to\nhave\n> \"missing files\" in the first place, I would think, but \"git checkout\n$path\" is \"I\n> messed up the version in the working tree at $path, and want to restore\nthem\".\n> One particular kind of \"I messed up\" may be \"I deleted by mistake\" (hence\n> making them \"missing\"), but is it so common to delete things by mistake,\nas\n> opposed to editing, making a mess and realizing that the work so far was\nnot\n> improving things and wanting to restart from scratch?\n\nWhen working in an IDE like ECLIPSE or MonoDevelop, accidentally hitting the\nDEL button or a drag-drop move is a fairly common trigger for the\n\"Wait-No-Stop-Oh-Drats\" process which includes running git checkout to\nrecover. My keyboard is excessively sensitive static, so this happens more\noften than I will admit (shamelessly blaming hardware when it really is a\nuser problem). Git checkout is a life-saver in this case as is frequently\ncommitting. :)\n\nCheers,\nRandall\n\n-- Brief whoami: NonStop&UNIX developer since approximately\nUNIX(421664400)/NonStop(211288444200000000)\n-- In my real life, I talk too much.\n"},{"id":"262897","messageId":"xmqq4mmoy84y.fsf@gitster.dls.corp.google.com","threadId":"39511","inReplyTo":"004801d09e25$a339b0f0$e9ad12d0$@nexbridge.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-03T18:11:25Z","receivedAt":"2015-06-03T18:11:25Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Randall S. Becker\" <rsbecker@nexbridge.com> writes:\n\n> On June 3, 2015 1:35 PM Junio C Hamano wrote:\n>> Is that really true?  It all depends on why you came to a\n>> situation to have \"missing files\" in the first place, I would\n>> think, but \"git checkout $path\" is \"I messed up the version in\n>> the working tree at $path, and want to restore them\".  One\n>> particular kind of \"I messed up\" may be \"I deleted by mistake\"\n>> (hence making them \"missing\"), but is it so common to delete\n>> things by mistake, as opposed to editing, making a mess and\n>> realizing that the work so far was not improving things and\n>> wanting to restart from scratch?\n>\n> When working in an IDE like ECLIPSE or MonoDevelop, accidentally\n> hitting the DEL button or a drag-drop move is a fairly common\n> trigger for the \"Wait-No-Stop-Oh-Drats\" process which includes\n> running git checkout to recover.\n\nThat is an interesting tangent.  If you are lucky then the deleted\nfile may be unedited one, but I presume that you are not always\nlucky.  So perhaps \"git checkout\" is not a solution to that\nparticular IDE issue in the first place?\n"},{"id":"262898","messageId":"CAGZ79kYv5Xgfv=3KD0oPrUsJD2Yw-EHu7U=_35FZTm4Rp5hbBA@mail.gmail.com","threadId":"39511","inReplyTo":"004801d09e25$a339b0f0$e9ad12d0$@nexbridge.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2015-06-03T18:14:20Z","receivedAt":"2015-06-03T18:14:20Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Maybe the expectation comes from the existing warnings when checking\nout branches?\n\n    $ mkdir tmp && cd tmp\n    $ git init\n    $ echo Hello >foo\n    $ git add foo\n    $ git commit -am \"Hello\"\n    $ git branch next\n    $ echo \"world\" >bar\n    $ git add bar\n    $ git commit -a -m \"World\"\n    $ git checkout test\n      # no problem so far, just going back one commit on anther branch\n    $ echo Kitty >bar\n    $ git checkout master # now we get it:\n    error: The following untracked working tree files would be\noverwritten by checkout:\n    bar\n    Please move or remove them before you can switch branches.\n    Aborting\n\nSo in one mode, we do actually warn about contents going missing, and the other\nmode is designed to actually make things go missing without any warning.\n\nSo maybe the checkout command is *too powerful* ? Looking at the man page:\n\n    Updates files in the working tree to match the version in the index or the\n    specified tree. If no paths are given, git checkout will also update HEAD\n    to set the specified branch as the current branch.\n\nwe're mixing two different tasks here anyway. \"Updating files in the work tree\"\ncan be understood as \"throwing away all changes until you're back at a specified\nsafe point\". If I were to come up with a name for such an action it's\nmaybe \"reset\" or\n\"reset-file(s)\". Though git reset is taken already and does different things.\n\"reset\" sounds as if stuff may go missing, so anyone who types\n\"reset\", (even without\nexactly understanding what it does, would assume it is as safe as\ntyping \"rm\" probably.\n\n And \"also update HEAD\" can be understood as \"switch to another branch\",\nso if I were to invent a new porcelain command for such functionality it may be\ncalled \"git switch-branch\". And typing switch-branch would be expected\nto carry all\nthe warnings (no updating files in the work tree, when in danger of\nlosing its content)\n"},{"id":"262900","messageId":"004901d09e29$b38c2ba0$1aa482e0$@nexbridge.com","threadId":"39511","inReplyTo":"xmqq4mmoy84y.fsf@gitster.dls.corp.google.com","subject":"RE: Suggestion: make git checkout safer","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2015-06-03T18:18:32Z","receivedAt":"2015-06-03T18:18:32Z","isPatch":false,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"On June 3, 2015 2:11 PM Junio C Hamano wrote:\n> \"Randall S. Becker\" <rsbecker@nexbridge.com> writes:\n> > On June 3, 2015 1:35 PM Junio C Hamano wrote:\n> >> Is that really true?  It all depends on why you came to a situation\n> >> to have \"missing files\" in the first place, I would think, but \"git\n> >> checkout $path\" is \"I messed up the version in the working tree at\n> >> $path, and want to restore them\".  One particular kind of \"I messed\n> >> up\" may be \"I deleted by mistake\"\n> >> (hence making them \"missing\"), but is it so common to delete things\n> >> by mistake, as opposed to editing, making a mess and realizing that\n> >> the work so far was not improving things and wanting to restart from\n> >> scratch?\n> >\n> > When working in an IDE like ECLIPSE or MonoDevelop, accidentally\n> > hitting the DEL button or a drag-drop move is a fairly common trigger\n> > for the \"Wait-No-Stop-Oh-Drats\" process which includes running git\n> > checkout to recover.\n> \n> That is an interesting tangent.  If you are lucky then the deleted file\nmay be\n> unedited one, but I presume that you are not always lucky.  So perhaps\n\"git\n> checkout\" is not a solution to that particular IDE issue in the first\nplace?\n\nAgreed. That's why I like knowing what's in my sausages and commit often.\nOnly lost a minor change once from this. I wonder what else is afoot. Ed,\ncan you expand on the issue?\n"},{"id":"262905","messageId":"20150603190616.GA28488@peff.net","threadId":"39511","inReplyTo":"xmqqlhg0y9xj.fsf@gitster.dls.corp.google.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2015-06-03T19:06:16Z","receivedAt":"2015-06-03T19:06:16Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Jun 03, 2015 at 10:32:40AM -0700, Junio C Hamano wrote:\n\n> \"git checkout $paths\" (and you can give \".\" for $paths to mean\n> \"everything\") is akin to \"cp -R $elsewhere/$path .\" to restore the\n> working tree copies from somewhere else.\n> \n> \"Ouch, 'git checkout .'  overwrote what was in my working tree\" is\n> exactly the same kind of confusion as \"I ran 'cp -r ../saved .' and\n> it overwrote everything\".  As you said in your initial response,\n> that is what the command is meant for.\n> \n> What does that similar command outside world, \"cp\", have for \"more\n> safety\"?  'cp -i' asks if the user wants to overwrite a file for\n> each path; perhaps a behaviour similar to that was the original\n> poster wanted to see?\n\nYeah, I'd say \"cp -i\" is the closest thing. I don't have a problem with\nadding that, but I'd really hate for it to be the default (just as I\nfind distros which \"alias rm='rm -i\" annoying).\n\n-Peff\n"},{"id":"262908","messageId":"006401d09e32$dfc29890$9f47c9b0$@nexbridge.com","threadId":"39511","inReplyTo":"20150603190616.GA28488@peff.net","subject":"RE: Suggestion: make git checkout safer","fromName":"Randall S. Becker","fromEmail":"rsbecker@nexbridge.com","sentAt":"2015-06-03T19:24:12Z","receivedAt":"2015-06-03T19:24:12Z","isPatch":false,"sender":{"key":"randall.becker@nexbridge.ca","avatar":"https://avatars.githubusercontent.com/u/28956764?v=4"},"body":"On June 3, 2015 3:06 PM Jeff King wrote:\n> On Wed, Jun 03, 2015 at 10:32:40AM -0700, Junio C Hamano wrote:\n> > \"git checkout $paths\" (and you can give \".\" for $paths to mean\n> > \"everything\") is akin to \"cp -R $elsewhere/$path .\" to restore the\n> > working tree copies from somewhere else.\n> >\n> > \"Ouch, 'git checkout .'  overwrote what was in my working tree\" is\n> > exactly the same kind of confusion as \"I ran 'cp -r ../saved .' and it\n> > overwrote everything\".  As you said in your initial response, that is\n> > what the command is meant for.\n> >\n> > What does that similar command outside world, \"cp\", have for \"more\n> > safety\"?  'cp -i' asks if the user wants to overwrite a file for each\n> > path; perhaps a behaviour similar to that was the original poster\n> > wanted to see?\n> \n> Yeah, I'd say \"cp -i\" is the closest thing. I don't have a problem with adding that,\n> but I'd really hate for it to be the default (just as I find distros which \"alias\n> rm='rm -i\" annoying).\n\nBrainstorming a few compromises:\n\nor some such config option to turn on behaviour like this:\ncore.checkout=-i\n\nor some such thing where if there are strictly more than m files being touched and strictly less than n files to act accordingly - a threshold concept:\ncore.checkout_warn_upperlimit=n # default to 0\ncore.checkout_warn_lowerlimit=m # default to 0\n\nor in a more gross fashion provide a pre-checkout hook to do all the work of prompting/control of the situation.\n\nPersonally I'm happy with the defaults as they are (and was not a fan of defaulting rm -i or cp -i either) but I can see the point and have had diffuse whines from my team on the checkout subject, which is why I'm commenting.\n"},{"id":"262909","messageId":"556F54F9.2050202@web.de","threadId":"39511","inReplyTo":"loom.20150603T114527-151@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2015-06-03T19:26:49Z","receivedAt":"2015-06-03T19:26:49Z","isPatch":false,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On 2015-06-03 11.55, Ed Avis wrote:\n> Jeff King <peff <at> peff.net> writes:\n> \n>> I would say the more \"usual\" way to use checkout like this\n>> is to give specific paths. I.e., run \"git status\", say \"oh, I need to\n>> restore the contents of 'foo', but not 'bar'\", and run \"git checkout\n>> foo\". That works regardless of the type of change to \"foo\" and \"bar\".\n> \n> That seems fine - a specific file is named and you clearly want to alter\n> the contents of that file.  By analogy, 'rm foo' will silently delete it,\n> but if you specify a directory to delete recursively you need the -r flag.\n> OK, it's not a perfect analogy because the purpose of rm is to delete data\n> and nothing else ;-).\n> \n> If my personal experience is anything to go by, newcomers may fall into the\n> habit of running 'git checkout .' to restore missing files.  In the old days\n> I would often delete a file and then run 'cvs update' or 'svn update' to\n> restore it.  That would fetch a fresh copy from the repository, and while\n> it might do some kind of diff/patch operation on modified files, it would\n> not simply throw away local changes.\n> \n> 'git checkout .' seems like the analogous command, but it has much sharper\n> edges.  I still think it should be safer by default, but if you decide\n> against that then perhaps you need to create some way to restore missing\n> files and not overwrite others.  'git checkout --no-overwrite'?  Then it\n> could even be added to .gitconfig as the default for those who like it.\n> \n> I have to say that as a newcomer to git I do not like the idea of creating\n> a special undo log for git.  It would just be yet another concept to learn\n> and another thing to add to the list of 'where is git hiding my data this\n> time?'.  And the time when it would be useful - after some bungled operation\n> that lost data - is just the time when the user is already confused and\n> adding another semi-hidden stash of objects to the mix would befuddle them\n> further.  If there is to be a backup made of local changes that get lost,\n> and I agree it is a good idea, then it should be something stupid and\n> completely obvious, such as saving the old file as 'foo.before_checkout.1'.\n> \nThis is what my Git says:\n\ngit status\nOn branch master\nChanges not staged for commit:\n  (use \"git add/rm <file>...\" to update what will be committed)\n  (use \"git checkout -- <file>...\" to discard changes in working directory)\n\n        modified:   A\n        deleted:    B\n\n(So it should be somewhat self-documenting)\n\n\nI try to avoid things like \"git reset --hard\", and \"git checkout .\",\nand often use \"git stash\" instead.\n\nIt may be that there is a chance to improve the documentation.\n\nJust for curiosity:\nFrom where did you got the information to run \"git checkout .\" ?\n"},{"id":"262911","messageId":"20150603194756.GB29730@vps892.directvps.nl","threadId":"39511","inReplyTo":"loom.20150603T114527-151@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Kevin Daudt","fromEmail":"me@ikke.info","sentAt":"2015-06-03T19:47:56Z","receivedAt":"2015-06-03T19:47:56Z","isPatch":false,"sender":{"key":"me@ikke.info","avatar":"https://avatars.githubusercontent.com/u/135698?v=4"},"body":"On Wed, Jun 03, 2015 at 09:55:05AM +0000, Ed Avis wrote:\n> Jeff King <peff <at> peff.net> writes:\n> \n \n> If my personal experience is anything to go by, newcomers may fall into the\n> habit of running 'git checkout .' to restore missing files.  In the old days\n> I would often delete a file and then run 'cvs update' or 'svn update' to\n> restore it.  That would fetch a fresh copy from the repository, and while\n> it might do some kind of diff/patch operation on modified files, it would\n> not simply throw away local changes.\n> \n\nThe problem with these kinds of habbits is that they easily extend to\nthe --force variant. If people execute git checkout . as a habbit\nwithout thinking, they will soon train to do git checkout -f . without\nthinking, and then you still have the same problem.\n\nI do share your sentiment that it's easy to loose uncomitted changes to\ngit checkout <path>, but like Jeff said, the entire goal of this command\nis to reset specific files from the index or commits. \n\nIntroducing a way to undo this would be a much better option to me then\nadding an extra switch with no way to undo.\n"},{"id":"262914","messageId":"D1F2397B48664FB29734EF1FF3DD0E7E@PhilipOakley","threadId":"39511","inReplyTo":"loom.20150603T114527-151@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.org","sentAt":"2015-06-03T20:12:09Z","receivedAt":"2015-06-03T20:12:09Z","isPatch":false,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"From: \"Ed Avis\" <eda@waniasset.com>\nSent: Wednesday, June 03, 2015 10:55 AM\n> Jeff King <peff <at> peff.net> writes:\n>\n>>I would say the more \"usual\" way to use checkout like this\n>>is to give specific paths. I.e., run \"git status\", say \"oh, I need to\n>>restore the contents of 'foo', but not 'bar'\", and run \"git checkout\n>>foo\". That works regardless of the type of change to \"foo\" and \"bar\".\n>\n> That seems fine - a specific file is named and you clearly want to \n> alter\n> the contents of that file.  By analogy, 'rm foo' will silently delete \n> it,\n> but if you specify a directory to delete recursively you need the -r \n> flag.\n> OK, it's not a perfect analogy because the purpose of rm is to delete \n> data\n> and nothing else ;-).\n>\n> If my personal experience is anything to go by, newcomers may fall \n> into the\n> habit of running 'git checkout .' to restore missing files.  In the \n> old days\n> I would often delete a file and then run 'cvs update' or 'svn update' \n> to\n> restore it.  That would fetch a fresh copy from the repository, and \n> while\n> it might do some kind of diff/patch operation on modified files, it \n> would\n> not simply throw away local changes.\n>\n> 'git checkout .' seems like the analogous command, but it has much \n> sharper\n> edges.  I still think it should be safer by default, but if you decide\n> against that then perhaps you need to create some way to restore \n> missing\n> files and not overwrite others.  'git checkout --no-overwrite'?  Then \n> it\n> could even be added to .gitconfig as the default for those who like \n> it.\n>\n> I have to say that as a newcomer to git I do not like the idea of \n> creating\n> a special undo log for git.  It would just be yet another concept to \n> learn\n> and another thing to add to the list of 'where is git hiding my data \n> this\n> time?'.  And the time when it would be useful - after some bungled \n> operation\n> that lost data - is just the time when the user is already confused \n> and\n> adding another semi-hidden stash of objects to the mix would befuddle \n> them\n> further.  If there is to be a backup made of local changes that get \n> lost,\n> and I agree it is a good idea, then it should be something stupid and\n> completely obvious, such as saving the old file as \n> 'foo.before_checkout.1'.\n>\n> -- \n> Ed Avis <eda@waniasset.com>\n>\n\nTo me, when I saw the 'git checkout .', I was reminded of the 'git push \n. <refs>' special case where '.' is the repo, so in my mind the first \nthought was that Ed wanted to checkout the head of the current repo, and \nthat should have barfed from that viewpoint.\n\nThe [is it equivalent? (rhet)] 'git checkout -- .' would clearly \nindicate that the '.' refers to the files of the current directory \n(wouldn't it?)\n\nSo it's about how '.' is perceived by the code in different \ncircumstances, and whether, perhaps, the optional discriminating '--' \nshould be required in this (special) case.\n\nPhilip \n"},{"id":"262921","messageId":"xmqqiob4wkem.fsf@gitster.dls.corp.google.com","threadId":"39511","inReplyTo":"20150603190616.GA28488@peff.net","subject":"Re: Suggestion: make git checkout safer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-03T21:29:21Z","receivedAt":"2015-06-03T21:29:21Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> On Wed, Jun 03, 2015 at 10:32:40AM -0700, Junio C Hamano wrote:\n>\n> Yeah, I'd say \"cp -i\" is the closest thing. I don't have a problem with\n> adding that, but I'd really hate for it to be the default (just as I\n> find distros which \"alias rm='rm -i\" annoying).\n\nOh, no question about it.\n\nI think a typical user cease to be a newbie before having to type\n\"-i\" every time starts to annoy her, and instead will learn to use\nthe tool more effectively and efficiently [*1*], so making \"-i\"\ndefault is not good not just for you but for everybody.\n\n\n[Footnote]\n\n*1* In the context of this discussion, after screwing up the change\n    in hello.c, instead of expressing the wish to recover and to\n    start from scratch in two separate commands, i.e.\n\n\trm hello.c && update-from-scm\n\n    they will learn to use a single command that is designed for\n    that purpose, i.e.\n\n\tcheckout-from-scm hello.c\n\n    without the \"rm\" step, which _is_ an artificial workaround for\n    their other SCMs that do not update from the repository unless\n    they remove the files.\n"},{"id":"262943","messageId":"CAEBDL5XcEWpXeVjYb9spvy1QHbODbuvcXxFRp7_-hq=RNemyXA@mail.gmail.com","threadId":"39511","inReplyTo":"xmqqiob4wkem.fsf@gitster.dls.corp.google.com","subject":"Re: Suggestion: make git checkout safer","fromName":"John Szakmeister","fromEmail":"john@szakmeister.net","sentAt":"2015-06-04T09:01:00Z","receivedAt":"2015-06-04T09:01:00Z","isPatch":false,"sender":{"key":"john@szakmeister.net","avatar":"https://avatars.githubusercontent.com/u/448087?v=4"},"body":"On Wed, Jun 3, 2015 at 5:29 PM, Junio C Hamano <gitster@pobox.com> wrote:\n[snip]\n> [Footnote]\n>\n> *1* In the context of this discussion, after screwing up the change\n>     in hello.c, instead of expressing the wish to recover and to\n>     start from scratch in two separate commands, i.e.\n>\n>         rm hello.c && update-from-scm\n>\n>     they will learn to use a single command that is designed for\n>     that purpose, i.e.\n>\n>         checkout-from-scm hello.c\n>\n>     without the \"rm\" step, which _is_ an artificial workaround for\n>     their other SCMs that do not update from the repository unless\n>     they remove the files.\n\nJust to be clear, Subversion doesn't require you to remove the file to\nrestore it (I'm sure most of you know that, but just in case others\ndidn't).  There is a one-step way to restore the file:\n\n    svn revert hello.c\n\nUnfortunately, revert in the Git sense is about reverting commits, so\nthere's a bit of friction between Subversion and Git's terminology.\nOTOH, once the team was educated how to think about it, \"git checkout\n<path>\" has been pretty natural to use.\n\n-John\n"},{"id":"262945","messageId":"loom.20150604T123949-199@post.gmane.org","threadId":"39511","inReplyTo":"CAGZ79kYv5Xgfv=3KD0oPrUsJD2Yw-EHu7U=_35FZTm4Rp5hbBA@mail.gmail.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-04T10:47:32Z","receivedAt":"2015-06-04T10:47:32Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"Stefan Beller <sbeller <at> google.com> writes:\n\n>So in one mode, we do actually warn about contents going missing, and the\n>other mode is designed to actually make things go missing without any\n>warning.\n\nI think this is a big part of the issue.  Two rather different operations\nare given the name 'checkout', and the safety standards applied to them\nalso differ greatly.  The manual page doesn't make it clear that it can\nbe quite a dangerous command to run, even without --force.\n\n>If I were to come up with a name for such an action it's\n>maybe \"reset\" or \"reset-file(s)\".\n\nAgreed.  Or 'git clean' could become more powerful and able to reset file\ncontents as well as deleting untracked files.  The name and documentation of\n'git clean' already make it clear that it's not something safe to run without\nthinking first.\n\nJulio H. asked how I had learned to run 'git checkout .'.  I think it was just\nword of mouth.  I had deleted some files from the working tree and asked a\ncolleague how to restore them from the repository - which is, after all, a\nbread-and-butter operation for any version control system.  What is the\ncorrect command to run, then, to safely restore missing files?\n\nAnd yes, it probably would be better to use git's native mechanisms to throw\naway local changes to a file, rather than the sledgehammer approach of just\ndeleting it and checking it out again.  Most of the time I do so.  Sometimes\nwhen everything is a real mess it is more straighforward to reach for 'rm' -\nor indeed for the delete option in your IDE or file browser.\n\n-- \nEd Avis <eda@waniasset.com>\n"},{"id":"262946","messageId":"loom.20150604T124827-124@post.gmane.org","threadId":"39511","inReplyTo":"20150603194756.GB29730@vps892.directvps.nl","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-04T11:00:09Z","receivedAt":"2015-06-04T11:00:09Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"Kevin Daudt <me <at> ikke.info> writes:\n\n>If people execute git checkout . as a habbit\n>without thinking, they will soon train to do git checkout -f . without\n>thinking, and then you still have the same problem.\n\nI don't quite agree; you only learn to use the -f flag if the plain command\ndoesn't do what you want.  With rm, I want to remove that file, dammit!  The\n-f flag is often a necessity to stop the tool getting in my way.  But when\nfixing up a working tree, I rarely want to silently trash any local changes.\n\n>I do share your sentiment that it's easy to loose uncomitted changes to\n>git checkout <path>, but like Jeff said, the entire goal of this command\n>is to reset specific files from the index or commits.\n\nWell that's not quite the flavour given by the documentation, which says\n\n    >Updates files in the working tree to match...\n\n'Updating' files sounds like a fairly safe thing to do, right?  Like 'cvs\nupdate' or 'svn update', which don't just overwrite working tree changes.\nThe doc doesn't really make clear that any local changes will be discarded;\nindeed the only mention of that is\n\n       -f, --force\n         When switching branches... this is used to throw away local changes.\n\nTo the casual reader, following 'the exception proves the rule', it appears\nthat local changes are not thrown away except in this case.\n\n-- \nEd Avis <eda@waniasset.com>\n"},{"id":"262947","messageId":"loom.20150604T130018-619@post.gmane.org","threadId":"39511","inReplyTo":"loom.20150604T123949-199@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-04T11:02:19Z","receivedAt":"2015-06-04T11:02:19Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"Ed Avis <eda <at> waniasset.com> writes:\n\n>Julio H. asked how I had learned to run 'git checkout .'.\n\nSorry it was Torsten B. who asked that.  But yes, I think it was just word\nof mouth.\n\n-- \nEd Avis <eda@waniasset.com>\n"},{"id":"262976","messageId":"5570B1AC.2060108@web.de","threadId":"39511","inReplyTo":"loom.20150604T124827-124@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Torsten Bögershausen","fromEmail":"tboegi@web.de","sentAt":"2015-06-04T20:14:36Z","receivedAt":"2015-06-04T20:14:36Z","isPatch":false,"sender":{"key":"tboegi@web.de","avatar":"https://avatars.githubusercontent.com/u/7138363?v=4"},"body":"On 2015-06-04 13.00, Ed Avis wrote:\n> \n>     >Updates files in the working tree to match...\nI think that this had been written with\n\"git checkout <branch>\" in mind, which is different\nfrom \"git checkout -- <paths>\" (or \"git checkout .\")\n\nDo you think you can write a patch to improve the documentation ?\n"},{"id":"263000","messageId":"loom.20150605T113129-339@post.gmane.org","threadId":"39511","inReplyTo":"5570B1AC.2060108@web.de","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-05T09:32:27Z","receivedAt":"2015-06-05T09:32:27Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"Torsten Bögershausen <tboegi <at> web.de> writes:\n\n>Do you think you can write a patch to improve the documentation ?\n\nHere is my attempt, but it is only a starting point.\n\ndiff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\nindex d263a56..ee25354 100644\n--- a/Documentation/git-checkout.txt\n+++ b/Documentation/git-checkout.txt\n@@ -3,7 +3,7 @@ git-checkout(1)\n\n NAME\n ----\n-git-checkout - Checkout a branch or paths to the working tree\n+git-checkout - Overwrite working tree files with a given branch\n\n SYNOPSIS\n --------\n@@ -17,10 +17,11 @@ SYNOPSIS\n\n DESCRIPTION\n -----------\n-Updates files in the working tree to match the version in the index\n-or the specified tree.  If no paths are given, 'git checkout' will\n-also update `HEAD` to set the specified branch as the current\n-branch.\n+Updates, creates, or overwrites files in the working tree to match the\n+version in the index or the specified tree.  If no paths are given,\n+'git checkout' will also update `HEAD` to set the specified branch as\n+the current branch, and will keep local changes.  If paths are given,\n+'git checkout' will unconditionally overwrite local changes.\n\n 'git checkout' <branch>::\n        To prepare for working on <branch>, switch to it by updating\n@@ -81,21 +82,24 @@ Omitting <branch> detaches HEAD at the tip of the\ncurrent branch.\n 'git checkout' [-p|--patch] [<tree-ish>] [--] <pathspec>...::\n\n        When <paths> or `--patch` are given, 'git checkout' does *not*\n-       switch branches.  It updates the named paths in the working tree\n-       from the index file or from a named <tree-ish> (most often a\n-       commit).  In this case, the `-b` and `--track` options are\n-       meaningless and giving either of them results in an error.  The\n-       <tree-ish> argument can be used to specify a specific tree-ish\n-       (i.e.  commit, tag or tree) to update the index for the given\n-       paths before updating the working tree.\n-+\n-The index may contain unmerged entries because of a previous failed merge.\n-By default, if you try to check out such an entry from the index, the\n-checkout operation will fail and nothing will be checked out.\n-Using `-f` will ignore these unmerged entries.  The contents from a\n-specific side of the merge can be checked out of the index by\n-using `--ours` or `--theirs`.  With `-m`, changes made to the working tree\n-file can be discarded to re-create the original conflicted merge result.\n+       switch branches.  It overwrites the named paths in the working\n+       tree from the index file or from a named <tree-ish> (most\n+       often a commit).  Unlike other modes, local modifications to\n+       the files in the working tree are *not* kept.\n+\n+        In this case, the `-b` and `--track` options are meaningless\n+       and giving either of them results in an error.  The <tree-ish>\n+       argument can be used to specify a specific tree-ish (i.e.\n+       commit, tag or tree) to update the index for the given paths\n+       before updating the working tree.  + The index may contain\n+       unmerged entries because of a previous failed merge.  By\n+       default, if you try to check out such an entry from the index,\n+       the checkout operation will fail and nothing will be checked\n+       out.  Using `-f` will ignore these unmerged entries.  The\n+       contents from a specific side of the merge can be checked out\n+       of the index by using `--ours` or `--theirs`.  With `-m`,\n+       changes made to the working tree file can be discarded to\n+       re-create the original conflicted merge result.\n\n OPTIONS\n -------\n@@ -110,7 +114,9 @@ OPTIONS\n        local changes.\n +\n When checking out paths from the index, do not fail upon unmerged\n-entries; instead, unmerged entries are ignored.\n+entries; instead, unmerged entries are ignored.  (Note that when\n+checking out paths, local changes are thrown away whether or not\n+this flag is given.)\n\n --ours::\n --theirs::\n@@ -481,10 +487,10 @@ $ git checkout hello.c            <3>\n ------------\n +\n <1> switch branch\n-<2> take a file out of another commit\n-<3> restore hello.c from the index\n+<2> take a file out of another commit, overwriting any local changes\n+<3> restore hello.c from the index (would overwrite it if it existed)\n +\n-If you want to check out _all_ C source files out of the index,\n+If you want to revert _all_ C source files out of the index,\n you can say\n +\n ------------\n@@ -492,7 +498,7 @@ $ git checkout -- '*.c'\n ------------\n +\n Note the quotes around `*.c`.  The file `hello.c` will also be\n-checked out, even though it is no longer in the working tree,\n+created, even though it is no longer in the working tree,\n because the file globbing is used to match entries in the index\n (not in the working tree by the shell).\n\n"},{"id":"263005","messageId":"CACsJy8Ch7myCC8s-=0yRvQYT_Rwrz97ZAW3mU2KQxVdac6vcbw@mail.gmail.com","threadId":"39511","inReplyTo":"loom.20150605T113129-339@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Duy Nguyen","fromEmail":"pclouds@gmail.com","sentAt":"2015-06-05T10:49:04Z","receivedAt":"2015-06-05T10:49:04Z","isPatch":false,"sender":{"key":"pclouds@gmail.com","avatar":"https://avatars.githubusercontent.com/u/720?v=4"},"body":"On Fri, Jun 5, 2015 at 4:32 PM, Ed Avis <eda@waniasset.com> wrote:\n> Torsten Bögershausen <tboegi <at> web.de> writes:\n>\n>>Do you think you can write a patch to improve the documentation ?\n>\n> Here is my attempt, but it is only a starting point.\n>\n> diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n> index d263a56..ee25354 100644\n> --- a/Documentation/git-checkout.txt\n> +++ b/Documentation/git-checkout.txt\n> @@ -3,7 +3,7 @@ git-checkout(1)\n>\n>  NAME\n>  ----\n> -git-checkout - Checkout a branch or paths to the working tree\n> +git-checkout - Overwrite working tree files with a given branch\n\nMaybe \"switch branches or reset working tree files\"?\n-- \nDuy\n"},{"id":"263047","messageId":"CAPig+cTK4pXgweoGZc1-nj41aYo0bEK6Zrsc9291xQr5v8=p8g@mail.gmail.com","threadId":"39511","inReplyTo":"loom.20150605T113129-339@post.gmane.org","subject":"Re: Suggestion: make git checkout safer","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-06-05T17:44:50Z","receivedAt":"2015-06-05T17:44:50Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jun 5, 2015 at 5:32 AM, Ed Avis <eda@waniasset.com> wrote:\n> Torsten Bögershausen <tboegi <at> web.de> writes:\n>>Do you think you can write a patch to improve the documentation ?\n>\n> Here is my attempt, but it is only a starting point.\n>\n> diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n> index d263a56..ee25354 100644\n> --- a/Documentation/git-checkout.txt\n> +++ b/Documentation/git-checkout.txt\n> @@ -3,7 +3,7 @@ git-checkout(1)\n>\n>  NAME\n>  ----\n> -git-checkout - Checkout a branch or paths to the working tree\n> +git-checkout - Overwrite working tree files with a given branch\n\nI agree with Duy's suggestion of \"switch branches or reset working\ntree files\" since it explains the high-level purpose of the command,\nwhereas your wording gives details of the low-level operation without\nconveying the high-level purpose.\n\n>  SYNOPSIS\n>  --------\n> @@ -17,10 +17,11 @@ SYNOPSIS\n>\n>  DESCRIPTION\n>  -----------\n> -Updates files in the working tree to match the version in the index\n> -or the specified tree.  If no paths are given, 'git checkout' will\n> -also update `HEAD` to set the specified branch as the current\n> -branch.\n> +Updates, creates, or overwrites files in the working tree to match the\n> +version in the index or the specified tree.  If no paths are given,\n> +'git checkout' will also update `HEAD` to set the specified branch as\n> +the current branch, and will keep local changes.\n\nThe two changes you made here don't really work together, do they? In\nthe one case, you changed \"Update\" to \"Update, creates, or\noverwrites\", and in the second you added \"and will keep local changes\"\nwhich seems to contradict the \"overwrites\" bit.\n\nMoreover, as this paragraph is a high-level overview of the modes\nenumerated below, it doesn't necessarily make sense to go into such\ndetail here. For instance, the \"git checkout <branch>\" case\nimmediately below this paragraph already says clearly \"Local\nmodifications to the files in the working tree are kept\", so repeating\nit here seems unnecessary.\n\n> +If paths are given,\n> +'git checkout' will unconditionally overwrite local changes.\n\nLikewise, I'm not convinced that it makes sense to add this sentence.\nThe preceding sentence about updating HEAD applies to all of the\nenumerated cases except the \"git checkout <pathspec>…\" case, so it\nmakes sense to have it in the overview paragraph, however, this new\nsentence applies only to the one case, so its placement here is\nquestionable.\n\n>  'git checkout' <branch>::\n>         To prepare for working on <branch>, switch to it by updating\n> @@ -81,21 +82,24 @@ Omitting <branch> detaches HEAD at the tip of the\n> current branch.\n>  'git checkout' [-p|--patch] [<tree-ish>] [--] <pathspec>...::\n>\n>         When <paths> or `--patch` are given, 'git checkout' does *not*\n> -       switch branches.  It updates the named paths in the working tree\n> -       from the index file or from a named <tree-ish> (most often a\n> -       commit).  In this case, the `-b` and `--track` options are\n> -       meaningless and giving either of them results in an error.  The\n> -       <tree-ish> argument can be used to specify a specific tree-ish\n> -       (i.e.  commit, tag or tree) to update the index for the given\n> -       paths before updating the working tree.\n> -+\n> -The index may contain unmerged entries because of a previous failed merge.\n> -By default, if you try to check out such an entry from the index, the\n> -checkout operation will fail and nothing will be checked out.\n> -Using `-f` will ignore these unmerged entries.  The contents from a\n> -specific side of the merge can be checked out of the index by\n> -using `--ours` or `--theirs`.  With `-m`, changes made to the working tree\n> -file can be discarded to re-create the original conflicted merge result.\n> +       switch branches.  It overwrites the named paths in the working\n> +       tree from the index file or from a named <tree-ish> (most\n> +       often a commit).\n\nRather than \"updates\" or \"overwrites\", how about something like this?\n\n    \"It restores the named paths in the working tree\n    to a pristine state from the index...\"\n\n> +Unlike other modes, local modifications to\n> +       the files in the working tree are *not* kept.\n\nThis sentence seems utterly redundant with the sentence immediately\npreceding it, thus adds noise but no obvious value.\n\n> +        In this case, the `-b` and `--track` options are meaningless\n> +       and giving either of them results in an error.  The <tree-ish>\n> +       argument can be used to specify a specific tree-ish (i.e.\n> +       commit, tag or tree) to update the index for the given paths\n> +       before updating the working tree.  + The index may contain\n> +       unmerged entries because of a previous failed merge.  By\n> +       default, if you try to check out such an entry from the index,\n> +       the checkout operation will fail and nothing will be checked\n> +       out.  Using `-f` will ignore these unmerged entries.  The\n> +       contents from a specific side of the merge can be checked out\n> +       of the index by using `--ours` or `--theirs`.  With `-m`,\n> +       changes made to the working tree file can be discarded to\n> +       re-create the original conflicted merge result.\n\nA couple issues:\n\nIn order for this to format correctly in Asciidoc, it must be\nunindented (as in the original), and you must keep the unindented \"+\"\non the line by itself before the paragraph to tie it to the preceding\nparagraph.\n\nYou mis-wrapped and combined two formerly separate paragraphs into\none. Notice the \"+ The\" in the middle of your re-wrapped paragraph.\n\n>  OPTIONS\n>  -------\n> @@ -110,7 +114,9 @@ OPTIONS\n>         local changes.\n>  +\n>  When checking out paths from the index, do not fail upon unmerged\n> -entries; instead, unmerged entries are ignored.\n> +entries; instead, unmerged entries are ignored.  (Note that when\n> +checking out paths, local changes are thrown away whether or not\n> +this flag is given.)\n\nI don't see what value this change adds. The description of \"git\ncheckout <pathspec>…\" already explains that named paths are restored\nto a pristine state, so talking about it here may give the false\nimpression that the reader must be aware that something unusual or\nunexpected is going on beyond what was already documented.\n\n>  --ours::\n>  --theirs::\n> @@ -481,10 +487,10 @@ $ git checkout hello.c            <3>\n>  ------------\n>  +\n>  <1> switch branch\n> -<2> take a file out of another commit\n> -<3> restore hello.c from the index\n> +<2> take a file out of another commit, overwriting any local changes\n> +<3> restore hello.c from the index (would overwrite it if it existed)\n\nAgain, I don't see what value these changes add. These\nexample-specific notes are intended to explain what is happening in\nthe example. These new clauses don't do that, thus making them\npotentially confusing.\n\nTo really convey that local changes will be overwritten, how about\nadding a new example which demonstrates it explicitly?\n\n> -If you want to check out _all_ C source files out of the index,\n> +If you want to revert _all_ C source files out of the index,\n>  you can say\n\nHow about?\n\n    If you want to restore _all_ C source files to a\n    pristine state from the index, you can say\n\n>  +\n>  ------------\n> @@ -492,7 +498,7 @@ $ git checkout -- '*.c'\n>  ------------\n>  +\n>  Note the quotes around `*.c`.  The file `hello.c` will also be\n> -checked out, even though it is no longer in the working tree,\n> +created, even though it is no longer in the working tree,\n\nAgain:\n\n    ...`hello.c` will also be restored,...\n\n>  because the file globbing is used to match entries in the index\n>  (not in the working tree by the shell).\n"},{"id":"263049","messageId":"xmqqd21arq0n.fsf@gitster.dls.corp.google.com","threadId":"39511","inReplyTo":"CAPig+cTK4pXgweoGZc1-nj41aYo0bEK6Zrsc9291xQr5v8=p8g@mail.gmail.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-05T18:03:52Z","receivedAt":"2015-06-05T18:03:52Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> ...\n> Again:\n>\n>     ...`hello.c` will also be restored,...\n>\n>>  because the file globbing is used to match entries in the index\n>>  (not in the working tree by the shell).\n\nThanks for a thorough review.  I agree with all the comments and\nsuggestions you gave.  Also, Ed, thanks for an attempt to improve\nthe documentation.\n\nI think the biggest problem with this patch is that the tone of the\nupdated text is geared a lot more towards venting the initial\nfrustration of the writer than helping the readers of the document.\n\nBy explaining what the behaviour is meant to solve and help, the\nreaders would get useful information (e.g. \"this is to be used to\nrestore pristine contents\").  The same thing said in the negative\nway only serve to unnecessarily repel readers (e.g. \"this will\nunconditionally overwrite and lose contents\").\n\nTechnically, they are the descriptions of the same thing---in order\nto restore pristine contents to the workng tree, you have to discard\nthe botched changes you made in the working tree, and that is done\n\"unconditionally\" by \"overwriting\" and \"losing contents\".  But\nsaying it in the negative way does not serve as a useful warning.\n\nThe readers are intelligent, and they will understand (and will even\nappreciate) that a request to replace their botched contents in the\nworking tree out of the index is done unconditionally without being\nasked an unnecessary \"are you sure?\" and done by overwriting the\nfiles, losing the botched contents from there, once they are\nexplained why they want to \"git checkout $paths\", what the operation\nis meant to be used for.\n\nPerhaps taking a deep breath and waiting for a few days for the head\nto coll down and frustrations to dissipate may be a good thing to do\n;-)\n"},{"id":"263050","messageId":"CAPig+cTuajnDGdVs18zLd_ngcA=3TZnCn9iNutB9J0FVU1HqrA@mail.gmail.com","threadId":"39511","inReplyTo":"CAPig+cTK4pXgweoGZc1-nj41aYo0bEK6Zrsc9291xQr5v8=p8g@mail.gmail.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-06-05T18:37:21Z","receivedAt":"2015-06-05T18:37:21Z","isPatch":false,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Jun 5, 2015 at 1:44 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Fri, Jun 5, 2015 at 5:32 AM, Ed Avis <eda@waniasset.com> wrote:\n>> Torsten Bögershausen <tboegi <at> web.de> writes:\n>>>Do you think you can write a patch to improve the documentation ?\n>>\n>> Here is my attempt, but it is only a starting point.\n>>\n>> diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt\n>> index d263a56..ee25354 100644\n>> --- a/Documentation/git-checkout.txt\n>> +++ b/Documentation/git-checkout.txt\n>> @@ -3,7 +3,7 @@ git-checkout(1)\n>>\n>>  NAME\n>>  ----\n>> -git-checkout - Checkout a branch or paths to the working tree\n>> +git-checkout - Overwrite working tree files with a given branch\n>\n> I agree with Duy's suggestion of \"switch branches or reset working\n\nI meant, but forgot to say, that I'd probably replace \"reset\" with\n\"restore\" in Duy's suggestion.\n\n> tree files\" since it explains the high-level purpose of the command,\n> whereas your wording gives details of the low-level operation without\n> conveying the high-level purpose.\n"},{"id":"263051","messageId":"loom.20150605T203544-871@post.gmane.org","threadId":"39511","inReplyTo":"xmqqd21arq0n.fsf@gitster.dls.corp.google.com","subject":"Re: Suggestion: make git checkout safer","fromName":"Ed Avis","fromEmail":"eda@waniasset.com","sentAt":"2015-06-05T18:46:41Z","receivedAt":"2015-06-05T18:46:41Z","isPatch":false,"sender":{"key":"eda@waniasset.com","avatar":null},"body":"I'm not attached to the wording changes posted earlier.  As I said, it is\nonly a starting point.\n\nI do feel that 'git checkout PATH' is rather a dangerous operation, and\nmoreover a surprisingly dangerous one, since 'git checkout BRANCH' is\ncareful not to lose local changes, as are other common commands like\n'git pull'.  In the documentation patch I tried to highlight the\ndistinction between the two rather different, and perhaps even\nJekyll-and-Hyde-like, modes of this command.\n\nBut rather than adding heavyhanded and redundant warnings to the\ndocumentation it would be better for the command not to be quite so\nsharp-edged.  There is already a --force option for one mode, which could\neasily be made to apply to the other too (so local changes will not be\ndiscarded unless --force is given).  Is the only argument against it that\n'git checkout is intended to overwrite changes'?  That seems a little\ncircular since the question is whether its intended behaviour could change\nto something a little safer.  Surely a sensible Huffman-coding of git\ncommands would give longer and harder-to-type names like 'git checkout\n--force .' to relatively dangerous operations?\n\nOr indeed, split out the two different modes into two separate commands.\nThe job of reverting file contents seems like something for 'git clean'.\n\nI've said all I have to say but I would like to ask, in the hope of becoming\na better git user: if 'git checkout .' is not a safe way to restore missing\nfiles in the working tree, what is the recommended way to do that?\n\nThanks all for your comments and guidance.\n\n-- \nEd Avis <eda@waniasset.com>\n"}]}