# diff.py # Copyright (C) 2008-2010 Michael Trier (mtrier@gmail.com) and contributors # # This module is part of GitPython and is released under # the BSD License: http://www.opensource.org/licenses/bsd-license.php import re import commit class Diff(object): """ A Diff contains diff information between two commits. """ def __init__(self, repo, a_path, b_path, a_commit, b_commit, a_mode, b_mode, new_file, deleted_file, rename_from, rename_to, diff): self.repo = repo self.a_path = a_path self.b_path = b_path if not a_commit or re.search(r'^0{40}$', a_commit): self.a_commit = None else: self.a_commit = commit.Commit(repo, id=a_commit) if not b_commit or re.search(r'^0{40}$', b_commit): self.b_commit = None else: self.b_commit = commit.Commit(repo, id=b_commit) self.a_mode = a_mode self.b_mode = b_mode self.new_file = new_file self.deleted_file = deleted_file self.rename_from = rename_from self.rename_to = rename_to self.renamed = rename_from != rename_to self.diff = diff @classmethod def list_from_string(cls, repo, text): diffs = [] diff_header = re.compile(r""" #^diff[ ]--git [ ]a/(?P\S+)[ ]b/(?P\S+)\n (?:^similarity[ ]index[ ](?P\d+)%\n ^rename[ ]from[ ](?P\S+)\n ^rename[ ]to[ ](?P\S+)(?:\n|$))? (?:^old[ ]mode[ ](?P\d+)\n ^new[ ]mode[ ](?P\d+)(?:\n|$))? (?:^new[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^deleted[ ]file[ ]mode[ ](?P.+)(?:\n|$))? (?:^index[ ](?P[0-9A-Fa-f]+) \.\.(?P[0-9A-Fa-f]+)[ ]?(?P.+)?(?:\n|$))? """, re.VERBOSE | re.MULTILINE).match for diff in ('\n' + text).split('\ndiff --git')[1:]: header = diff_header(diff) a_path, b_path, similarity_index, rename_from, rename_to, \ old_mode, new_mode, new_file_mode, deleted_file_mode, \ a_commit, b_commit, b_mode = header.groups() new_file, deleted_file = bool(new_file_mode), bool(deleted_file_mode) diffs.append(Diff(repo, a_path, b_path, a_commit, b_commit, old_mode or deleted_file_mode, new_mode or new_file_mode or b_mode, new_file, deleted_file, rename_from, rename_to, diff[header.end():])) return diffs