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:
		
							
								
								
									
										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
 | 
				
			||||||
		Reference in New Issue
	
	Block a user