From 5ceac3789094f70b45cc837ed7d4e85bc323731d Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sun, 30 Oct 2011 14:25:43 +0100 Subject: GitRepository: Use update-ref to force a branch's head in bare repos --- gbp/git.py | 44 ++++++++++++++++++++++++++++++++++++++------ tests/test_GitRepository.py | 8 ++++++++ 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/gbp/git.py b/gbp/git.py index ce4d133..6bb6b8b 100644 --- a/gbp/git.py +++ b/gbp/git.py @@ -79,6 +79,32 @@ class GitModifier(object): return self._get_env('committer') +class GitCommit(object): + """A git commit""" + sha1_re = re.compile(r'[0-9a-f]{40}$') + + @staticmethod + def is_sha1(value): + """ + Is I{value} a valid 40 digit SHA1? + + >>> GitCommit.is_sha1('asdf') + False + >>> GitCommit.is_sha1('deadbeef') + False + >>> GitCommit.is_sha1('17975594b2d42f2a3d144a9678fdf2c2c1dd96a0') + True + >>> GitCommit.is_sha1('17975594b2d42f2a3d144a9678fdf2c2c1dd96a0toolong') + False + + @param value: the value to check + @type value: C{str} + @return: C{True} if I{value} is a 40 digit SHA1, C{False} otherwise. + @rtype: C{bool} + """ + return True if GitCommit.sha1_re.match(value) else False + + class GitRepository(object): """ Represents a git repository at I{path}. It's currently assumed that the git @@ -528,7 +554,6 @@ class GitRepository(object): args = [ '-l', pattern ] if pattern else [] return [ line.strip() for line in self.__git_getoutput('tag', args)[0] ] #} - def force_head(self, commit, hard=False): """ Force HEAD to a specific commit @@ -537,11 +562,18 @@ class GitRepository(object): @param hard: also update the working copy @type hard: C{bool} """ - args = ['--quiet'] - if hard: - args += [ '--hard' ] - args += [ commit, '--' ] - self._git_command("reset", args) + if not GitCommit.is_sha1(commit): + commit = self.rev_parse(commit) + + if self.bare: + ref = "refs/heads/%s" % self.get_branch() + self._git_command("update-ref", [ ref, commit ]) + else: + args = ['--quiet'] + if hard: + args += [ '--hard' ] + args += [ commit, '--' ] + self._git_command("reset", args) def is_clean(self): """ diff --git a/tests/test_GitRepository.py b/tests/test_GitRepository.py index 55bf9cb..dd713c1 100644 --- a/tests/test_GitRepository.py +++ b/tests/test_GitRepository.py @@ -2,6 +2,13 @@ """ Test L{gbp.git.GitRepository} + +This testcase creates several repositores: + + - A repository at L{repo_dir} called I{repo} + - A bare repository at L{bare_dir} called I{bare} + - A clone of I{repo} below L{clone_dir} called I{clone} + - A mirror of I{repo} below L{mirror_clone_dir} called I{mirror} """ import os @@ -261,6 +268,7 @@ def test_mirror_clone(): >>> mirror.set_branch('foo') >>> mirror.branch 'foo' + >>> mirror.force_head('foo^') """ def test_clone(): -- cgit v1.2.3