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:
Paul Barker 2020-06-15 17:59:51 +02:00 committed by Jan Kiszka
parent a5dc5f8663
commit b998dfa722

View File

@ -229,16 +229,16 @@ class RepoImpl(Repo):
logging.warning('Repo %s is dirty - no checkout', self.name)
return
# Check if current HEAD is what in the config file is defined.
(_, output) = run_cmd(self.current_rev_cmd(),
(_, output) = run_cmd(self.resolve_branch_cmd(),
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:
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)
run_cmd(self.checkout_cmd(desired_ref, branch), cwd=self.path)
async def apply_patches_async(self):
"""
@ -351,12 +351,15 @@ class GitRepo(RepoImpl):
def is_dirty_cmd(self):
return ['git', 'status', '-s']
def current_rev_cmd(self):
return ['git', 'rev-parse', '--verify', 'HEAD']
def resolve_branch_cmd(self):
return ['git', 'rev-parse', '--verify', '-q',
'origin/{refspec}'.format(refspec=self.refspec)]
def checkout_cmd(self):
return ['git', 'checkout', '-q',
'{refspec}'.format(refspec=self.refspec)]
def checkout_cmd(self, desired_ref, branch):
cmd = ['git', 'checkout', '-q', desired_ref]
if branch:
cmd.extend(['-B', self.refspec])
return cmd
def prepare_patches_cmd(self):
return ['git', 'checkout', '-q', '-B',
@ -392,11 +395,12 @@ class MercurialRepo(RepoImpl):
def is_dirty_cmd(self):
return ['hg', 'diff']
def current_rev_cmd(self):
return ['hg', 'identify', '-i', '--debug']
def resolve_branch_cmd(self):
# We never need to care about creating tracking branches in mercurial
return ['false']
def checkout_cmd(self):
return ['hg', 'checkout', '{refspec}'.format(refspec=self.refspec)]
def checkout_cmd(self, desired_ref, branch):
return ['hg', 'checkout', desired_ref]
def prepare_patches_cmd(self):
return ['hg', 'branch', '-f',