Changeset - 5fe0f744bec0
[Not reviewed]
beta
0 1 0
Marcin Kuzminski - 13 years ago 2012-07-06 20:29:36
marcin@python-works.com
fixed issue #492 missing `\ No newline at end of file` test at the end of new chunk
in html diff
1 file changed with 18 insertions and 10 deletions:
0 comments (0 inline, 0 general)
rhodecode/lib/diffs.py
Show inline comments
 
@@ -113,48 +113,49 @@ def get_gitdiff(filenode_old, filenode_n
 
    if submodules:
 
        return ''
 

	
 
    for filenode in (filenode_old, filenode_new):
 
        if not isinstance(filenode, FileNode):
 
            raise VCSError("Given object should be FileNode object, not %s"
 
                % filenode.__class__)
 

	
 
    repo = filenode_new.changeset.repository
 
    old_raw_id = getattr(filenode_old.changeset, 'raw_id', repo.EMPTY_CHANGESET)
 
    new_raw_id = getattr(filenode_new.changeset, 'raw_id', repo.EMPTY_CHANGESET)
 

	
 
    vcs_gitdiff = repo.get_diff(old_raw_id, new_raw_id, filenode_new.path,
 
                                 ignore_whitespace, context)
 
    return vcs_gitdiff
 

	
 

	
 
class DiffProcessor(object):
 
    """
 
    Give it a unified diff and it returns a list of the files that were
 
    mentioned in the diff together with a dict of meta information that
 
    can be used to render it in a HTML template.
 
    """
 
    _chunk_re = re.compile(r'@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)')
 
    _newline_marker = '\\ No newline at end of file\n'
 

	
 
    def __init__(self, diff, differ='diff', format='gitdiff'):
 
        """
 
        :param diff:   a text in diff format or generator
 
        :param format: format of diff passed, `udiff` or `gitdiff`
 
        """
 
        if isinstance(diff, basestring):
 
            diff = [diff]
 

	
 
        self.__udiff = diff
 
        self.__format = format
 
        self.adds = 0
 
        self.removes = 0
 

	
 
        if isinstance(self.__udiff, basestring):
 
            self.lines = iter(self.__udiff.splitlines(1))
 

	
 
        elif self.__format == 'gitdiff':
 
            udiff_copy = self.copy_iterator()
 
            self.lines = imap(self.escaper, self._parse_gitdiff(udiff_copy))
 
        else:
 
            udiff_copy = self.copy_iterator()
 
            self.lines = imap(self.escaper, udiff_copy)
 

	
 
@@ -324,89 +325,96 @@ class DiffProcessor(object):
 

	
 
                    lines = []
 
                    chunks.append(lines)
 

	
 
                    old_line, old_end, new_line, new_end = \
 
                        [int(x or 1) for x in match.groups()[:-1]]
 
                    old_line -= 1
 
                    new_line -= 1
 
                    gr = match.groups()
 
                    context = len(gr) == 5
 
                    old_end += old_line
 
                    new_end += new_line
 

	
 
                    if context:
 
                        # skip context only if it's first line
 
                        if int(gr[0]) > 1:
 
                            lines.append({
 
                                'old_lineno': '...',
 
                                'new_lineno': '...',
 
                                'action':     'context',
 
                                'line':       line,
 
                            })
 

	
 
                    line = lineiter.next()
 

	
 
                    while old_line < old_end or new_line < new_end:
 
                        if line:
 
                            command, line = line[0], line[1:]
 
                            command = line[0]
 
                            if command in ['+', '-', ' ']:
 
                                #only modify the line if it's actually a diff
 
                                # thing
 
                                line = line[1:]
 
                        else:
 
                            command = ' '
 

	
 
                        affects_old = affects_new = False
 

	
 
                        # ignore those if we don't expect them
 
                        if command in '#@':
 
                            continue
 
                        elif command == '+':
 
                            affects_new = True
 
                            action = 'add'
 
                            stats[0] += 1
 
                        elif command == '-':
 
                            affects_old = True
 
                            action = 'del'
 
                            stats[1] += 1
 
                        else:
 
                            affects_old = affects_new = True
 
                            action = 'unmod'
 

	
 
                        if line.find('No newline at end of file') != -1:
 
                            lines.append({
 
                                'old_lineno':   '...',
 
                                'new_lineno':   '...',
 
                                'action':       'context',
 
                                'line':         line
 
                            })
 

	
 
                        else:
 
                        if line != self._newline_marker:
 
                            old_line += affects_old
 
                            new_line += affects_new
 
                            lines.append({
 
                                'old_lineno':   affects_old and old_line or '',
 
                                'new_lineno':   affects_new and new_line or '',
 
                                'action':       action,
 
                                'line':         line
 
                            })
 

	
 
                        line = lineiter.next()
 
                        if line == self._newline_marker:
 
                            # we need to append to lines, since this is not
 
                            # counted in the line specs of diff
 
                            lines.append({
 
                                'old_lineno':   '...',
 
                                'new_lineno':   '...',
 
                                'action':       'context',
 
                                'line':         line
 
                            })
 

	
 
        except StopIteration:
 
            pass
 

	
 
        sorter = lambda info: {'A': 0, 'M': 1, 'D': 2}.get(info['operation'])
 
        if inline_diff is False:
 
            return sorted(files, key=sorter)
 

	
 
        # highlight inline changes
 
        for diff_data in files:
 
            for chunk in diff_data['chunks']:
 
                lineiter = iter(chunk)
 
                try:
 
                    while 1:
 
                        line = lineiter.next()
 
                        if line['action'] not in ['unmod', 'context']:
 
                            nextline = lineiter.next()
 
                            if nextline['action'] in ['unmod', 'context'] or \
 
                               nextline['action'] == line['action']:
 
                                continue
 
                            self.differ(line, nextline)
 
                except StopIteration:
 
                    pass
 

	
0 comments (0 inline, 0 general)