{"thread":{"id":"44425","subject":"git -C has unexpected behaviour","startedAt":"2016-11-04T14:29:05Z","lastAt":"2016-11-07T16:54:55Z","messageCount":5,"participants":["Felix Nairz","Stefan Beller","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"305393","messageId":"CADJspfL3zVCPv+mfRM_v4ukUggQkhGH7KB50a+HLPZXZqn1pXw@mail.gmail.com","threadId":"44425","inReplyTo":null,"subject":"git -C has unexpected behaviour","fromName":"Felix Nairz","fromEmail":"felix.nairz@gmail.com","sentAt":"2016-11-04T14:28:59Z","receivedAt":"2016-11-04T14:29:05Z","isPatch":false,"sender":{"key":"felix.nairz@gmail.com","avatar":null},"body":"Hi guys,\n\nI ran into some really weird git behaviour today.\n\nMy git --version is: git version 2.8.1.windows.1\n\nWe have a git repository with a submodule called TestData. The data in\nthere is modified and reset as part of our unit tests.\n\nThe submodule is a sub-folder of the git repository called TestData.\nSo the relative path from the git repository to the submodule is\n.\\TestData\n\nIf I delete the entire TestData folder and run\ngit -C .\\TestData reset --hard\n\nI will get the following error:\ngit : fatal: Cannot change to '.\\TestData': No such file or directory\nThis is as expected.\n\n\nNow, to the unexpected part, which I think is a bug:\n\nIf the TestData folder is there, but empty (I deleted all the files),\nthen running\n\ngit -C .\\TestData reset --hard\n\nwill NOT throw me an error but run\n\ngit reset --hard\n\non the git repository (not the submodule in the sub-directory!),\nwithout warning, or error. This is easy to reproduce by having an\nempty .\\TestData folder, and just changing any file in your git\nrepository before running\n\ngit -C .\\TestData reset --hard\n\nand seeing the local file changes gone.\n\nBecause of this we have had losses of uncommitted changes a few times\nnow (loosing a few days of work, and getting a bit paranoid), but\ncould never find the root cause for this until today, where I found\nout that it happens when the TestData directory is empty.\n\nThank for looking into this, and I am looking forward to hear your\nopinions about this.\n\nBest Regards, Felix Nairz\n"},{"id":"305395","messageId":"CAGZ79kafn3usjKPPif6yRg1r_zyspWGNqOPLpCeyQwqFKXydwQ@mail.gmail.com","threadId":"44425","inReplyTo":"CADJspfL3zVCPv+mfRM_v4ukUggQkhGH7KB50a+HLPZXZqn1pXw@mail.gmail.com","subject":"Re: git -C has unexpected behaviour","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-11-04T16:10:07Z","receivedAt":"2016-11-04T16:10:14Z","isPatch":false,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Fri, Nov 4, 2016 at 7:28 AM, Felix Nairz <felix.nairz@gmail.com> wrote:\n> Hi guys,\n>\n> I ran into some really weird git behaviour today.\n>\n> My git --version is: git version 2.8.1.windows.1\n>\n> We have a git repository with a submodule called TestData. The data in\n> there is modified and reset as part of our unit tests.\n>\n> The submodule is a sub-folder of the git repository called TestData.\n> So the relative path from the git repository to the submodule is\n> .\\TestData\n>\n> If I delete the entire TestData folder and run\n> git -C .\\TestData reset --hard\n>\n> I will get the following error:\n> git : fatal: Cannot change to '.\\TestData': No such file or directory\n> This is as expected.\n>\n>\n> Now, to the unexpected part, which I think is a bug:\n>\n> If the TestData folder is there, but empty (I deleted all the files),\n\nAnd \"all the files\" includes the \".git\" file, which git uses to find out if\nit is in a git repository. So it keeps walking up until it finds a .git\nfile/directory, which is the parent project.\n\nOnce a git directory is found, the main function of git initializes some\ndata structures, e.g. the \"path prefix\" inside the repository which would be\n\" .\\TestData\" in your case. then the actual command is found and run.\n\nSo what it is doing is:\n\"Suppose you are in the TestData directory of the parent project and then\nrun the command ...\"\n\nMy gut reaction was to propose to check if any GITLINK (submodule)\nis a prefix of said \"path prefix\" and then rather initialize and operate on\nthe submodule.\n\nHowever I do not think this is a good idea:\n* Git wants to be fast and checking if we are in any submodule\nslows down the common case.\n* Historically commands in un-initialized or deinitialized submodules\nbehave as if in the parent project. I think if we'd fix this issue, other\npeople would complain as their workflow is harmed.\n\n>\n> Because of this we have had losses of uncommitted changes a few times\n> now (loosing a few days of work, and getting a bit paranoid),\n\n* commit early, commit often such that the losses are less than a few days.\n* do not remove the submodule directory as a whole thing\n  (make sure the .git file is there and not wiped)\n* instead use \"git -C TestData clean -dffx && git -C TestData reset --hard\"\n   https://git-scm.com/docs/git-clean\n\n\n> could never find the root cause for this until today, where I found\n> out that it happens when the TestData directory is empty.\n\nI am undecided if it is a bug or a feature. Fixing this as a bug\nwould be a performance penalty. Not fixing it may incur data losses.\nI dunno.\n\n>\n> Thank for looking into this, and I am looking forward to hear your\n> opinions about this.\n>\n> Best Regards, Felix Nairz\n"},{"id":"305397","messageId":"alpine.DEB.2.20.1611041719140.3108@virtualbox","threadId":"44425","inReplyTo":"CADJspfL3zVCPv+mfRM_v4ukUggQkhGH7KB50a+HLPZXZqn1pXw@mail.gmail.com","subject":"Re: git -C has unexpected behaviour","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-11-04T16:36:49Z","receivedAt":"2016-11-04T16:36:58Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Felix,\n\nOn Fri, 4 Nov 2016, Felix Nairz wrote:\n\n> Now, to the unexpected part, which I think is a bug:\n> \n> If the TestData folder is there, but empty (I deleted all the files),\n> then running\n> \n> git -C .\\TestData reset --hard\n> \n> will NOT throw me an error but run\n> \n> git reset --hard\n> \n> on the git repository (not the submodule in the sub-directory!),\n> without warning, or error.\n\nI *think* that this is actually intended. Please note that -C is *not* a\nsynonym of --git-dir. It is more of a synonym of\n\n\tcd .\\TestData\n\tgit reset --hard\n\nIn other words, you probably expected -C to specify the top-level\ndirectory of a worktree, and you expected Git to error out when it is not.\nInstead, Git will treat -C as a directory *from where to start*; It *can*\nbe a subdirectory of the top-level directory of the worktree.\n\nPlease note that\n\n\tgit --git-dir=.\\TestData\\.git reset --hard\n\nwill not work, though, as it mistakes the current directory for the\ntop-level directory of the worktree. What you want to do is probably\n\n\tgit -C .\\TestData --git-dir=.git reset --hard\n\nThis will tell Git to change the current working directory to the\ntop-level of your intended worktree, *and* state that the repository needs\nto be in .git (which can be a file containing \"gitdir: <real-git-dir>\",\nwhich is the default in submodules).\n\nIf the repository is *not* found, this command will exit with a failure.\n\nCiao,\nJohannes\n"},{"id":"305477","messageId":"CADJspf+zqj2hHjD85dvt8Y4HKPViubvTzybbTq5mJDGCh2q1UQ@mail.gmail.com","threadId":"44425","inReplyTo":"alpine.DEB.2.20.1611041719140.3108@virtualbox","subject":"Re: git -C has unexpected behaviour","fromName":"Felix Nairz","fromEmail":"felix.nairz@gmail.com","sentAt":"2016-11-07T07:26:45Z","receivedAt":"2016-11-07T07:26:56Z","isPatch":false,"sender":{"key":"felix.nairz@gmail.com","avatar":null},"body":"Hi guys,\n\nthanks for the answer and the clarification.\n\nFrom what you are saying I can see that this expects as designed. It's\nconfusing in the submodule case, but I get you don't want to add extra\nrules which slow down performance and mess with other people at the\nsame time.\n\nI will look into the git-dir solution, this seems to be exactly what I need.\n\nThanks, Felix\n\nOn Fri, Nov 4, 2016 at 5:36 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Felix,\n>\n> On Fri, 4 Nov 2016, Felix Nairz wrote:\n>\n>> Now, to the unexpected part, which I think is a bug:\n>>\n>> If the TestData folder is there, but empty (I deleted all the files),\n>> then running\n>>\n>> git -C .\\TestData reset --hard\n>>\n>> will NOT throw me an error but run\n>>\n>> git reset --hard\n>>\n>> on the git repository (not the submodule in the sub-directory!),\n>> without warning, or error.\n>\n> I *think* that this is actually intended. Please note that -C is *not* a\n> synonym of --git-dir. It is more of a synonym of\n>\n>         cd .\\TestData\n>         git reset --hard\n>\n> In other words, you probably expected -C to specify the top-level\n> directory of a worktree, and you expected Git to error out when it is not.\n> Instead, Git will treat -C as a directory *from where to start*; It *can*\n> be a subdirectory of the top-level directory of the worktree.\n>\n> Please note that\n>\n>         git --git-dir=.\\TestData\\.git reset --hard\n>\n> will not work, though, as it mistakes the current directory for the\n> top-level directory of the worktree. What you want to do is probably\n>\n>         git -C .\\TestData --git-dir=.git reset --hard\n>\n> This will tell Git to change the current working directory to the\n> top-level of your intended worktree, *and* state that the repository needs\n> to be in .git (which can be a file containing \"gitdir: <real-git-dir>\",\n> which is the default in submodules).\n>\n> If the repository is *not* found, this command will exit with a failure.\n>\n> Ciao,\n> Johannes\n"},{"id":"305488","messageId":"alpine.DEB.2.20.1611071753200.3108@virtualbox","threadId":"44425","inReplyTo":"CADJspf+zqj2hHjD85dvt8Y4HKPViubvTzybbTq5mJDGCh2q1UQ@mail.gmail.com","subject":"Re: git -C has unexpected behaviour","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-11-07T16:54:39Z","receivedAt":"2016-11-07T16:54:55Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Felix,\n\nOn Mon, 7 Nov 2016, Felix Nairz wrote:\n\n> From what you are saying I can see that this expects as designed. It's\n> confusing in the submodule case, but I get you don't want to add extra\n> rules which slow down performance and mess with other people at the\n> same time.\n\nThe \"messing with other people\" is the key point. There are most likely\nother users than just me who use the fact that `git -C sub/directory/ ...`\nworks in a subdirectory of a checkout.\n\nCiao,\nJohannes\n"}]}