{"thread":{"id":"36872","subject":"Re: Git reset --hard with staged changes","startedAt":"2014-06-09T11:24:56Z","lastAt":"2014-06-10T16:30:13Z","messageCount":9,"participants":["Pierre-François CLEMENT","David Kastrup","Junio C Hamano","Dale Worley"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"243618","messageId":"CANWD=rX-MEiS4cNzDWr2wwkshz2zu8-L31UrKwbZrJSBcJX-nQ@mail.gmail.com","threadId":"36872","inReplyTo":"CANWD=rWmzgAwTp=E_1=th0Myk-dh4m5Y9PE3=fpHeirsVVQKwQ@mail.gmail.com","subject":"Re: Git reset --hard with staged changes","fromName":"Pierre-François CLEMENT","fromEmail":"likeyn@gmail.com","sentAt":"2014-06-09T11:24:56Z","receivedAt":"2014-06-09T11:24:56Z","isPatch":false,"sender":{"key":"likeyn@gmail.com","avatar":"https://gravatar.com/avatar/d2efe6b33bc5c161a48ec7f2515bc286da4b8ad94adf29ff546845d69d8aeb7d?d=mp&s=160"},"body":"Hi all,\n\nSomeone pointed out on the \"Git for human beings\" Google group\n(https://groups.google.com/d/topic/git-users/27_FxIV_100/discussion)\nthat using git-reset's hard mode when having staged untracked files\nsimply deletes them from the working dir.\n\nSince git-reset specifically doesn't touch untracked files, one could\nexpect having staged untracked files reset to their previous\n\"untracked\" state rather than being deleted.\n\nCould this be a bug or a missing feature? Or if it isn't, can someone\nexplain what we got wrong?\nCheers\n\n--\nPierre-François CLEMENT\nApplication developer at Upcast Social\n"},{"id":"243624","messageId":"87vbsayy9w.fsf@fencepost.gnu.org","threadId":"36872","inReplyTo":"CANWD=rX-MEiS4cNzDWr2wwkshz2zu8-L31UrKwbZrJSBcJX-nQ@mail.gmail.com","subject":"Re: Git reset --hard with staged changes","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2014-06-09T14:04:43Z","receivedAt":"2014-06-09T14:04:43Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Pierre-François CLEMENT <likeyn@gmail.com> writes:\n\n> Hi all,\n>\n> Someone pointed out on the \"Git for human beings\" Google group\n> (https://groups.google.com/d/topic/git-users/27_FxIV_100/discussion)\n> that using git-reset's hard mode when having staged untracked files\n> simply deletes them from the working dir.\n>\n> Since git-reset specifically doesn't touch untracked files, one could\n> expect having staged untracked files reset to their previous\n> \"untracked\" state rather than being deleted.\n>\n> Could this be a bug or a missing feature? Or if it isn't, can someone\n> explain what we got wrong?\n\ngit reset --keep maybe?\n\nIn a work dir and index without modifications, I expect\n\ngit apply --index ...\ngit reset --hard\n\nto remove any files that git apply created.  It would not do so using\nyour proposal.  I agree that it seems a bit of a borderline, but I\nconsider it better that once a file _is_ tracked, git reset --hard will\nfirst physically remove it before untracking it.\n\n-- \nDavid Kastrup\n"},{"id":"243678","messageId":"CANWD=rVB249Vu1QMk64V+FxfCfJPzxqZgCfyEuixJJ_iKoTLPQ@mail.gmail.com","threadId":"36872","inReplyTo":"87vbsayy9w.fsf@fencepost.gnu.org","subject":"Re: Git reset --hard with staged changes","fromName":"Pierre-François CLEMENT","fromEmail":"likeyn@gmail.com","sentAt":"2014-06-09T23:22:55Z","receivedAt":"2014-06-09T23:22:55Z","isPatch":false,"sender":{"key":"likeyn@gmail.com","avatar":"https://gravatar.com/avatar/d2efe6b33bc5c161a48ec7f2515bc286da4b8ad94adf29ff546845d69d8aeb7d?d=mp&s=160"},"body":"2014-06-09 16:04 GMT+02:00 David Kastrup <dak@gnu.org>:\n> Pierre-François CLEMENT <likeyn@gmail.com> writes:\n>\n>> Hi all,\n>>\n>> Someone pointed out on the \"Git for human beings\" Google group\n>> (https://groups.google.com/d/topic/git-users/27_FxIV_100/discussion)\n>> that using git-reset's hard mode when having staged untracked files\n>> simply deletes them from the working dir.\n>>\n>> Since git-reset specifically doesn't touch untracked files, one could\n>> expect having staged untracked files reset to their previous\n>> \"untracked\" state rather than being deleted.\n>>\n>> Could this be a bug or a missing feature? Or if it isn't, can someone\n>> explain what we got wrong?\n>\n> git reset --keep maybe?\n>\n> In a work dir and index without modifications, I expect\n>\n> git apply --index ...\n> git reset --hard\n>\n> to remove any files that git apply created.  It would not do so using\n> your proposal.  I agree that it seems a bit of a borderline, but I\n> consider it better that once a file _is_ tracked, git reset --hard will\n> first physically remove it before untracking it.\n>\n> --\n> David Kastrup\n\nHm, I didn't think of \"git apply --index\"... Makes sense for this\nspecial use, but I'm not sure about the other use cases. Consider this\nscenario:\n\nYou create a new (untracked) file.\nYou use git-reset's hard mode to go one commit back, the new\n(untracked) file's still there.\nYou add/stage that new file.\nYou use git-reset's hard mode again to go one commit back, and the new\nuntracked file you just staged gets deleted.\n\nAlso, according to Git-scm\n(http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository):\n\n\"Tracked files are files that were in the last snapshot [...].\nUntracked files are everything else.\"\n\nSo it seems to me like staged untracked files shouldn't be considered\nas tracked files, and thus shouldn't be removed. Or maybe, git-reset's\nhard mode should always delete everything including untracked files?\nIt would also make sense, given the numerous modes it has.\n\n--\nPierre-François CLEMENT\nApplication developer at Upcast Social\n"},{"id":"243688","messageId":"xmqq61k9d5nk.fsf@gitster.dls.corp.google.com","threadId":"36872","inReplyTo":"CANWD=rVB249Vu1QMk64V+FxfCfJPzxqZgCfyEuixJJ_iKoTLPQ@mail.gmail.com","subject":"Re: Git reset --hard with staged changes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-06-09T23:28:31Z","receivedAt":"2014-06-09T23:28:31Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pierre-François CLEMENT <likeyn@gmail.com> writes:\n\n> Hm, I didn't think of \"git apply --index\"... Makes sense for this\n> special use, but I'm not sure about the other use cases.\n\nTry merging another branch that tracks a file your current branch\ndoes not know about and ending up with conflicts during that merge.\nResetting the half-done result away must remove that new path from\nyour working tree and the index.\n"},{"id":"243694","messageId":"loom.20140610T025754-449@post.gmane.org","threadId":"36872","inReplyTo":"CANWD=rVB249Vu1QMk64V+FxfCfJPzxqZgCfyEuixJJ_iKoTLPQ@mail.gmail.com","subject":"Re: Git reset --hard with staged changes","fromName":"Dale Worley","fromEmail":"worley@alum.mit.edu","sentAt":"2014-06-10T01:03:09Z","receivedAt":"2014-06-10T01:03:09Z","isPatch":false,"sender":{"key":"worley@alum.mit.edu","avatar":"https://avatars.githubusercontent.com/u/19911107?v=4"},"body":"From: Pierre-François CLEMENT <likeyn <at> gmail.com>\n> You create a new (untracked) file.\n> You use git-reset's hard mode to go one commit back, the new\n> (untracked) file's still there.\n> You add/stage that new file.\n> You use git-reset's hard mode again to go one commit back, and the new\n> untracked file you just staged gets deleted.\n> \n> Also, according to Git-scm\n> (http://git-scm.com/book/en/Git-Basics-Recording-Changes-to-the-Repository):\n> \n> \"Tracked files are files that were in the last snapshot [...].\n> Untracked files are everything else.\"\n> \n> So it seems to me like staged untracked files shouldn't be considered\n> as tracked files, and thus shouldn't be removed. Or maybe, git-reset's\n> hard mode should always delete everything including untracked files?\n> It would also make sense, given the numerous modes it has.\n\nThere's a core question that must be answered:  What, *exactly*, is a\n\"tracked file\"?\n\nIf you look at that passage in the book, it continues:\n\n\"Tracked files are files that were in the last snapshot; they can be\nunmodified, modified, or staged. Untracked files are everything else — any\nfiles in your working directory that were not in your last snapshot and are\nnot in your staging area.\"\n\nBut if you look carefully, that passage gives two definitions of \"untracked\nfiles\", and *they don't agree*, specifically in the case of a file that is\nin the index but not in the base commit.  And that's the case we're considering.\n\nTo fix this, you've got to figure out what the definition of \"tracked file\"\nis supposed to be, and then ensure that everything (code and documentation)\nis consistent with that.\n\n(As far as I can tell from Git's behavior, the definition of tracked file is\n\"any file that is in the base commit or in the index\".  Based on that\ndefinition, \"git reset --hard\" is working as documented.)\n\nDale\n"},{"id":"243704","messageId":"xmqqsindb9nu.fsf@gitster.dls.corp.google.com","threadId":"36872","inReplyTo":"loom.20140610T025754-449@post.gmane.org","subject":"Re: Git reset --hard with staged changes","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2014-06-10T05:44:53Z","receivedAt":"2014-06-10T05:44:53Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Dale Worley <worley@alum.mit.edu> writes:\n\n> (As far as I can tell from Git's behavior, the definition of tracked file is\n> \"any file that is in the base commit or in the index\".  Based on that\n> definition, \"git reset --hard\" is working as documented.)\n\nThe book (whichever book you guys are talking about) is wrong, if it\nconsiders only the paths in the HEAD commit tracked.  After the user\ndeliberately does \"git add\" a path not in HEAD, the user runs any\ncommand (e.g. \"git apply --index\", \"git cherry-pick --no-commit\")\nthat may bring a path not in HEAD to the result without recording a\nnew commit that updates the HEAD, a new path is recorded in the\nindex and that path is considered \"tracked\" before the resulting\ncontents in the index is made into a commit.\n"},{"id":"243736","messageId":"CANWD=rUz9Wgoktp7-NkQMvWDmYOPv0kMqUNoe4FPJ9+Ax_UJBA@mail.gmail.com","threadId":"36872","inReplyTo":"xmqq61k9d5nk.fsf@gitster.dls.corp.google.com","subject":"Re: Git reset --hard with staged changes","fromName":"Pierre-François CLEMENT","fromEmail":"likeyn@gmail.com","sentAt":"2014-06-10T14:59:19Z","receivedAt":"2014-06-10T14:59:19Z","isPatch":false,"sender":{"key":"likeyn@gmail.com","avatar":"https://gravatar.com/avatar/d2efe6b33bc5c161a48ec7f2515bc286da4b8ad94adf29ff546845d69d8aeb7d?d=mp&s=160"},"body":"2014-06-10 1:28 GMT+02:00 Junio C Hamano <gitster@pobox.com>:\n> Pierre-François CLEMENT <likeyn@gmail.com> writes:\n>\n>> Hm, I didn't think of \"git apply --index\"... Makes sense for this\n>> special use, but I'm not sure about the other use cases.\n>\n> Try merging another branch that tracks a file your current branch\n> does not know about and ending up with conflicts during that merge.\n> Resetting the half-done result away must remove that new path from\n> your working tree and the index.\n\nHm I see. Even though the documentation doesn't make it very clear\nabout what happens to such files, it turns out the scenario we\nstumbled upon seems to be the special use case after all. Thanks for\nshedding some light on this :) I wonder why does git-reset's hard mode\nnot always remove untracked files then?\n--\nPierre-François CLEMENT\nApplication developer at Upcast Social\n"},{"id":"243738","messageId":"871tuwss2p.fsf@fencepost.gnu.org","threadId":"36872","inReplyTo":"CANWD=rUz9Wgoktp7-NkQMvWDmYOPv0kMqUNoe4FPJ9+Ax_UJBA@mail.gmail.com","subject":"Re: Git reset --hard with staged changes","fromName":"David Kastrup","fromEmail":"dak@gnu.org","sentAt":"2014-06-10T15:27:26Z","receivedAt":"2014-06-10T15:27:26Z","isPatch":false,"sender":{"key":"dak@gnu.org","avatar":"https://avatars.githubusercontent.com/u/52141349?v=4"},"body":"Pierre-François CLEMENT <likeyn@gmail.com> writes:\n\n> 2014-06-10 1:28 GMT+02:00 Junio C Hamano <gitster@pobox.com>:\n>> Pierre-François CLEMENT <likeyn@gmail.com> writes:\n>>\n>>> Hm, I didn't think of \"git apply --index\"... Makes sense for this\n>>> special use, but I'm not sure about the other use cases.\n>>\n>> Try merging another branch that tracks a file your current branch\n>> does not know about and ending up with conflicts during that merge.\n>> Resetting the half-done result away must remove that new path from\n>> your working tree and the index.\n>\n> Hm I see. Even though the documentation doesn't make it very clear\n> about what happens to such files, it turns out the scenario we\n> stumbled upon seems to be the special use case after all. Thanks for\n> shedding some light on this :) I wonder why does git-reset's hard mode\n> not always remove untracked files then?\n\nBecause it never removes them?  Git only removes files once it tracks\nthem.  This includes the operation of removing _and_ untracking them,\nlike with git reset --hard.\n\nThe only command which explicitly messes with untracked files is\ngit-clean.\n\n-- \nDavid Kastrup\n"},{"id":"243744","messageId":"CANWD=rWRT1iarnZzyd75g6gr0nyo3rrdH01j+Bjq0t4q2UUhhg@mail.gmail.com","threadId":"36872","inReplyTo":"871tuwss2p.fsf@fencepost.gnu.org","subject":"Re: Git reset --hard with staged changes","fromName":"Pierre-François CLEMENT","fromEmail":"likeyn@gmail.com","sentAt":"2014-06-10T16:30:13Z","receivedAt":"2014-06-10T16:30:13Z","isPatch":false,"sender":{"key":"likeyn@gmail.com","avatar":"https://gravatar.com/avatar/d2efe6b33bc5c161a48ec7f2515bc286da4b8ad94adf29ff546845d69d8aeb7d?d=mp&s=160"},"body":"2014-06-10 17:27 GMT+02:00 David Kastrup <dak@gnu.org>:\n> Pierre-François CLEMENT <likeyn@gmail.com> writes:\n>\n>> 2014-06-10 1:28 GMT+02:00 Junio C Hamano <gitster@pobox.com>:\n>>> Pierre-François CLEMENT <likeyn@gmail.com> writes:\n>>>\n>>>> Hm, I didn't think of \"git apply --index\"... Makes sense for this\n>>>> special use, but I'm not sure about the other use cases.\n>>>\n>>> Try merging another branch that tracks a file your current branch\n>>> does not know about and ending up with conflicts during that merge.\n>>> Resetting the half-done result away must remove that new path from\n>>> your working tree and the index.\n>>\n>> Hm I see. Even though the documentation doesn't make it very clear\n>> about what happens to such files, it turns out the scenario we\n>> stumbled upon seems to be the special use case after all. Thanks for\n>> shedding some light on this :) I wonder why does git-reset's hard mode\n>> not always remove untracked files then?\n>\n> Because it never removes them?  Git only removes files once it tracks\n> them.  This includes the operation of removing _and_ untracking them,\n> like with git reset --hard.\n>\n> The only command which explicitly messes with untracked files is\n> git-clean.\n>\n> --\n> David Kastrup\n\nYeah sorry, I just noticed the emails on the definition of what are\n(un)tracked files\n(http://thread.gmane.org/gmane.comp.version-control.git/251071/focus=251151),\nas I didn't get them in my inbox for some reason. So staged files\nwhich aren't in HEAD are also considered tracked -- which explains it\nall. Someone told me that too on the \"Git for human beings\" Google\nGroup, but I couldn't find a definition that backs this in the man\npages (maybe the git-glossary would be a good place for it?), and the\none from the Git-Scm book only confused me in thinking the opposite.\nThanks for the clarification\n\n--\nPierre-François CLEMENT\nApplication developer at Upcast Social\n"}]}