Example #1
0
 def merge(self,
           commit_oid,
           squash=False,
           message=None,
           author_signature=None):
     if not self.branch:
         raise GitError('no branch specified')
     index = self.repo.merge_commits(self.parents[0], commit_oid)
     if index.conflicts:
         raise GitError("conflicts occurred. cannot merge")
     new_tree = index.write_tree(repo=self.repo)
     try:
         name = settings.GIT_USER_NAME
         email = settings.GIT_USER_EMAIL
     except KeyError as e:
         raise GitError('{} not found in Django settings'.format(e))
     sig = pygit2.Signature(name, email)
     if not author_signature:
         author_signature = sig
     ref = get_branch_reference(self.branch)
     if squash:
         if not message:
             message = self.repo[commit_oid].message
         parents = self.parents
     else:
         if not message:
             message = "Merged with {}".format(str(commit_oid))
         parents = self.parents + [commit_oid]
     return self.repo.create_commit(ref, author_signature, sig, message,
                                    new_tree, parents, 'utf-8')
Example #2
0
def begin():
    global _transaction
    if _transaction:
        raise GitError('there is already a transaction running')
    repo = get_repository()
    if repo is None:
        raise GitError('no repository found')
    ref = 'refs/heads/{}'.format(get_branch())
    try:
        parents = [repo.lookup_reference(ref).oid]
    except KeyError:
        parents = []
    _transaction = Transaction(repo, parents)
Example #3
0
def fetch():
    cmd = [
        'git', 'fetch', get_remote(),
        'refs/heads/{0}:refs/remotes/origin/{0}'.format(get_branch()),
    ]
    p = Popen(cmd, cwd=get_repository().workdir)
    status = p.wait()
    if status:
        raise GitError('git-fetch returned with exit status {}'.format(status))
Example #4
0
 def get_blob(self, path):
     *path, filename = map(quote_filename, path)
     memory_tree = self.get_memory_tree(path)
     content = None
     if filename in memory_tree.blobs:
         content = memory_tree.blobs[filename]
     elif filename in memory_tree.tree:
         entry = memory_tree.tree[filename]
         if entry.attributes & stat.S_IFREG:
             content = entry.to_object().data
     if content is None:
         raise GitError('blob not found')
     return content
Example #5
0
    def commit(self, message=None):
        if not self.has_changes:
            raise GitError(
                'nothing changed; use rollback to abort the transaction')
        if not message:
            if not self.messages:
                raise GitError('no message for commit')
            message = '\n'.join(self.messages)
        elif self.messages:
            message += '\n\n' + '\n'.join(self.messages)

        tree_id = self._store_objects(self.memory_tree)

        try:
            name = self.repo.config['user.name']
            email = self.repo.config['user.email']
        except KeyError as e:
            raise GitError('{} not found in git config'.format(e))
        sig = pygit2.Signature(name, email)
        ref = 'refs/heads/{}'.format(get_branch())
        self.repo.create_commit(ref, sig, sig, message, tree_id, self.parents,
                                'utf-8')
Example #6
0
 def get_blob(self, path):
     path = PurePath(os.path.join(*path)).parts
     *path, filename = map(quote_filename, path)
     memory_tree = self.get_memory_tree(path)
     content = None
     if filename in memory_tree.blobs:
         content = memory_tree.blobs[filename]
     elif filename in memory_tree.tree:
         entry = memory_tree.tree[filename]
         if entry.filemode & stat.S_IFREG:
             content = self.repo[entry.oid].data
     if content is None:
         raise GitError('blob not found')
     return content
Example #7
0
    def __init__(self, repository_path, commit_id=None, branch_name=None):
        try:
            path = pygit2.discover_repository(repository_path)
        except KeyError:
            raise GitError(
                'no repository found in "{}"'.format(repository_path))
        self.repo = repo = pygit2.Repository(path)

        if branch_name is not None and commit_id is not None:
            raise ValueError(
                'only one of branch_name and commit_id should be set')

        self.branch = None
        if branch_name is None and commit_id is None:
            parents = []
        elif branch_name is not None:
            self.branch = branch_name
            branch_reference = get_branch_reference(self.branch)
            try:
                commit_oid = self.repo.lookup_reference(
                    branch_reference).target
            except KeyError:
                parents = []
            else:
                parents = [commit_oid]
        else:
            commit_oid = pygit2.Oid(hex=commit_id)
            parents = [commit_oid]

        self.parents = parents
        tree = []
        if parents:
            tree = repo[parents[0]].tree
        self.memory_tree = MemoryTree(tree, {}, {})

        self.has_changes = False
        self.messages = []
Example #8
0
    def commit(self,
               message=None,
               author_signature=None,
               amend=False,
               allow_empty=False):
        if not self.branch:
            raise GitError('no branch specified')
        if not allow_empty and not self.has_changes:
            raise GitError(
                'nothing changed; use rollback to abort the transaction')
        if amend:
            if len(self.parents) > 1:
                raise GitError('cannot amend more than one commit')
            elif len(self.parents) == 0:
                raise GitError('no commit to amend')
            else:
                previous_commit_message = self.repo[self.parents[0]].message
                parts = previous_commit_message.split('\n\n')
                if not message:
                    message = parts[0]
                detailed_messages = ['\n\n'.join(parts[1:])] + self.messages
            parents = self.repo[self.parents[0]].parents
        else:
            detailed_messages = self.messages
            if not message:
                if not self.messages:
                    raise GitError('no message for commit')
                message = '\n'.join(detailed_messages)
            parents = self.parents
        if detailed_messages:
            message += '\n\n' + '\n'.join(detailed_messages)

        tree_id = self._store_objects(self.memory_tree)
        try:
            name = settings.GIT_USER_NAME
            email = settings.GIT_USER_EMAIL
        except KeyError as e:
            raise GitError('{} not found in Django settings'.format(e))
        sig = pygit2.Signature(name, email)
        if not author_signature:
            author_signature = sig
        ref = get_branch_reference(self.branch)
        return self.repo.create_commit(ref, author_signature, sig, message,
                                       tree_id, parents, 'utf-8')
Example #9
0
def current():
    if _transaction is None:
        raise GitError('no transaction running')
    return _transaction
Example #10
0
def rollback():
    global _transaction
    if not _transaction:
        raise GitError('no transaction in progress')
    _transaction.rollback()
    _transaction = None
Example #11
0
def commit(message=None):
    global _transaction
    if not _transaction:
        raise GitError('no transaction in progress')
    _transaction.commit(message)
    _transaction = None
Example #12
0
def begin():
    global _transaction
    if _transaction:
        raise GitError('there is already a transaction running')
    _transaction = Transaction(repository_path=get_repository(),
                               branch_name=get_branch())