{"thread":{"id":"64157","subject":"Fwd: Why does git-status suggest different commands to unstage files depending on whether there is a commit yet or not?","startedAt":"2025-09-16T21:51:47Z","lastAt":"2025-09-18T06:57:04Z","messageCount":3,"participants":["Anselm Schüler","Chris Torek","Johannes Sixt"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"526505","messageId":"c28bff47-04ef-4568-8dc3-add99f52209a@anselmschueler.com","threadId":"64157","inReplyTo":"8e1905c7-7744-444f-9a39-ca809edb6896@anselmschueler.com","subject":"Fwd: Why does git-status suggest different commands to unstage files depending on whether there is a commit yet or not?","fromName":"Anselm Schüler","fromEmail":"mail@anselmschueler.com","sentAt":"2025-09-16T21:51:45Z","receivedAt":"2025-09-16T21:51:47Z","isPatch":false,"sender":{"key":"mail@anselmschueler.com","avatar":"https://gravatar.com/avatar/fb911b2f7cf9596f7bbc61cd9799da5fe87733c0394d6ca79531e07368fd757f?d=mp&s=160"},"body":"forgot to Reply All 💀\n\n\n\n-------- Forwarded Message --------\nSubject: \tRe: Why does git-status suggest different commands to unstage \nfiles depending on whether there is a commit yet or not?\nDate: \tTue, 16 Sep 2025 22:56:52 +0200\nFrom: \tAnselm Schüler <mail@anselmschueler.com>\nTo: \tJunio C Hamano <gitster@pobox.com>\n\n\n\nThat makes sense, thank you.\n\nI suppose this isn’t that interesting, but I find this unintuitive. If \nit were not for the suggestion in git-status on an empty repository, I \nwould’ve assumed git-rm simply removes the file and “writes” that \nremoval to the staged changes. This seems to be what y’all are \ndescribing. But with that suggestion, I was confused, because I assumed \ngit-rm there would be equivalent in some sense to git-restore in a \nrepository with commits.\n\nCould git-restore be made to work anyway, by “imagining” a \npre-initial-commit commit that has absolutely nothing in it?\n\nOn 16/09/2025 22:48, Junio C Hamano wrote:\n> Anselm Schüler <mail@anselmschueler.com> writes:\n>\n>> $ git status\n>> [...]\n>> No commits yet\n>>\n>> Changes to be committed:\n>> (use \"git rm --cached <file>...\" to unstage)\n>> [...]\n> As this is a very initial commit, any file you are including would\n> only exist in the index and in the working tree files. The index is\n> where you prepare the contents of the commit you are going to\n> create, and \"git rm --cached <file>\" is the way to remove <file>\n> from there without losing or clobbering the <file> in the working\n> tree. As you do not have a commit yet, you wouldn't have anywhere\n> to \"restore\" from, would you?\n>\n>> After a commit has been made, git-status suggests using git-restore \n>> instead:\n>>\n>> $ git status\n>> [...]\n>> Changes to be committed:\n>> (use \"git restore --staged <file>...\" to unstage)\n>> [...]\n> Compared to the previous situation, you do have a commit, so you can\n> restore to the version in that commit. During the course of\n> development that led you to this state, you may have added <file> in\n> a commit way before the current commit, and you may have made\n> changes to the <file> multiple times in different commits before the\n> current commit. \"git rm --cached <file>\" would not be how you would\n> go back to the version in the current commit in such a situation, as\n> it would take you to the state _before_ you originally added that\n> file. You would \"restore\" the contents in the index to that of the\n> current commit (i.e. HEAD) to go back to the state.\n>\n> So, isn't a short answer to the \"why\" question, \"because that is\n> what you need to do\", I guess?\n"},{"id":"526556","messageId":"CAPx1Gvdnz=PjF7viakFmYUSL72aQS83O9c8NWBCz_1Nt7z2V-Q@mail.gmail.com","threadId":"64157","inReplyTo":"c28bff47-04ef-4568-8dc3-add99f52209a@anselmschueler.com","subject":"Re: Why does git-status suggest different commands to unstage files depending on whether there is a commit yet or not?","fromName":"Chris Torek","fromEmail":"chris.torek@gmail.com","sentAt":"2025-09-17T08:03:47Z","receivedAt":"2025-09-17T08:04:01Z","isPatch":false,"sender":{"key":"chris.torek@gmail.com","avatar":"https://avatars.githubusercontent.com/u/16826774?v=4"},"body":"[resend as plain text]\n\nOn Tue, Sep 16, 2025 at 2:53 PM Anselm Schüler <mail@anselmschueler.com> wrote:\n> ... I would’ve assumed git-rm simply removes the file\n> and “writes” that removal to the staged changes.\n\nMore precisely, it removes the file from the working tree\nand removes the index entry that would cause the index\ncopy of the file to be in the next commit.\n\n> This seems to be what y’all are\n> describing. But with that suggestion, I was confused, because I assumed\n> git-rm there would be equivalent in some sense to git-restore in a\n> repository with commits.\n>\n> Could git-restore be made to work anyway, by “imagining” a\n> pre-initial-commit commit that has absolutely nothing in it?\n\nYes, and in fact a number of Git internal operations work this\nway, by pretending the commit before the first commit has as\nits tree the empty tree. If `git restore` did that here it would\nJust Work. (This is part of why the empty tree always seems\nto exist.)\n\nWhether this is a Good Idea, I leave to others to judge, as\nI'm too well steeped in Git internals to tell any more. :-)\n\nChris\n"},{"id":"526679","messageId":"42250bbc-95f1-4f15-825e-66fbafb0b061@kdbg.org","threadId":"64157","inReplyTo":"c28bff47-04ef-4568-8dc3-add99f52209a@anselmschueler.com","subject":"Re: Fwd: Why does git-status suggest different commands to unstage files depending on whether there is a commit yet or not?","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2025-09-18T06:56:55Z","receivedAt":"2025-09-18T06:57:04Z","isPatch":false,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 16.09.25 um 23:51 schrieb Anselm Schüler:\n> [...] I\n> would’ve assumed git-rm simply removes the file and “writes” that\n> removal to the staged changes. This seems to be what y’all are\n> describing. But with that suggestion, I was confused, because I assumed\n> git-rm there would be equivalent in some sense to git-restore in a\n> repository with commits.\n\nYou seem to think that `git rm` removes a *change*. This leads me to\nbelieve that you think of commits as a set of *changes*. But this is the\nwrong mental model. A commit is a complete state of the project, and the\nindex (\"stage\") is the complete project state that is going into the\nnext commit. `git rm` removes a file, not a change.\n\n-- Hannes\n\n"}]}