{"thread":{"id":"40214","subject":"\"git checkout\" resets modified files","startedAt":"2015-08-29T06:15:52Z","lastAt":"2015-08-29T07:58:01Z","messageCount":3,"participants":["Steve Heyns","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"268884","messageId":"CANDob0LdQpoSfsedPK_yhNunXBvNTc9L1zKOM9h8dBUDePs0kg@mail.gmail.com","threadId":"40214","inReplyTo":null,"subject":"\"git checkout\" resets modified files","fromName":"Steve Heyns","fromEmail":"notzippy@gmail.com","sentAt":"2015-08-29T06:15:52Z","receivedAt":"2015-08-29T06:15:52Z","isPatch":false,"sender":{"key":"notzippy@gmail.com","avatar":null},"body":"\"git checkout\" resets modified files\n\nVersion git  2.5.0,\n\nDescription:\nI was automating a process that would pull and switch to another\nbranch when I stumbled across this. I have not been able to emulate\nthis from command line but using go (or I imagine other languages are\nsimilar) if you execute a command like\n\nexec.Command(\"git\",\"checkout\",\"\")\n\nA checkout with the branch parameter but the branch parameter is empty.\n\nThe result is git resets the the repository, modified files are reset\nback to original state without warning.\n\nI would expect the behavior should be the same as a \"git checkout\" command\n\nHas anyone else seen something like this ? For myself the solution was\nto simply suppress passing in the revision as a third argument if the\nrevision was empty. But this does appear to be an off behavior.\n\nThanks\nNz\n"},{"id":"268885","messageId":"xmqqlhcuzhsu.fsf@gitster.mtv.corp.google.com","threadId":"40214","inReplyTo":"CANDob0LdQpoSfsedPK_yhNunXBvNTc9L1zKOM9h8dBUDePs0kg@mail.gmail.com","subject":"Re: \"git checkout\" resets modified files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-29T07:15:45Z","receivedAt":"2015-08-29T07:15:45Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Steve Heyns <notzippy@gmail.com> writes:\n\n> \"git checkout\" resets modified files\n>\n> Version git  2.5.0,\n>\n> Description:\n> I was automating a process that would pull and switch to another\n> branch when I stumbled across this. I have not been able to emulate\n> this from command line but using go (or I imagine other languages are\n> similar) if you execute a command like\n>\n> exec.Command(\"git\",\"checkout\",\"\")\n>\n> A checkout with the branch parameter but the branch parameter is empty.\n\nIt is not feeding an empty branch parameter [*1*].  It is asking Git\nto check out all paths that match a pathspec \"\" out of the index.\n\nNow, arguably, the user who would want to match everything may be\nmore likely to give \".\" as the pathspec (or if she is not at the\nroot of the working tree, \":/\"), but \"\" means the same thing as \".\",\nand the requested behaviour \"check out all that match this pathspec\nfrom the index\" would essentially mean \"I want to get rid of all the\nmodification in my working tree relative to the index\".\n\nI do not think this behaviour depends on the vintage of Git.  An\nempty string as pathspec has always matched \"everything in here\"\nAFAIR.\n\n\n[Footnote]\n\n*1* Checking out a branch whose name is an empty string can be asked\n    explicitly by disambiguating double-dash like this:\n\n    $ git checkout \"\" --\n\nAnd it will be answered (correctly) with:\n\n    fatal: invalid reference\n"},{"id":"268886","messageId":"xmqqh9nizfue.fsf@gitster.mtv.corp.google.com","threadId":"40214","inReplyTo":"xmqqlhcuzhsu.fsf@gitster.mtv.corp.google.com","subject":"Re: \"git checkout\" resets modified files","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-08-29T07:58:01Z","receivedAt":"2015-08-29T07:58:01Z","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 do not think this behaviour depends on the vintage of Git.  An\n> empty string as pathspec has always matched \"everything in here\"\n> AFAIR.\n\nHaving said all that, I think the DWIM used by \"git checkout\" has\nsome room for improvement, namely, its \"we didn't see a double-dash;\nis it a ref or is it a pathspec?\" disambiguation should become\nsimilar to the revision parser's.\n\nNotice that\n\n    $ git log \"\"\n\nwill error out, saying that an empty string does not name either a\nrevision or an existing path in the working tree.  I think the same\n\"refusal due to ambiguity\" should be in \"git checkout\" when the user\nsays\n\n    $ git checkout \"\"\n\nRight now, when there is no double-dash, the code checks if the\nfirst token X can be DWIMmed as a ref.  It may either name an\nexisting branch X, or it may be a non-existing branch name, but\nthere is a single remotes/Y/X and the user is too lazy to say 'git\ncheckout -t -b remotes/Y/X X' and instead said 'git checkout X'.\n\nAnd if the first token X cannot be DWIMmed as a ref according to the\nabove logic, unlike the revision parser, we do not check it (and all\nthe subsequent tokens) name existing filesystem entity.\n\nI think we really should.  With that, Steve's command line would\nhave correctly diagnosed as a liely error.\n\nOf course, that still allows people to say\n\n    $ git checkout -- \"\"\n\nif they really mean it, but they can type\n\n    $ git checkout -- :/\n\njust as easily, so there is no big loss.\n\nAfter following the existing code myself, I think this is a rather\neasy low-hanging fruit for any aspiring Git hacker.  Hint, hint...\n\n\n> [Footnote]\n>\n> *1* Checking out a branch whose name is an empty string can be asked\n>     explicitly by disambiguating double-dash like this:\n>\n>     $ git checkout \"\" --\n>\n> And it will be answered (correctly) with:\n>\n>     fatal: invalid reference\n"}]}