def get_changed_files(self): """Return the list of added or modified files on a commit""" if self.changed_files is None: output = decode_str( check_output([ git_exe_path, 'diff-tree', '-r', '--root', # Get the initial commit as additions '--no-commit-id', # We already know the commit id. '--break-rewrites', # Get rewrites as additions '--no-renames', # Get renames as additions '--diff-filter=AM', # Only additions and modifications self.commit_id, ])) changed_files = [] for line in output.splitlines(): line_split = line.split(None, 5) assert len(line_split) == 6 assert line_split[0].startswith(':') file_mode = line_split[1] # sc add object_id object_id = line_split[3] file_path = line_split[5] changed_files.append( CommittedFile(file_path, self, file_mode, object_id)) self.changed_files = changed_files return self.changed_files
def get_shebang(self): """Get the shebang from the file content""" if not self.regular(): return None content = self.get_content() if not content.startswith(b'#!'): return None content = content[len(b'#!'):].strip() return decode_str(content.split(None, 1)[0])
def get_shebang_exe(self): """Get the executable from the shebang""" shebang = self.get_shebang() if not shebang: return None if shebang == '/usr/bin/env': rest = self.get_content().splitlines()[0][len(b'#!/usr/bin/env'):] rest_split = rest.split(None, 1) if rest_split: return decode_str(rest_split[0]) return shebang.rsplit('/', 1)[-1]
def get_symlink_target(self): """Get the symlink target as same kind of instance We just return None, if the target has no chance to be on the repository.""" content = self.get_content() if isabs(content): return None path = normpath(joinpath(self.path, '..', decode_str(content))) if path.startswith('..'): return None return type(self)(path, self.commit)
def get_new_commit_list(self, branch_name): """Get the list of parent new commits in order""" output = decode_str( check_output([ git_exe_path, 'rev-list', self.commit_id, '--not', '--all', '--reverse', ])) commit_list = CommitList([], branch_name) for commit_id in output.splitlines(): commit = Commit(commit_id, commit_list) commit_list.append(commit) return commit_list
def _fetch_content(self): content = check_output( [git_exe_path, 'cat-file', '-p', self.commit_id]) self._parents = [] self._message_lines = [] # The commit message starts after the empty line. We iterate until # we find one, and then consume the rest as the message. lines = iter(content.splitlines()) for line in lines: if not line: break if line.startswith(b'parent '): self._parents.append(Commit(line[len(b'parent '):].rstrip())) elif line.startswith(b'author '): self._author = Contributor.parse(line[len(b'author '):]) elif line.startswith(b'committer '): self._committer = Contributor.parse(line[len(b'committer '):]) for line in lines: self._message_lines.append(decode_str(line)) self.content_fetched = True
def get_binary_files(self): """Return the binary files on a commit""" if self.binary_files is None: output = decode_str( check_output([ git_exe_path, 'log', '--pretty=format:%H -M100%', # pretty format '--numstat', # number state of the file '--no-commit-id', # We already know the commit id. '--break-rewrites', # Get rewrites as additions '--no-renames', # Get renames as additions '--diff-filter=AM', # Only additions and modifications "{}^!".format(self.commit_id), ])) binary_files = [] for line in output.splitlines(): line_split = line.split('\t') if len(line_split) == 3: if "-" == line_split[0] and "-" == line_split[1]: binary_files.append(line_split[2]) self.binary_files = binary_files return self.binary_files
def parse(cls, line): """Parse the contribution line as bytes""" name, line = line.split(b' <', 1) email, line = line.split(b'> ', 1) timestamp, line = line.split(b' ', 1) return cls(decode_str(name), decode_str(email), int(timestamp))