{"thread":{"id":"50198","subject":"Git rebase --exec cannot run git commands affecting other repos","startedAt":"2019-01-10T16:19:10Z","lastAt":"2019-01-11T16:04:16Z","messageCount":4,"participants":["Samir Benmendil","Junio C Hamano","Jeff King"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"366507","messageId":"20190110161904.23fwbrgg7blyx3nj@uh-nuc001","threadId":"50198","inReplyTo":null,"subject":"Git rebase --exec cannot run git commands affecting other repos","fromName":"Samir Benmendil","fromEmail":"me@rmz.io","sentAt":"2019-01-10T16:19:04Z","receivedAt":"2019-01-10T16:19:10Z","isPatch":false,"sender":{"key":"me@rmz.io","avatar":null},"body":"It is impossible to run git commands affecting a different repo from \nwithin a `git rebase --exec` because in that environment the `GIT_DIR` \nand `GIT_WORK_TREE` variables are set and inherited by any commands run \nas part of `git rebase --exec`.\n\nA minimal reproduction is shown below:\n\n    git init\n    touch file\n    git add file\n    git commit -m\"Commit\"\n    git rebase --root --exec=\"git clone . subrepo\"\n\nIt is a bit convoluted for the sake of being self contained. But any git \ncommand in `--exec` acting on a different repo than the one being \nrebased will fail. See my ticket on CMake [0] for a more real usecase.\n\nAs mentioned in the other ticket, unsetting these variables will work \naround the issue.\n\n    git rebase --root --exec=\"env -u GIT_DIR -u GIT_WORK_TREE git clone . subrepo\"\n\n\n[0] https://gitlab.kitware.com/cmake/cmake/issues/18778\n\nRegards\n"},{"id":"366513","messageId":"xmqqlg3s2wu8.fsf@gitster-ct.c.googlers.com","threadId":"50198","inReplyTo":"20190110161904.23fwbrgg7blyx3nj@uh-nuc001","subject":"Re: Git rebase --exec cannot run git commands affecting other repos","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2019-01-10T18:26:07Z","receivedAt":"2019-01-10T18:26:12Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Samir Benmendil <me@rmz.io> writes:\n\n> It is impossible to run git commands affecting a different repo from\n> within a `git rebase --exec` because in that environment the `GIT_DIR`\n> and `GIT_WORK_TREE` variables are set and inherited by any commands\n> run as part of `git rebase --exec`.\n\nIf the user wants to work in a different repository, the\nenvironments that tells Git about the original repository can be\nunset to do so, which is a very much deliberately designed\nbehaviour, primarily to help those who run \"git rebase\" from a\nsubdirectory of the project.\n\n"},{"id":"366539","messageId":"20190110214842.dfisujzv7psx2jqe@hactar.rmz.io","threadId":"50198","inReplyTo":"xmqqlg3s2wu8.fsf@gitster-ct.c.googlers.com","subject":"Re: Git rebase --exec cannot run git commands affecting other repos","fromName":"Samir Benmendil","fromEmail":"me@rmz.io","sentAt":"2019-01-10T21:48:42Z","receivedAt":"2019-01-10T21:48:50Z","isPatch":false,"sender":{"key":"me@rmz.io","avatar":null},"body":"On Jan 10, 2019 at 10:26, Junio C Hamano wrote:\n> Samir Benmendil <me@rmz.io> writes:\n> \n>> It is impossible to run git commands affecting a different repo from\n>> within a `git rebase --exec` because in that environment the `GIT_DIR`\n>> and `GIT_WORK_TREE` variables are set and inherited by any commands\n>> run as part of `git rebase --exec`.\n> \n> If the user wants to work in a different repository, the\n> environments that tells Git about the original repository can be\n> unset to do so, which is a very much deliberately designed\n> behaviour, primarily to help those who run \"git rebase\" from a\n> subdirectory of the project.\n\nWhen run in a directory that does not have \".git\" repository directory, \nGit tries to find such a directory in the parent directories to find the \ntop of the working tree.\n\nThat should be the case as well for `git rebase`, is it not?\n\n\nRummaging through release notes to find out when this was added, I found \nthe following in `RelNotes/2.19.0.txt`.\n\n * \"git rebase\" started exporting GIT_DIR environment variable and\n   exposing it to hook scripts when part of it got rewritten in C.\n   Instead of matching the old scripted Porcelains' behaviour,\n   compensate by also exporting GIT_WORK_TREE environment as well to\n   lessen the damage.  This can harm existing hooks that want to\n   operate on different repository, but the current behaviour is\n   already broken for them anyway.\n   (merge ab5e67d751 bc/sequencer-export-work-tree-as-well later to maint).\n\nTo me it seems to be more of a regression introduced by porting rebase \nto C that was deemed to be acceptable at the time (only a few months \nago).\n\nI would argue that it is not.\n\nThe behaviour is also inconsistent with running these --exec commands \nfrom the command line while doing an interactive rebase, i.e. when \nchanging one of the lines to \"edit\" and being dropped into the terminal \nfor the edit, these env variables are not set.\n"},{"id":"366562","messageId":"20190111160411.GD16754@sigill.intra.peff.net","threadId":"50198","inReplyTo":"20190110214842.dfisujzv7psx2jqe@hactar.rmz.io","subject":"Re: Git rebase --exec cannot run git commands affecting other repos","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2019-01-11T16:04:12Z","receivedAt":"2019-01-11T16:04:16Z","isPatch":false,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Thu, Jan 10, 2019 at 09:48:42PM +0000, Samir Benmendil wrote:\n\n> > If the user wants to work in a different repository, the\n> > environments that tells Git about the original repository can be\n> > unset to do so, which is a very much deliberately designed\n> > behaviour, primarily to help those who run \"git rebase\" from a\n> > subdirectory of the project.\n> \n> When run in a directory that does not have \".git\" repository directory, Git\n> tries to find such a directory in the parent directories to find the top of\n> the working tree.\n> \n> That should be the case as well for `git rebase`, is it not?\n\nGenerally yes. But \".git\" does not necessarily have to be connected. For\nexample, try this:\n\n  # a separate worktree and repo\n  mkdir worktree\n  git init --bare repo.git\n  git -C repo.git config core.bare false\n  git -C repo.git config core.worktree \"$PWD/worktree\"\n\n  # an unrelated repo we'll try to access\n  git init unrelated\n\n  # operate in the separated repo using $GIT_DIR to point to the repo\n  export GIT_DIR=$PWD/repo.git\n  cd worktree\n\n  # rebase that tries to operate in another repository\n  echo content >file\n  git add file\n  git commit -m file\n  git rebase --root -x 'cd ../unrelated && git rev-parse --git-dir'\n\nAnd in fact, this case behaves the same now or with older versions of\nGit (because GIT_DIR would be set either way). Likewise the less exotic\n\"git --git-dir=something rebase\", which would set GIT_DIR in the\nenvironment. I think there are other cases, too, where we'd internally\nset GIT_DIR during repo discovery, but I don't remember all of them\noffhand.\n\nSo I think the reasoning at the time was along the lines of \"scripts\nalready should not be relying on the absence of $GIT_DIR\". That said, I\ndo think there's an argument to be made that it generally worked before\nin many common setups, even if it was not bulletproof.\n\nAnd I am not sure I could construct a case where setting $GIT_DIR when\nit was not already set explicitly _helps_ the \"exec\" command (because\nif searching from the working tree does not work, then the caller of\n\"git rebase\" would had to have set $GIT_DIR itself).\n\n-Peff\n"}]}