{"thread":{"id":"48366","subject":"In some rebases, `exec git -C ...` has wrong working directory","startedAt":"2018-04-27T02:56:54Z","lastAt":"2018-04-27T17:15:24Z","messageCount":3,"participants":["William Chargin","Johannes Schindelin"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"345934","messageId":"CAFW+GMAJcCG4mKe4TxFXXrfdRhZKXv8ffC-rNShFLW2J1_FANA@mail.gmail.com","threadId":"48366","inReplyTo":null,"subject":"In some rebases, `exec git -C ...` has wrong working directory","fromName":"William Chargin","fromEmail":"wchargin@gmail.com","sentAt":"2018-04-27T02:56:29Z","receivedAt":"2018-04-27T02:56:54Z","isPatch":false,"sender":{"key":"wchargin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/4317806?v=4"},"body":"Here is a repro script:\n\n    #!/bin/sh\n    set -eux\n    git --version\n    tmpdir=\"$(mktemp -d)\"\n    cd \"${tmpdir}\"\n    mkdir target repo\n    cd repo\n    git init\n    touch file; git add file\n    git commit -m \"Initial commit\"\n    git rebase HEAD --exec \"git -C ${tmpdir}/target init\"\n\nThe end of this script prints something like\n\n    Executing: git -C /tmp/tmp.gd2q51jO93/target init\n    Reinitialized existing Git repository in /tmp/tmp.gd2q51jO93/repo/.git/\n    Successfully rebased and updated refs/heads/master.\n\nBut this is wrong: the repository should be initialized in `target`, not\nreinitialized in `repo`.\n\nNotes:\n\n  - This propagates to subprocesses: if you run `exec make test` and\n    your test suite ends up calling `git -C`, then the same problem\n    occurs.\n\n  - Substituting `rebase --root` for `rebase HEAD` causes the problem to\n    go away.\n\n  - The `rebase HEAD` exec context adds the `GIT_DIR` environment\n    variable, and this is sufficient to reproduce the problem:\n    running `GIT_DIR=\"$PWD\" git -C /tmp/target init` puts the repo in\n    the current working directory. The `rebase --root` context adds no\n    such environment variable. (You can use `--exec 'env >tempfile'` to\n    verify these.)\n\nMy `git --version` is 2.16.2.\n"},{"id":"345945","messageId":"nycvar.QRO.7.76.6.1804270939400.72@tvgsbejvaqbjf.bet","threadId":"48366","inReplyTo":"CAFW+GMAJcCG4mKe4TxFXXrfdRhZKXv8ffC-rNShFLW2J1_FANA@mail.gmail.com","subject":"Re: In some rebases, `exec git -C ...` has wrong working directory","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2018-04-27T07:45:58Z","receivedAt":"2018-04-27T07:46:25Z","isPatch":false,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi William,\n\nOn Thu, 26 Apr 2018, William Chargin wrote:\n\n> Here is a repro script:\n> \n>     #!/bin/sh\n>     set -eux\n>     git --version\n>     tmpdir=\"$(mktemp -d)\"\n>     cd \"${tmpdir}\"\n>     mkdir target repo\n>     cd repo\n>     git init\n>     touch file; git add file\n>     git commit -m \"Initial commit\"\n>     git rebase HEAD --exec \"git -C ${tmpdir}/target init\"\n\nWe do take pains to pass the GIT_DIR to the exec'ed command, and it is the\nGIT_DIR of the worktree in which the rebase runs.\n\n> The end of this script prints something like\n> \n>     Executing: git -C /tmp/tmp.gd2q51jO93/target init\n>     Reinitialized existing Git repository in /tmp/tmp.gd2q51jO93/repo/.git/\n>     Successfully rebased and updated refs/heads/master.\n\nSo that is actually what I expected.\n\nI might even have one or two scripts relying on that feature, where\nsomething like\n\n\texec git -C /somewhere/else show HEAD:some-file >some-other-file\n\nis executed, and works.\n\n> But this is wrong: the repository should be initialized in `target`, not\n> reinitialized in `repo`.\n> \n> Notes:\n> \n>   - This propagates to subprocesses: if you run `exec make test` and\n>     your test suite ends up calling `git -C`, then the same problem\n>     occurs.\n> \n>   - Substituting `rebase --root` for `rebase HEAD` causes the problem to\n>     go away.\n> \n>   - The `rebase HEAD` exec context adds the `GIT_DIR` environment\n>     variable, and this is sufficient to reproduce the problem:\n>     running `GIT_DIR=\"$PWD\" git -C /tmp/target init` puts the repo in\n>     the current working directory. The `rebase --root` context adds no\n>     such environment variable. (You can use `--exec 'env >tempfile'` to\n>     verify these.)\n> \n> My `git --version` is 2.16.2.\n\nEven `pu` has the same behavior.\n\nI do not think that we can sensibly *remove* GIT_DIR from the environment\nvariables passed to the exec'ed command, as we have been doing that for\nages, and some scripts (as demonstrated above) started relying on that\nbehavior. So if we changed it, we would break backwards-compatibility,\nwhich is something we try to avoid very much in Git.\n\nMaybe you could a contribute a patch to the documentation? Something that\ntells people who use the `--exec` option that they want to prefix their\ncommand with `unset GIT_DIR; ` when their command wants to work with a\ndifferent Git repository than the current one?\n\nCiao,\nJohannes\n"},{"id":"345962","messageId":"CAFW+GMC5ST5tuSJAShDGkPeZ2ifLV1M9R3j_L+usPn+=+tAYaw@mail.gmail.com","threadId":"48366","inReplyTo":"nycvar.QRO.7.76.6.1804270939400.72@tvgsbejvaqbjf.bet","subject":"Re: In some rebases, `exec git -C ...` has wrong working directory","fromName":"William Chargin","fromEmail":"wchargin@gmail.com","sentAt":"2018-04-27T17:14:58Z","receivedAt":"2018-04-27T17:15:24Z","isPatch":false,"sender":{"key":"wchargin@gmail.com","avatar":"https://avatars.githubusercontent.com/u/4317806?v=4"},"body":"Hi Johannes,\n\nThanks for your reply.\n\nPart of my confusion was regarding the interaction between `-C` and\n`--git-dir`. For instance, we have\n\n    $ git --git-dir target -C /tmp/tmp.Cl4aXMSVis init\n    Initialized empty Git repository in /tmp/tmp.Cl4aXMSVis/target/\n\nwhich makes sense and is what I expected: the `-C` and `--git-dir`\nvalues are joined, as suggested by the docs for `-C` in git(1). But with\n\n    $ git --git-dir /tmp/tmp.Cl4aXMSVis/repo -C /tmp/tmp.Cl4aXMSVis init\n    Initialized empty Git repository in /tmp/tmp.Cl4aXMSVis/repo/\n\nit appears that the `-C` argument is ignored entirely. Is this because\nrunning `git -C foo ...` is equivalent to running `cd foo; git ...` in a\nshell, so when the `--git-dir` is an absolute path the value of `-C` has\nno effect? (Assuming that `GIT_WORK_TREE` is unset.)\n\nIn your example:\n\n>        exec git -C /somewhere/else show HEAD:some-file >some-other-file\n\nisn't the behavior to copy the version of `some-file` in the repository\nbeing rebased to `some-other-file` in the current working directory,\nsuch that the `-C` has no effect, because the shell redirect is not\naffected by the `-C`? (This is what happens for me.) If so, why include\nthe `-C` in the command?\n\n> I do not think that we can sensibly *remove* GIT_DIR from the environment\n> variables passed to the exec'ed command, as we have been doing that for\n> ages, and some scripts (as demonstrated above) started relying on that\n> behavior. So if we changed it, we would break backwards-compatibility,\n> which is something we try to avoid very much in Git.\n\nThis makes sense; understood and agreed.\n\nDo you know why `rebase --root` does not set `GIT_DIR`?\n\n> Maybe you could a contribute a patch to the documentation?\n\nSure; I'd be happy to do that once I understand this a bit better. :-)\n\nBest,\nWC\n"}]}