Skip to content

Repo() fails in Git Worktree when GIT_DIR environment variable is set #2022

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

Open
Leokap opened this issue Apr 8, 2025 · 2 comments
Open

Comments

@Leokap
Copy link

Leokap commented Apr 8, 2025

The git.Repo() constructor in GitPython fails to correctly initialize a repository when called without a path from within a Git worktree and the GIT_DIR environment variable is set to that worktree. This variable is often automatically set by Git when executing an alias to point to the current repo or worktree git_dir. While Repo(os.getcwd()) finds the worktree correctly, calling Repo() with GIT_DIR set to Repo(os.getcwd()).git_dir raises an InvalidGitRepositoryError.

Minimal Reproducing Example:

  1. Set up a main Git repository:

    mkdir main_repo
    cd main_repo
    git init
    touch initial_file.txt
    git add initial_file.txt
    git commit -m "Initial commit"
  2. Create a Git worktree:

    git worktree add worktree_a
    cd worktree_a
  3. Create a simple Python script (e.g., test_repo.py) to initialize a Repo object:

import os
from git import Repo, InvalidGitRepositoryError

print(f"Current working directory: {os.getcwd()}")
print(f"GIT_DIR environment variable: {os.getenv('GIT_DIR')}")

try:
    repo = Repo()
    print(f"Repo initialized successfully: {repo.working_dir}")
except InvalidGitRepositoryError as e:
    print(f"Error initializing Repo(): {e}")

try:
    repo_with_cwd = Repo(os.getcwd())
    print(f"Repo initialized with cwd successfully: {repo_with_cwd.working_dir}")
    print(f"Repo(os.getcwd()).git_dir: {Repo(os.getcwd()).git_dir}")
except InvalidGitRepositoryError as e:
    print(f"Error initializing Repo(os.getcwd()): {e}")
  1. Create a Git alias to run the Python script (e.g., in .git/config or using git config --local alias.test-repo '!python /path/to/test_repo.py'):

    Replace /path/to/test_repo.py with the actual path to your script.

  2. Run the Git alias from within the worktree:

    git test-repo

Expected Behavior:

Repo() should successfully initialize the repository, recognizing the worktree's context and linking back to the main repository's .git directory.

Observed Behavior:

Raises an InvalidGitRepositoryError when Repo() is called without a path, while Repo(os.getcwd()) succeeds. The output will also show that the GIT_DIR environment variable is set within the worktree's context.

Additional Information:

  • GitPython Version: 3.1.44
  • Python Version: 3.10.14
  • Operating System: Linux

Maybe one should also check if such happens for submodules since they also have the repo dir in a different place than the normal .git dir.

Workaround:

Explicitly passing os.getcwd() to the Repo() constructor or unsetting the GIT_DIR environment variable before calling Repo() seems to work.

@Byron
Copy link
Member

Byron commented Apr 8, 2025

Thanks a lot!

There are probably a lot of subtleties around 'active' Git environment variables and GitPython or Git not doing the right thing.

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

No branches or pull requests

3 participants
@Byron @Leokap and others