>From 986114bf211d5f4ce1d53cd054119cf035154324 Mon Sep 17 00:00:00 2001 From: Richard Dale Date: Fri, 8 Jun 2018 11:06:12 +0100 Subject: [PATCH] Add support for Git LFS repositories Use 'git lfs ls-files ' to determine whether or not there are any files under lfs control in the target branch. If there are files stored in git lfs, then change the origin URL to be the upstream one, rather than the local cached bare repo. This approach works, but it would be better to leave the origin URL, and instead add an .lfsconfig file that points to the lfs object store. However, I couldn't find a way of doing this without get a user/password prompt from git. --- buildstream/plugins/sources/git.py | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/buildstream/plugins/sources/git.py b/buildstream/plugins/sources/git.py index d079d87..06d6517 100644 --- a/buildstream/plugins/sources/git.py +++ b/buildstream/plugins/sources/git.py @@ -82,6 +82,7 @@ from buildstream import Source, SourceError, Consistency from buildstream import utils GIT_MODULES = '.gitmodules' +GIT_ATTRIBUTES = '.gitattributes' # Because of handling of submodules, we maintain a GitMirror @@ -138,6 +139,12 @@ class GitMirror(): rc = self.source.call([self.source.host_git, 'cat-file', '-t', self.ref], cwd=self.mirror) return rc == 0 + def ref_expects_lfs(self): + if not self.has_ref(): + return False + exit_code, files = self.source.check_output([self.source.host_git, 'lfs', 'ls-files', self.ref], cwd=self.mirror) + return exit_code == 0 and len(files) > 0 + def assert_ref(self): if not self.has_ref(): raise SourceError("{}: expected ref '{}' was not found in git repository: '{}'" @@ -159,6 +166,12 @@ class GitMirror(): self.source.call([self.source.host_git, 'clone', '--no-checkout', '--no-hardlinks', self.mirror, fullpath], fail="Failed to create git mirror {} in directory: {}".format(self.mirror, fullpath)) + expects_lfs = self.ref_expects_lfs(); + if expects_lfs: + self.source.warn("{}: ref expects lfs '{}'" + .format(self.source, self.ref)) + self.set_origin_url(directory) + self.source.call([self.source.host_git, 'checkout', '--force', self.ref], fail="Failed to checkout git ref {}".format(self.ref), cwd=fullpath) @@ -241,6 +254,14 @@ class GitMirror(): return None + def set_origin_url(self, directory): + fullpath = os.path.join(directory, self.path) + _, origin_url = self.source.check_output([self.source.host_git, 'config', '--get', 'remote.origin.url'], + fail='Failed to get origin url "{}"'.format(self.mirror), + cwd=self.mirror) + self.source.call([self.source.host_git, 'config', 'remote.origin.url', origin_url], + fail="Failed to set origin url {}".format(origin_url), + cwd=fullpath) class GitSource(Source): # pylint: disable=attribute-defined-outside-init @@ -432,7 +453,6 @@ class GitSource(Source): mirror.fetch() mirror.assert_ref() - # Plugin entry point def setup(): return GitSource -- 2.7.4