Enable gerrit/gitlab/github refspecs
By default git only fetches references under the refs/heads/ tree, this patch adds support to kas to enable you to specify references outside of the ref/heads tree. This is useful as it allows you to use uncommitted gerrit patchsets, Gitlab merge requests or github pull requests that live under refs/changes/, refs/merge-requests and refs/pull as the reference for a repo allowing the use of in development changes. When a refsepc is defined that starts with refs/ an additional git fetch operation is preformed on the repo to explicitly fetch the reference given so it can be checked out for use. Signed-off-by: Drew Reed <drew.reed@arm.com> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
parent
635b1023a1
commit
6b65de3e2f
26
kas/repos.py
26
kas/repos.py
@ -179,6 +179,7 @@ class RepoImpl(Repo):
|
|||||||
cwd=get_context().kas_work_dir)
|
cwd=get_context().kas_work_dir)
|
||||||
if retc == 0:
|
if retc == 0:
|
||||||
logging.info('Repository %s cloned', self.name)
|
logging.info('Repository %s cloned', self.name)
|
||||||
|
if not self.refspec.startswith('refs/'):
|
||||||
return retc
|
return retc
|
||||||
|
|
||||||
# Make sure the remote origin is set to the value
|
# Make sure the remote origin is set to the value
|
||||||
@ -336,6 +337,10 @@ class GitRepo(RepoImpl):
|
|||||||
Provides the git functionality for a Repo.
|
Provides the git functionality for a Repo.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def remove_ref_prefix(self, refspec):
|
||||||
|
ref_prefix = 'refs/'
|
||||||
|
return refspec[refspec.startswith(ref_prefix) and len(ref_prefix):]
|
||||||
|
|
||||||
def add_cmd(self):
|
def add_cmd(self):
|
||||||
return ['git', 'add', '-A']
|
return ['git', 'add', '-A']
|
||||||
|
|
||||||
@ -350,29 +355,38 @@ class GitRepo(RepoImpl):
|
|||||||
'-m', 'msg']
|
'-m', 'msg']
|
||||||
|
|
||||||
def contains_refspec_cmd(self):
|
def contains_refspec_cmd(self):
|
||||||
return ['git', 'cat-file', '-t', self.refspec]
|
return ['git', 'cat-file', '-t', self.remove_ref_prefix(self.refspec)]
|
||||||
|
|
||||||
def fetch_cmd(self):
|
def fetch_cmd(self):
|
||||||
return ['git', 'fetch']
|
cmd = ['git', 'fetch']
|
||||||
|
if self.refspec.startswith('refs/'):
|
||||||
|
cmd.extend(['--quiet', 'origin',
|
||||||
|
'+' + self.refspec
|
||||||
|
+ ':refs/remotes/origin/'
|
||||||
|
+ self.remove_ref_prefix(self.refspec)])
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
|
||||||
def is_dirty_cmd(self):
|
def is_dirty_cmd(self):
|
||||||
return ['git', 'status', '-s']
|
return ['git', 'status', '-s']
|
||||||
|
|
||||||
def resolve_branch_cmd(self):
|
def resolve_branch_cmd(self):
|
||||||
return ['git', 'rev-parse', '--verify', '-q',
|
return ['git', 'rev-parse', '--verify', '-q',
|
||||||
'origin/{refspec}'.format(refspec=self.refspec)]
|
'origin/{refspec}'.
|
||||||
|
format(refspec=self.remove_ref_prefix(self.refspec))]
|
||||||
|
|
||||||
def checkout_cmd(self, desired_ref, branch):
|
def checkout_cmd(self, desired_ref, branch):
|
||||||
cmd = ['git', 'checkout', '-q', desired_ref]
|
cmd = ['git', 'checkout', '-q', self.remove_ref_prefix(desired_ref)]
|
||||||
if branch:
|
if branch:
|
||||||
cmd.extend(['-B', self.refspec])
|
cmd.extend(['-B', self.remove_ref_prefix(self.refspec)])
|
||||||
if get_context().force_checkout:
|
if get_context().force_checkout:
|
||||||
cmd.append('--force')
|
cmd.append('--force')
|
||||||
return cmd
|
return cmd
|
||||||
|
|
||||||
def prepare_patches_cmd(self):
|
def prepare_patches_cmd(self):
|
||||||
return ['git', 'checkout', '-q', '-B',
|
return ['git', 'checkout', '-q', '-B',
|
||||||
'patched-{refspec}'.format(refspec=self.refspec)]
|
'patched-{refspec}'.
|
||||||
|
format(refspec=self.remove_ref_prefix(self.refspec))]
|
||||||
|
|
||||||
def apply_patches_file_cmd(self, path):
|
def apply_patches_file_cmd(self, path):
|
||||||
return ['git', 'apply', path]
|
return ['git', 'apply', path]
|
||||||
|
@ -63,3 +63,27 @@ def test_refspec_switch(changedir, tmpdir):
|
|||||||
fail=False, liveupdate=False)
|
fail=False, liveupdate=False)
|
||||||
assert rc == 0
|
assert rc == 0
|
||||||
assert output.strip() == '907816a5c4094b59a36aec12226e71c461c05b77'
|
assert output.strip() == '907816a5c4094b59a36aec12226e71c461c05b77'
|
||||||
|
|
||||||
|
|
||||||
|
def test_refspec_absolute(changedir, tmpdir):
|
||||||
|
"""
|
||||||
|
Test that the local git clone works when a absolute refspec
|
||||||
|
is givvn.
|
||||||
|
"""
|
||||||
|
tdir = str(tmpdir.mkdir('test_refspec_absolute'))
|
||||||
|
shutil.rmtree(tdir, ignore_errors=True)
|
||||||
|
shutil.copytree('tests/test_refspec', tdir)
|
||||||
|
os.chdir(tdir)
|
||||||
|
|
||||||
|
kas.kas(['shell', 'test3.yml', '-c', 'true'])
|
||||||
|
(rc, output) = run_cmd(['git', 'symbolic-ref', '-q', 'HEAD'],
|
||||||
|
cwd='kas_abs', fail=False, liveupdate=False)
|
||||||
|
assert rc != 0
|
||||||
|
assert output.strip() == ''
|
||||||
|
(rc, output_kas_abs) = run_cmd(['git', 'rev-parse', 'HEAD'],
|
||||||
|
cwd='kas_abs', fail=False, liveupdate=False)
|
||||||
|
assert rc == 0
|
||||||
|
(rc, output_kas_rel) = run_cmd(['git', 'rev-parse', 'HEAD'],
|
||||||
|
cwd='kas_rel', fail=False, liveupdate=False)
|
||||||
|
assert rc == 0
|
||||||
|
assert output_kas_abs.strip() == output_kas_rel.strip()
|
||||||
|
13
tests/test_refspec/test3.yml
Normal file
13
tests/test_refspec/test3.yml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
header:
|
||||||
|
version: 8
|
||||||
|
|
||||||
|
repos:
|
||||||
|
this:
|
||||||
|
|
||||||
|
kas_abs:
|
||||||
|
url: https://github.com/siemens/kas.git
|
||||||
|
refspec: refs/heads/master
|
||||||
|
|
||||||
|
kas_rel:
|
||||||
|
url: https://github.com/siemens/kas.git
|
||||||
|
refspec: master
|
Loading…
Reference in New Issue
Block a user