repos: Make tracking branch resolution more robust
If refspec is a branch name, ensure that the local branch name is always set to the refspec. In the opposite case when refspec is a commit hash, ensure that for git repositories we always end up in the 'detached HEAD' state. It's also cheaper and simpler to always run `git checkout` or `hg checkout` than it is to test if a checkout is actually needed. If the desired refspec is already checked out then these commands are no-ops. Signed-off-by: Paul Barker <pbarker@konsulko.com> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
This commit is contained in:
		
							
								
								
									
										38
									
								
								kas/repos.py
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								kas/repos.py
									
									
									
									
									
								
							@@ -229,16 +229,16 @@ class RepoImpl(Repo):
 | 
				
			|||||||
            logging.warning('Repo %s is dirty - no checkout', self.name)
 | 
					            logging.warning('Repo %s is dirty - no checkout', self.name)
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Check if current HEAD is what in the config file is defined.
 | 
					        (_, output) = run_cmd(self.resolve_branch_cmd(),
 | 
				
			||||||
        (_, output) = run_cmd(self.current_rev_cmd(),
 | 
					 | 
				
			||||||
                              cwd=self.path, fail=False)
 | 
					                              cwd=self.path, fail=False)
 | 
				
			||||||
 | 
					        if output:
 | 
				
			||||||
 | 
					            desired_ref = output.strip()
 | 
				
			||||||
 | 
					            branch = True
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            desired_ref = self.refspec
 | 
				
			||||||
 | 
					            branch = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if output and output.strip() == self.refspec:
 | 
					        run_cmd(self.checkout_cmd(desired_ref, branch), cwd=self.path)
 | 
				
			||||||
            logging.info('Repo %s has already been checked out with correct '
 | 
					 | 
				
			||||||
                         'refspec. Nothing to do.', self.name)
 | 
					 | 
				
			||||||
            return
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        run_cmd(self.checkout_cmd(), cwd=self.path)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def apply_patches_async(self):
 | 
					    async def apply_patches_async(self):
 | 
				
			||||||
        """
 | 
					        """
 | 
				
			||||||
@@ -351,12 +351,15 @@ class GitRepo(RepoImpl):
 | 
				
			|||||||
    def is_dirty_cmd(self):
 | 
					    def is_dirty_cmd(self):
 | 
				
			||||||
        return ['git', 'status', '-s']
 | 
					        return ['git', 'status', '-s']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def current_rev_cmd(self):
 | 
					    def resolve_branch_cmd(self):
 | 
				
			||||||
        return ['git', 'rev-parse', '--verify', 'HEAD']
 | 
					        return ['git', 'rev-parse', '--verify', '-q',
 | 
				
			||||||
 | 
					                'origin/{refspec}'.format(refspec=self.refspec)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def checkout_cmd(self):
 | 
					    def checkout_cmd(self, desired_ref, branch):
 | 
				
			||||||
        return ['git', 'checkout', '-q',
 | 
					        cmd = ['git', 'checkout', '-q', desired_ref]
 | 
				
			||||||
                '{refspec}'.format(refspec=self.refspec)]
 | 
					        if branch:
 | 
				
			||||||
 | 
					            cmd.extend(['-B', self.refspec])
 | 
				
			||||||
 | 
					        return cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def prepare_patches_cmd(self):
 | 
					    def prepare_patches_cmd(self):
 | 
				
			||||||
        return ['git', 'checkout', '-q', '-B',
 | 
					        return ['git', 'checkout', '-q', '-B',
 | 
				
			||||||
@@ -392,11 +395,12 @@ class MercurialRepo(RepoImpl):
 | 
				
			|||||||
    def is_dirty_cmd(self):
 | 
					    def is_dirty_cmd(self):
 | 
				
			||||||
        return ['hg', 'diff']
 | 
					        return ['hg', 'diff']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def current_rev_cmd(self):
 | 
					    def resolve_branch_cmd(self):
 | 
				
			||||||
        return ['hg', 'identify', '-i', '--debug']
 | 
					        # We never need to care about creating tracking branches in mercurial
 | 
				
			||||||
 | 
					        return ['false']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def checkout_cmd(self):
 | 
					    def checkout_cmd(self, desired_ref, branch):
 | 
				
			||||||
        return ['hg', 'checkout', '{refspec}'.format(refspec=self.refspec)]
 | 
					        return ['hg', 'checkout', desired_ref]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def prepare_patches_cmd(self):
 | 
					    def prepare_patches_cmd(self):
 | 
				
			||||||
        return ['hg', 'branch', '-f',
 | 
					        return ['hg', 'branch', '-f',
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user