git: Fix submodule names issue (#2274)

GitPython creates submodules nodes during tree iterate without explicit
passing name attribute. This path replaces such submodules with new
instances with filled name attribute.

Fixes: #1898
This commit is contained in:
Georgy Dyuldin
2019-07-16 16:38:42 +03:00
committed by Ruslan Kuprieiev
parent db19957b8a
commit 840318dd22
2 changed files with 34 additions and 9 deletions
+17 -2
View File
@@ -13,6 +13,21 @@ GIT_MODE_DIR = 0o40000
GIT_MODE_FILE = 0o644
def _iter_tree(tree):
# During usual tree iteration with ``for .. in ..`` GitPython returns each
# submodule instance without correctly filled ``name`` property. It raises
# an exception during accessing such submodule ``name`` later.
# The same time repo's submodules property contains correctly initialized
# submodules list.
# Here we just replace submodule instance from iterator with the
# corresponding instance from ``repo.submodules.``
submodules = {x.hexsha: x for x in tree.repo.submodules}
for node in tree:
if node.type == "submodule":
node = submodules[node.hexsha]
yield node
class GitTree(BaseTree):
"""Proxies the repo file access methods to Git objects"""
@@ -72,7 +87,7 @@ class GitTree(BaseTree):
return False
# see https://github.com/gitpython-developers/GitPython/issues/851
# `return (i in tree)` doesn't work so here is a workaround:
for i in obj:
for i in _iter_tree(obj):
if i.name == path:
return True
return False
@@ -104,7 +119,7 @@ class GitTree(BaseTree):
def _walk(self, tree, topdown=True):
dirs, nondirs = [], []
for i in tree:
for i in _iter_tree(tree):
if i.mode == GIT_MODE_DIR:
dirs.append(i.name)
else:
+17 -7
View File
@@ -9,7 +9,7 @@ from dvc.scm import SCM
from dvc.scm.git import GitTree
from dvc.scm.tree import WorkingTree
from tests.basic_env import TestDir, TestGit
from tests.basic_env import TestDir, TestGit, TestGitSubmodule
class TestWorkingTree(TestDir):
@@ -39,12 +39,7 @@ class TestWorkingTree(TestDir):
self.assertFalse(self.tree.isfile("not-existing-file"))
class TestGitTree(TestGit):
def setUp(self):
super(TestGitTree, self).setUp()
self.scm = SCM(self._root_dir)
self.tree = GitTree(self.git, "master")
class GitTreeTests(object):
def test_open(self):
self.scm.add([self.FOO, self.UNICODE, self.DATA_DIR])
self.scm.commit("add")
@@ -83,6 +78,21 @@ class TestGitTree(TestGit):
self.assertFalse(self.tree.isfile("not-existing-file"))
class TestGitTree(TestGit, GitTreeTests):
def setUp(self):
super(TestGitTree, self).setUp()
self.scm = SCM(self._root_dir)
self.tree = GitTree(self.git, "master")
class TestGitSubmoduleTree(TestGitSubmodule, GitTreeTests):
def setUp(self):
super(TestGitSubmoduleTree, self).setUp()
self.scm = SCM(self._root_dir)
self.tree = GitTree(self.git, "master")
self._pushd(self._root_dir)
class AssertWalkEqualMixin(object):
def assertWalkEqual(self, actual, expected, msg=None):
def convert_to_sets(walk_results):