From 32fa8e33c4357040554dc515d16426bc8f6bde29 Mon Sep 17 00:00:00 2001 From: Ruslan Kuprieiev Date: Fri, 30 Oct 2020 01:01:58 +0200 Subject: [PATCH] git: use dulwich for .gitignore (#4809) In my tests `Git._ignore` is taking around ~65seconds for the whole test suit(~50K invocations). The reason is that `gitpython` is launching a real `git check-ignore` process, that takes time and resources. Switching to `pygit2` or `dulwich` makes it drop to ~5seconds, saving us almost a minute of the test run time and a lot of resources by not launching any processes. I've chosen `dulwich` over `pygit2` here because it is much more pythonic and as long as the performance is on-par with `pygit2` it is better for us to use `dulwich`. --- dvc/scm/git.py | 11 +++++------ setup.py | 1 + 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dvc/scm/git.py b/dvc/scm/git.py index 22318d781..5b3965f15 100644 --- a/dvc/scm/git.py +++ b/dvc/scm/git.py @@ -183,13 +183,12 @@ class Git(Base): return entry, gitignore def _ignored(self, path): - from git.exc import GitCommandError + from dulwich import ignore + from dulwich.repo import Repo - try: - self.repo.git.check_ignore(path) - return True - except GitCommandError: - return False + repo = Repo(self.root_dir) + manager = ignore.IgnoreFilterManager.from_repo(repo) + return manager.is_ignored(relpath(path, self.root_dir)) def ignore(self, path): entry, gitignore = self._get_gitignore(path) diff --git a/setup.py b/setup.py index 083b7c11e..7087a7e5f 100644 --- a/setup.py +++ b/setup.py @@ -50,6 +50,7 @@ install_requires = [ "colorama>=0.3.9", "configobj>=5.0.6", "gitpython>3", + "dulwich>=0.20.6", "setuptools>=34.0.0", "nanotime>=0.5.2", "pyasn1>=0.4.1",