Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gpg wrapper fails in git worktree #87

Open
laanwj opened this issue May 17, 2018 · 6 comments
Open

gpg wrapper fails in git worktree #87

laanwj opened this issue May 17, 2018 · 6 comments

Comments

@laanwj
Copy link

laanwj commented May 17, 2018

When using the gpg wrapper in a git worktree (out-of-tree checkout), the following error happens when signing:

Traceback (most recent call last):
  File "/.../.local/bin/ots-git-gpg-wrapper", line 11, in <module>
    sys.exit(main())
  File "/.../.local/lib/python3.5/site-packages/otsclient/git_gpg_wrapper.py", line 115, in main
    repo = git.Repo()
  File "/.../.local/lib/python3.5/site-packages/git/repo/base.py", line 161, in __init__
    raise InvalidGitRepositoryError(epath)
git.exc.InvalidGitRepositoryError: /.../projects/bitcoin/bitcoin/.git/worktrees/bitcoin-0.16

I think this is a problem with the upstream git python module.

@laanwj
Copy link
Author

laanwj commented May 17, 2018

The issue seems to be due to buggy handling of the GITDIR environment variable in gitpython.

The funny thing is that git.Repo() works fine in a worktree outside of the tool. It correctly detects that the repository in the current directory is a worktree and sets the path accordingly

/.../bitcoin/bitcoin-0.16$ python3
>>> import git
>>> git.Repo()
<git.Repo "/.../bitcoin/.git/worktrees/bitcoin-0.16">
>>> git.Repo('/.../bitcoin/bitcoin-0.16')
<git.Repo "/.../bitcoin/.git/worktrees/bitcoin-0.16">
>>> git.Repo('/.../bitcoin/.git/worktrees/bitcoin-0.16')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/.../.local/lib/python3.5/site-packages/git/repo/base.py", line 169, in __init__
    raise InvalidGitRepositoryError(epath)
git.exc.InvalidGitRepositoryError: /.../bitcoin/.git/worktrees/bitcoin-0.16

However, it looks like that when calling the gpg program, git itself (I think) has set GIT_DIR not to the current directory, but to the worktree link (/.../bitcoin/.git/worktrees/bitcoin-0.16 in this case).
git.Repo() picks this up as argument, and somehow fails to grasp what kind of directory it is.

Edit: Okay, apparently worktrees are explicitly unsupported upstream, that's interesting gitpython-developers/GitPython#344

@petertodd
Copy link
Member

Bah:

As GitPython is in maintenance mode, I won't be adding any new features.

I wonder if there's an alternative we could use instead? Worktrees are a cool and useful feature.

@laanwj
Copy link
Author

laanwj commented May 24, 2018

I wonder, too. Haven't looked yet into how much work it would be to add worktree support, or whether there are alternatives to GitPython that do.

Or whether it's possible to temporarily work around this at the opentimestamps-client side - it doesn't sound to difficult to find the original git directory then use that - would just have to be careful with 'current branch'.

I use worktrees for building and merging into version branches. So for the last few merges on 0.16 I had to disable the wrapper. Which is pretty lousy. For signing the v0.16.1 tag I'm going to do a full clone.

@petertodd
Copy link
Member

petertodd commented May 24, 2018

Heh, looks like Rust's git2 crate has worktree support, so maybe I can just rewrite it all in rust. :)

The git commit signing code shouldn't care about what branch it is, so all we really have to do is have a hack to figure out where the git directory is. Specifically, that hack would need to be added to

git.Repo() takes an optional directory argument, so it might be enough to just attempt to find the .git ourselves; in the case of a worktree, .git is a file:

gitdir: /tmp/opentimestamps-client/.git/worktrees/ots-0.3.2

and in that directory there's another file, gitdir, which contains the actual path for .git:

$ cat gitdir 
/tmp/ots-0.3.2/.git

@laanwj
Copy link
Author

laanwj commented Oct 31, 2019

Apparently this was fixed upstream for a while,
gitpython-developers/GitPython#894
then reverted later due to performance regression
gitpython-developers/GitPython#719

@real-or-random
Copy link

The simplest way to get the real directory seems to be git rev-parse --git-path config (and then strip the trailing config).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants