Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions git/repo/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,28 @@ def __init__(
# It's important to normalize the paths, as submodules will otherwise
# initialize their repo instances with paths that depend on path-portions
# that will not exist after being removed. It's just cleaner.
if (
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems the comment above this hunk was actually meant for the block below it. So that should be changed. I also think the code block can use some documentation on what it's trying to do.

osp.isfile(osp.join(curpath, "gitdir"))
and osp.isfile(osp.join(curpath, "commondir"))
and osp.isfile(osp.join(curpath, "HEAD"))
):
git_dir = curpath

if "GIT_WORK_TREE" in os.environ:
self._working_tree_dir = os.getenv("GIT_WORK_TREE")
Comment on lines +252 to +253
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The _working_tree_dir probably starts out as None, and should be set by whatever has the final say, probably the environment variable.
Then if it's not yet set, all this extra work can be done to figure out the worktree dir.

else:
# Linked worktree administrative directories store the path to the
# worktree's .git file in their gitdir file (without "gitdir: " prefix).
with open(osp.join(git_dir, "gitdir")) as fp:
worktree_gitfile = fp.read().strip()

if not osp.isabs(worktree_gitfile):
worktree_gitfile = osp.normpath(osp.join(git_dir, worktree_gitfile))

self._working_tree_dir = osp.dirname(worktree_gitfile)

break

if is_git_dir(curpath):
git_dir = curpath
# from man git-config : core.worktree
Expand Down
31 changes: 31 additions & 0 deletions test/test_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -1126,6 +1126,37 @@ def test_git_work_tree_env(self, rw_dir):
self.assertEqual(r.working_tree_dir, repo_dir)
self.assertEqual(r.working_dir, repo_dir)

@with_rw_directory
def test_git_work_tree_env_in_linked_worktree(self, rw_dir):
"""Check that Repo() autodiscovers a linked worktree when GIT_DIR is set."""
git = Git(rw_dir)
if git.version_info[:3] < (2, 5, 1):
raise RuntimeError("worktree feature unsupported (test needs git 2.5.1 or later)")

rw_master = self.rorepo.clone(join_path_native(rw_dir, "master_repo"))
branch = rw_master.create_head("bbbbbbbb")
worktree_path = join_path_native(rw_dir, "worktree_repo")
if Git.is_cygwin():
worktree_path = cygpath(worktree_path)

rw_master.git.worktree("add", worktree_path, branch.name)

git_dir = Git(worktree_path).rev_parse("--git-dir")

with mock.patch.dict(os.environ, {"GIT_DIR": git_dir}, clear=False):
old_cwd = os.getcwd()
try:
os.chdir(worktree_path)

explicit = Repo(os.getcwd())
autodiscovered = Repo()

self.assertTrue(osp.samefile(explicit.working_tree_dir, worktree_path))
self.assertTrue(osp.samefile(autodiscovered.working_tree_dir, worktree_path))
self.assertTrue(osp.samefile(autodiscovered.working_tree_dir, explicit.working_tree_dir))
finally:
os.chdir(old_cwd)

@with_rw_directory
def test_rebasing(self, rw_dir):
r = Repo.init(rw_dir)
Expand Down
Loading