Switch to unified view

a/Allura/allura/model/repo.py b/Allura/allura/model/repo.py
...
...
34
QSIZE = 100
34
QSIZE = 100
35
README_RE = re.compile('^README(\.[^.]*)?$', re.IGNORECASE)
35
README_RE = re.compile('^README(\.[^.]*)?$', re.IGNORECASE)
36
VIEWABLE_EXTENSIONS = ['.php','.py','.js','.java','.html','.htm','.yaml','.sh',
36
VIEWABLE_EXTENSIONS = ['.php','.py','.js','.java','.html','.htm','.yaml','.sh',
37
    '.rb','.phtml','.txt','.bat','.ps1','.xhtml','.css','.cfm','.jsp','.jspx',
37
    '.rb','.phtml','.txt','.bat','.ps1','.xhtml','.css','.cfm','.jsp','.jspx',
38
    '.pl','.php4','.php3','.rhtml','.svg','.markdown','.json','.ini','.tcl','.vbs','.xsl']
38
    '.pl','.php4','.php3','.rhtml','.svg','.markdown','.json','.ini','.tcl','.vbs','.xsl']
39
40
DIFF_SIMILARITY_THRESHOLD = .5  # used for determining file renames
39
41
40
# Basic commit information
42
# Basic commit information
41
# One of these for each commit in the physical repo on disk. The _id is the
43
# One of these for each commit in the physical repo on disk. The _id is the
42
# hexsha of the commit (for Git and Hg).
44
# hexsha of the commit (for Git and Hg).
43
CommitDoc = collection(
45
CommitDoc = collection(
...
...
265
                removed.append(change.name)
267
                removed.append(change.name)
266
            elif change.lhs_id is None:
268
            elif change.lhs_id is None:
267
                added.append(change.name)
269
                added.append(change.name)
268
            else:
270
            else:
269
                changed.append(change.name)
271
                changed.append(change.name)
272
        prev_commit = self.log(1, 1)[0]
273
        for r_name in removed[:]:
274
            r_blob = prev_commit.tree.get_obj_by_path(r_name)
275
            r_type = 'blob' if isinstance(r_blob, Blob) else 'tree'
276
            best = dict(ratio=0, name='')
277
            for a_name in added:
278
                a_blob = self.tree.get_obj_by_path(a_name)
279
                if r_type == 'tree':
280
                    if isinstance(a_blob, Tree):
281
                        if r_blob._id == a_blob._id:
282
                            best['ratio'] = 100
283
                            best['name'] = a_name
284
                            break;
285
                else:
286
                    diff = SequenceMatcher(None, r_blob.text, a_blob.text)
287
                    if diff.ratio() > best['ratio']:
288
                        best['ratio'] = diff.ratio()
289
                        best['name'] = a_name
290
            if best['ratio'] > DIFF_SIMILARITY_THRESHOLD:
291
                copied.append(dict(old=r_name, new=a_name))
292
                removed.remove(r_name)
293
                added.remove(best['name'])
270
        return Object(
294
        return Object(
271
            added=added, removed=removed,
295
            added=added, removed=removed,
272
            changed=changed, copied=copied)
296
            changed=changed, copied=copied)
273
297
274
    def get_path(self, path):
298
    def get_path(self, path):
...
...
309
            obj = self.query.get(_id=oid)
333
            obj = self.query.get(_id=oid)
310
        if obj is None: raise KeyError, name
334
        if obj is None: raise KeyError, name
311
        obj.set_context(self, name)
335
        obj.set_context(self, name)
312
        return obj
336
        return obj
313
337
314
    def get_blob_by_path(self, path):
338
    def get_obj_by_path(self, path):
315
        path = path.split('/')
339
        path = path.split('/')
316
        obj = self
340
        obj = self
317
        for p in path:
341
        for p in path:
318
            try:
342
            try:
319
                obj = obj[p]
343
                obj = obj[p]
320
            except KeyError:
344
            except KeyError:
321
                return None
345
                return None
346
        return obj
347
348
    def get_blob_by_path(self, path):
349
        obj = self.get_obj_by_path(path)
322
        return obj if isinstance(obj, Blob) else None
350
        return obj if isinstance(obj, Blob) else None
323
351
324
    def set_context(self, commit_or_tree, name=None):
352
    def set_context(self, commit_or_tree, name=None):
325
        assert commit_or_tree is not self
353
        assert commit_or_tree is not self
326
        self.repo = commit_or_tree.repo
354
        self.repo = commit_or_tree.repo