git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
* Git rebase --exec cannot run git commands affecting other repos
@ 2019-01-10 16:19 Samir Benmendil
  2019-01-10 18:26 ` Junio C Hamano
  0 siblings, 1 reply; 4+ messages in thread
From: Samir Benmendil @ 2019-01-10 16:19 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 890 bytes --]

It is impossible to run git commands affecting a different repo from 
within a `git rebase --exec` because in that environment the `GIT_DIR` 
and `GIT_WORK_TREE` variables are set and inherited by any commands run 
as part of `git rebase --exec`.

A minimal reproduction is shown below:

    git init
    touch file
    git add file
    git commit -m"Commit"
    git rebase --root --exec="git clone . subrepo"

It is a bit convoluted for the sake of being self contained. But any git 
command in `--exec` acting on a different repo than the one being 
rebased will fail. See my ticket on CMake [0] for a more real usecase.

As mentioned in the other ticket, unsetting these variables will work 
around the issue.

    git rebase --root --exec="env -u GIT_DIR -u GIT_WORK_TREE git clone . subrepo"


[0] https://gitlab.kitware.com/cmake/cmake/issues/18778

Regards

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Git rebase --exec cannot run git commands affecting other repos
  2019-01-10 16:19 Git rebase --exec cannot run git commands affecting other repos Samir Benmendil
@ 2019-01-10 18:26 ` Junio C Hamano
  2019-01-10 21:48   ` Samir Benmendil
  0 siblings, 1 reply; 4+ messages in thread
From: Junio C Hamano @ 2019-01-10 18:26 UTC (permalink / raw)
  To: Samir Benmendil; +Cc: git

Samir Benmendil <me@rmz.io> writes:

> It is impossible to run git commands affecting a different repo from
> within a `git rebase --exec` because in that environment the `GIT_DIR`
> and `GIT_WORK_TREE` variables are set and inherited by any commands
> run as part of `git rebase --exec`.

If the user wants to work in a different repository, the
environments that tells Git about the original repository can be
unset to do so, which is a very much deliberately designed
behaviour, primarily to help those who run "git rebase" from a
subdirectory of the project.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Git rebase --exec cannot run git commands affecting other repos
  2019-01-10 18:26 ` Junio C Hamano
@ 2019-01-10 21:48   ` Samir Benmendil
  2019-01-11 16:04     ` Jeff King
  0 siblings, 1 reply; 4+ messages in thread
From: Samir Benmendil @ 2019-01-10 21:48 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git

[-- Attachment #1: Type: text/plain, Size: 1973 bytes --]

On Jan 10, 2019 at 10:26, Junio C Hamano wrote:
> Samir Benmendil <me@rmz.io> writes:
> 
>> It is impossible to run git commands affecting a different repo from
>> within a `git rebase --exec` because in that environment the `GIT_DIR`
>> and `GIT_WORK_TREE` variables are set and inherited by any commands
>> run as part of `git rebase --exec`.
> 
> If the user wants to work in a different repository, the
> environments that tells Git about the original repository can be
> unset to do so, which is a very much deliberately designed
> behaviour, primarily to help those who run "git rebase" from a
> subdirectory of the project.

When run in a directory that does not have ".git" repository directory, 
Git tries to find such a directory in the parent directories to find the 
top of the working tree.

That should be the case as well for `git rebase`, is it not?


Rummaging through release notes to find out when this was added, I found 
the following in `RelNotes/2.19.0.txt`.

 * "git rebase" started exporting GIT_DIR environment variable and
   exposing it to hook scripts when part of it got rewritten in C.
   Instead of matching the old scripted Porcelains' behaviour,
   compensate by also exporting GIT_WORK_TREE environment as well to
   lessen the damage.  This can harm existing hooks that want to
   operate on different repository, but the current behaviour is
   already broken for them anyway.
   (merge ab5e67d751 bc/sequencer-export-work-tree-as-well later to maint).

To me it seems to be more of a regression introduced by porting rebase 
to C that was deemed to be acceptable at the time (only a few months 
ago).

I would argue that it is not.

The behaviour is also inconsistent with running these --exec commands 
from the command line while doing an interactive rebase, i.e. when 
changing one of the lines to "edit" and being dropped into the terminal 
for the edit, these env variables are not set.

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Git rebase --exec cannot run git commands affecting other repos
  2019-01-10 21:48   ` Samir Benmendil
@ 2019-01-11 16:04     ` Jeff King
  0 siblings, 0 replies; 4+ messages in thread
From: Jeff King @ 2019-01-11 16:04 UTC (permalink / raw)
  To: Samir Benmendil; +Cc: Junio C Hamano, git

On Thu, Jan 10, 2019 at 09:48:42PM +0000, Samir Benmendil wrote:

> > If the user wants to work in a different repository, the
> > environments that tells Git about the original repository can be
> > unset to do so, which is a very much deliberately designed
> > behaviour, primarily to help those who run "git rebase" from a
> > subdirectory of the project.
> 
> When run in a directory that does not have ".git" repository directory, Git
> tries to find such a directory in the parent directories to find the top of
> the working tree.
> 
> That should be the case as well for `git rebase`, is it not?

Generally yes. But ".git" does not necessarily have to be connected. For
example, try this:

  # a separate worktree and repo
  mkdir worktree
  git init --bare repo.git
  git -C repo.git config core.bare false
  git -C repo.git config core.worktree "$PWD/worktree"

  # an unrelated repo we'll try to access
  git init unrelated

  # operate in the separated repo using $GIT_DIR to point to the repo
  export GIT_DIR=$PWD/repo.git
  cd worktree

  # rebase that tries to operate in another repository
  echo content >file
  git add file
  git commit -m file
  git rebase --root -x 'cd ../unrelated && git rev-parse --git-dir'

And in fact, this case behaves the same now or with older versions of
Git (because GIT_DIR would be set either way). Likewise the less exotic
"git --git-dir=something rebase", which would set GIT_DIR in the
environment. I think there are other cases, too, where we'd internally
set GIT_DIR during repo discovery, but I don't remember all of them
offhand.

So I think the reasoning at the time was along the lines of "scripts
already should not be relying on the absence of $GIT_DIR". That said, I
do think there's an argument to be made that it generally worked before
in many common setups, even if it was not bulletproof.

And I am not sure I could construct a case where setting $GIT_DIR when
it was not already set explicitly _helps_ the "exec" command (because
if searching from the working tree does not work, then the caller of
"git rebase" would had to have set $GIT_DIR itself).

-Peff

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-01-11 16:04 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-10 16:19 Git rebase --exec cannot run git commands affecting other repos Samir Benmendil
2019-01-10 18:26 ` Junio C Hamano
2019-01-10 21:48   ` Samir Benmendil
2019-01-11 16:04     ` Jeff King

Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).