-
Notifications
You must be signed in to change notification settings - Fork 1.3k
erepo: cache all read only external repos by hexsha #3286
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,14 +8,9 @@ | |
|
|
||
| from dvc.exceptions import GitHookAlreadyExistsError | ||
| from dvc.scm.base import Base | ||
| from dvc.scm.base import CloneError | ||
| from dvc.scm.base import FileNotInRepoError | ||
| from dvc.scm.base import RevError | ||
| from dvc.scm.base import SCMError | ||
| from dvc.scm.base import CloneError, FileNotInRepoError, RevError, SCMError | ||
| from dvc.scm.git.tree import GitTree | ||
| from dvc.utils import fix_env | ||
| from dvc.utils import is_binary | ||
| from dvc.utils import relpath | ||
| from dvc.utils import fix_env, is_binary, relpath | ||
| from dvc.utils.fs import path_isin | ||
|
|
||
| logger = logging.getLogger(__name__) | ||
|
|
@@ -94,6 +89,12 @@ def clone(url, to_path, rev=None): | |
|
|
||
| return repo | ||
|
|
||
| @staticmethod | ||
| def is_sha(rev): | ||
| import git | ||
|
|
||
| return rev and git.Repo.re_hexsha_shortened.search(rev) | ||
|
|
||
| @staticmethod | ||
| def is_repo(root_dir): | ||
| return os.path.isdir(Git._get_git_dir(root_dir)) | ||
|
|
@@ -211,14 +212,16 @@ def checkout(self, branch, create_new=False): | |
| self.repo.git.checkout(branch) | ||
|
|
||
| def pull(self): | ||
| info, = self.repo.remote().pull() | ||
| if info.flags & info.ERROR: | ||
| raise SCMError("pull failed: {}".format(info.note)) | ||
| infos = self.repo.remote().pull() | ||
| for info in infos: | ||
| if info.flags & info.ERROR: | ||
| raise SCMError("pull failed: {}".format(info.note)) | ||
|
|
||
| def push(self): | ||
| info, = self.repo.remote().push() | ||
| if info.flags & info.ERROR: | ||
| raise SCMError("push failed: {}".format(info.summary)) | ||
| infos = self.repo.remote().push() | ||
| for info in infos: | ||
| if info.flags & info.ERROR: | ||
| raise SCMError("push failed: {}".format(info.summary)) | ||
|
|
||
| def branch(self, branch): | ||
| self.repo.git.branch(branch) | ||
|
|
@@ -324,15 +327,45 @@ def get_tree(self, rev): | |
| return GitTree(self.repo, self.resolve_rev(rev)) | ||
|
|
||
| def get_rev(self): | ||
| return self.repo.git.rev_parse("HEAD") | ||
| return self.repo.rev_parse("HEAD").hexsha | ||
|
|
||
| def resolve_rev(self, rev): | ||
| from git.exc import GitCommandError | ||
|
|
||
| from git.exc import BadName, GitCommandError | ||
| from contextlib import suppress | ||
|
|
||
| def _resolve_rev(name): | ||
| with suppress(BadName, GitCommandError): | ||
| try: | ||
| # Try python implementation of rev-parse first, it's faster | ||
| return self.repo.rev_parse(name).hexsha | ||
| except NotImplementedError: | ||
|
||
| # Fall back to `git rev-parse` for advanced features | ||
| return self.repo.git.rev_parse(name) | ||
|
|
||
| # Resolve across local names | ||
| sha = _resolve_rev(rev) | ||
| if sha: | ||
| return sha | ||
|
|
||
| # Try all the remotes and if it resolves unambiguously then take it | ||
| if not Git.is_sha(rev): | ||
| shas = { | ||
| _resolve_rev("{}/{}".format(remote.name, rev)) | ||
| for remote in self.repo.remotes | ||
| } - {None} | ||
| if len(shas) > 1: | ||
| raise RevError("ambiguous Git revision '{}'".format(rev)) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IIRC git choses the ref-like rev if it can, even in ambigous case. It does print a warning though. Not sure if it matters that much here. |
||
| if len(shas) == 1: | ||
| return shas.pop() | ||
|
|
||
| raise RevError("unknown Git revision '{}'".format(rev)) | ||
|
|
||
| def has_rev(self, rev): | ||
| try: | ||
| return self.repo.git.rev_parse(rev) | ||
| except GitCommandError: | ||
| raise RevError("unknown Git revision '{}'".format(rev)) | ||
| self.resolve_rev(rev) | ||
| return True | ||
| except RevError: | ||
| return False | ||
|
|
||
| def close(self): | ||
| self.repo.close() | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.