def hard_reset_to_ref(self, branch, ref): """Perform a hard reset of a local branch to any reference. :param str branch: Local branch to reset :param str ref: Reference (commit, tag, ...) to reset to """ # Ensure the reference maps to a commit try: commit = git.repo.fun.name_to_object(self.git_repo.repo, ref) except git.exc.BadName as ex: msg = "Could not find reference {0}.".format(ref) raise_from(exceptions.ReferenceNotFoundException(msg), ex) # Switch to the branch try: self.git_repo.git.checkout(branch) except git.GitCommandError as ex: msg = ( "Could not checkout branch {branch}. Error: {error}".format( branch=branch, error=ex) ) raise_from(exceptions.CheckoutException(msg), ex) # Reset --hard to that reference try: self.git_repo.repo.head.reset(commit=commit, index=True, working_tree=True) except git.GitCommandError as ex: msg = ( "Error resetting branch {branch} to {ref}. " "Error: {error}".format(ref=ref, branch=branch, error=ex) ) raise_from(exceptions.ResetException(msg), ex)
def to_hash(self, branch_name, hash_): """Perform a rebase from a specific reference to another. :param str branch_name: The name of the branch or reference to start from :param str hash_: The commit hash or reference to rebase to """ logger.debug( "Rebasing branch %s to hash %s. Repo currently at commit %s.", branch_name, hash_, self.repo.head.commit) if self.repo.is_dirty(): msg = "Repository %s is dirty. Please clean workspace before proceeding." % self.repo.working_dir raise exceptions.DirtyRepositoryException(msg) # Does the branch exist? try: branch = git.repo.fun.name_to_object(self.repo, branch_name) except git.exc.BadName as ex: msg = "Could not find branch %s." % branch_name raise exceptions.ReferenceNotFoundException(msg) from ex # Does the hash exists? try: commit = git.repo.fun.name_to_object(self.repo, hash_) except git.exc.BadName as ex: msg = "Could not find hash %s." % hash_ raise exceptions.ReferenceNotFoundException(msg) from ex # Checkout try: self.repo.git.checkout(branch.hexsha) except git.GitCommandError as ex: msg = "Could not checkout branch %s. Error: %s" % (branch_name, ex) raise exceptions.CheckoutException(msg) from ex # Rebase try: self.repo.git.rebase(commit.hexsha) except git.GitCommandError as ex: msg = "Could not rebase hash %s onto branch %s. Error: %s" % ( hash_, branch_name, ex) raise exceptions.RebaseException(msg) from ex logger.debug("Successfully rebased branch %s (%s) to %s" % (branch_name, branch.hexsha, hash_))
def wrapper(func, instance, args, kwargs): all_args = inspect.getcallargs(func, *args, **kwargs) try: repo = all_args['self'].git_repo.repo git.repo.fun.name_to_object(repo, all_args[ref]) except git.exc.BadName as ex: msg = "Could not find %s %s." % (ref, all_args[ref]) raise_from(exceptions.ReferenceNotFoundException(msg), ex) return func(*args, **kwargs)
def hard_reset_to_ref(self, branch, ref, checkout=True): """Perform a hard reset of a local branch to any reference. :param str branch: Local branch to reset :param str ref: Reference (commit, tag, ...) to reset to :param bool checkout: Whether to checkout the new branch """ # Ensure the reference maps to a commit try: commit = git.repo.fun.name_to_object(self.git_repo.repo, ref) except git.exc.BadName as ex: msg = "Could not find reference {0}.".format(ref) raise_from(exceptions.ReferenceNotFoundException(msg), ex) try: # Preserve the reference name if there is one orig = self.git_repo.repo.head.ref.name except TypeError: # Detached head orig = self.git_repo.repo.head.commit.hexsha # Switch to the branch try: self.git_repo.git.checkout(branch) except git.GitCommandError as ex: msg = ( "Could not checkout branch {branch}. Error: {error}".format( branch=branch, error=ex) ) raise_from(exceptions.CheckoutException(msg), ex) # Reset --hard to that reference try: self.git_repo.repo.head.reset(commit=commit, index=True, working_tree=True) except git.GitCommandError as ex: msg = ( "Error resetting branch {branch} to {ref}. " "Error: {error}".format(ref=ref, branch=branch, error=ex) ) raise_from(exceptions.ResetException(msg), ex) # Return to the original head if required if not checkout: try: self.git_repo.git.checkout(orig) except git.GitCommandError as ex: msg = ( "Could not checkout {orig}. Error: {error}".format( orig=orig, error=ex) ) raise_from(exceptions.CheckoutException(msg), ex)
def fetch(self, remote="origin"): """Refresh the specified remote :param str remote: Remote to fetch """ try: remote = self.git_repo.repo.remote(remote) except ValueError: repo = self.git_repo.repo.working_dir msg = f"Remote {remote} does not exist on repo {repo}" raise exceptions.ReferenceNotFoundException(msg) try: remote.fetch() except git.GitCommandError as ex: msg = (f"Could not fetch remote {remote.name} ({remote.url}). " f"Error: {ex}") raise exceptions.RemoteException(msg) from ex
def fetch(self, remote="origin"): """Refresh the specified remote :param str remote: Remote to fetch """ try: remote = self.git_repo.repo.remote(remote) except ValueError: msg = "Remote {remote} does not exist on repo {repo}".format( remote=remote, repo=self.git_repo.repo.working_dir) raise exceptions.ReferenceNotFoundException(msg) try: remote.fetch() except git.GitCommandError as ex: msg = ("Could not fetch remote {remote} ({url}). " "Error: {error}".format(remote=remote.name, url=remote.url, error=ex)) raise_from(exceptions.RemoteException(msg), ex)
def push(self, name, remote, dry_run=False): """Push specified tag to specified remote :param str name: Tag name :param str remote: Remote to push the tag to :param bool dry_run: Whether to run the commands in dry-run mode """ if remote not in self.git_repo.remote.names(): msg = "No remote named {0}".format(remote) raise exceptions.ReferenceNotFoundException(msg) msg = ("Error pushing tag {name} (dry-run: {dry_run}) to remote " "{remote}.".format(name=name, remote=remote, dry_run=dry_run)) try: if dry_run: self.git_repo.git.push("-n", remote, name) else: self.git_repo.git.push(remote, name) except git.GitCommandError as ex: raise_from(exceptions.PushException(msg), ex)