mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-02 07:18:25 +01:00
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:
committed by
Ruslan Kuprieiev
parent
db19957b8a
commit
840318dd22
+17
-2
@@ -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
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user