diff options
Diffstat (limited to 'git/diff.py')
-rw-r--r-- | git/diff.py | 99 |
1 files changed, 49 insertions, 50 deletions
diff --git a/git/diff.py b/git/diff.py index e90fc1cf..b4d2bae8 100644 --- a/git/diff.py +++ b/git/diff.py @@ -11,21 +11,21 @@ from exc import GitCommandError from gitdb.util import hex_to_bin - + __all__ = ('Diffable', 'DiffIndex', 'Diff') - + class Diffable(object): """Common interface for all object that can be diffed against another object of compatible type. - + :note: Subclasses require a repo member as it is the case for Object instances, for practical reasons we do not derive from Object.""" __slots__ = tuple() - + # standin indicating you want to diff against the index class Index(object): pass - + def _process_diff_args(self, args): """ :return: @@ -33,7 +33,7 @@ class Diffable(object): Method is called right before git command execution. Subclasses can use it to alter the behaviour of the superclass""" return args - + def diff(self, other=Index, paths=None, create_patch=False, **kwargs): """Creates diffs between two items being trees, trees and index or an index and the working tree. @@ -60,16 +60,16 @@ class Diffable(object): R=True to swap both sides of the diff. :return: git.DiffIndex - + :note: Rename detection will only work if create_patch is True. - + On a bare repository, 'other' needs to be provided as Index or as as Tree/Commit, or a git command error will occour""" args = list() args.append( "--abbrev=40" ) # we need full shas args.append( "--full-index" ) # get full index paths, not only filenames - + if create_patch: args.append("-p") args.append("-M") # check for renames @@ -79,7 +79,7 @@ class Diffable(object): # in any way, assure we don't see colored output, # fixes https://github.com/gitpython-developers/GitPython/issues/172 args.append('--no-color') - + if paths is not None and not isinstance(paths, (tuple,list)): paths = [ paths ] @@ -87,23 +87,23 @@ class Diffable(object): args.insert(0, other) if other is self.Index: args.insert(0, "--cached") - + args.insert(0,self) - + # paths is list here or None if paths: args.append("--") args.extend(paths) # END paths handling - + kwargs['as_process'] = True proc = self.repo.git.diff(*self._process_diff_args(args), **kwargs) - + diff_method = Diff._index_from_raw_format if create_patch: diff_method = Diff._index_from_patch_format index = diff_method(self.repo, proc.stdout) - + status = proc.wait() return index @@ -111,7 +111,7 @@ class Diffable(object): class DiffIndex(list): """Implements an Index for diffs, allowing a list of Diffs to be queried by the diff properties. - + The class improves the diff handling convenience""" # change type invariant identifying possible ways a blob can have changed # A = Added @@ -119,23 +119,23 @@ class DiffIndex(list): # R = Renamed # M = modified change_type = ("A", "D", "R", "M") - - + + def iter_change_type(self, change_type): """ :return: iterator yieling Diff instances that match the given change_type - + :param change_type: Member of DiffIndex.change_type, namely: - + * 'A' for added paths * 'D' for deleted paths * 'R' for renamed paths * 'M' for paths with modified data""" if change_type not in self.change_type: raise ValueError( "Invalid change type: %s" % change_type ) - + for diff in self: if change_type == "A" and diff.new_file: yield diff @@ -146,37 +146,37 @@ class DiffIndex(list): elif change_type == "M" and diff.a_blob and diff.b_blob and diff.a_blob != diff.b_blob: yield diff # END for each diff - + class Diff(object): """A Diff contains diff information between two Trees. - + It contains two sides a and b of the diff, members are prefixed with "a" and "b" respectively to inidcate that. - + Diffs keep information about the changed blob objects, the file mode, renames, deletions and new files. - + There are a few cases where None has to be expected as member variable value: - + ``New File``:: - + a_mode is None a_blob is None - + ``Deleted File``:: - + b_mode is None b_blob is None - + ``Working Tree Blobs`` - + When comparing to working trees, the working tree blob will have a null hexsha as a corresponding object does not yet exist. The mode will be null as well. But the path will be available though. If it is listed in a diff the working tree version of the file must be different to the version in the index or tree, and hence has been modified.""" - + # precompiled regex re_header = re.compile(r""" #^diff[ ]--git @@ -194,22 +194,22 @@ class Diff(object): # can be used for comparisons NULL_HEX_SHA = "0"*40 NULL_BIN_SHA = "\0"*20 - + __slots__ = ("a_blob", "b_blob", "a_mode", "b_mode", "new_file", "deleted_file", "rename_from", "rename_to", "diff") def __init__(self, repo, a_path, b_path, a_blob_id, b_blob_id, a_mode, b_mode, new_file, deleted_file, rename_from, rename_to, diff): - + self.a_mode = a_mode self.b_mode = b_mode - + if self.a_mode: self.a_mode = mode_str_to_int(self.a_mode) if self.b_mode: self.b_mode = mode_str_to_int(self.b_mode) - + if a_blob_id is None: self.a_blob = None else: @@ -218,14 +218,14 @@ class Diff(object): self.b_blob = None else: self.b_blob = Blob(repo, hex_to_bin(b_blob_id), mode=self.b_mode, path=b_path) - + self.new_file = new_file self.deleted_file = deleted_file - + # be clear and use None instead of empty strings self.rename_from = rename_from or None self.rename_to = rename_to or None - + self.diff = diff @@ -235,10 +235,10 @@ class Diff(object): return False # END for each name return True - + def __ne__(self, other): return not ( self == other ) - + def __hash__(self): return hash(tuple(getattr(self,n) for n in self.__slots__)) @@ -248,7 +248,7 @@ class Diff(object): h %= self.a_blob.path elif self.b_blob: h %= self.b_blob.path - + msg = '' l = None # temp line ll = 0 # line length @@ -261,10 +261,10 @@ class Diff(object): ll = max(len(l), ll) msg += l # END for each blob - + # add headline h += '\n' + '='*ll - + if self.deleted_file: msg += '\nfile deleted in rhs' if self.new_file: @@ -278,7 +278,7 @@ class Diff(object): msg += self.diff msg += '\n---' # END diff info - + return h + msg @property @@ -310,7 +310,7 @@ class Diff(object): new_file, deleted_file, rename_from, rename_to, diff[header.end():])) return index - + @classmethod def _index_from_raw_format(cls, repo, stream): """Create a new DiffIndex from the given stream which must be in raw format. @@ -331,7 +331,7 @@ class Diff(object): b_path = path deleted_file = False new_file = False - + # NOTE: We cannot conclude from the existance of a blob to change type # as diffs with the working do not have blobs yet if change_type == 'D': @@ -341,11 +341,10 @@ class Diff(object): a_blob_id = None new_file = True # END add/remove handling - + diff = Diff(repo, a_path, b_path, a_blob_id, b_blob_id, old_mode, new_mode, new_file, deleted_file, None, None, '') index.append(diff) # END for each line - - return index + return index |