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')
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)
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))
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
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')
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
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 = []
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')
def current(): if _transaction is None: raise GitError('no transaction running') return _transaction
def rollback(): global _transaction if not _transaction: raise GitError('no transaction in progress') _transaction.rollback() _transaction = None
def commit(message=None): global _transaction if not _transaction: raise GitError('no transaction in progress') _transaction.commit(message) _transaction = None
def begin(): global _transaction if _transaction: raise GitError('there is already a transaction running') _transaction = Transaction(repository_path=get_repository(), branch_name=get_branch())