예제 #1
0
 def test_reuse_detector(self):
     blob = make_object(Blob, data='blob')
     tree1 = self.commit_tree([('a', blob)])
     tree2 = self.commit_tree([('b', blob)])
     detector = RenameDetector(self.store)
     changes = [TreeChange(CHANGE_RENAME, ('a', F, blob.id),
                           ('b', F, blob.id))]
     self.assertEqual(changes,
                      detector.changes_with_renames(tree1.id, tree2.id))
     self.assertEqual(changes,
                      detector.changes_with_renames(tree1.id, tree2.id))
예제 #2
0
 def test_reuse_detector(self):
     blob = make_object(Blob, data='blob')
     tree1 = self.commit_tree([('a', blob)])
     tree2 = self.commit_tree([('b', blob)])
     detector = RenameDetector(self.store)
     changes = [TreeChange(CHANGE_RENAME, ('a', F, blob.id),
                           ('b', F, blob.id))]
     self.assertEqual(changes,
                      detector.changes_with_renames(tree1.id, tree2.id))
     self.assertEqual(changes,
                      detector.changes_with_renames(tree1.id, tree2.id))
예제 #3
0
def main(args, hear, talk, complain):
    """Reset boring changes

    See doc-string of this file for outline.

    Required arguments - args, hear, talk and complain -- should,
    respectively, be (or behave as, e.g. if mocking to test) sys.argv,
    sys.stdin, sys.stdout and sys.stderr.  The only command-line
    option supported (in args) is a '--disclaim' flag, to treat as
    boring all changes in files with the standard 'We mean it'
    disclaimer; it is usual to pass this flag.\n"""
    ignore = Scanner.disclaimed if '--disclaim' in args else (
        lambda p, w: False)

    # We're in the root directory of the module:
    repo = Repo('.')
    store, index = repo.object_store, repo.open_index()
    renamer = RenameDetector(store)
    try:
        # TODO: demand stronger similarity for a copy than for rename;
        # our huge copyright headers (and common boilerplate) make
        # small header files look very similar despite their real
        # content all being quite different.  Probably need to hack
        # dulwich (find_copies_harder is off by default anyway).
        for kind, old, new in \
            renamer.changes_with_renames(store[repo.refs['HEAD']].tree,
                                         index.commit(store)):
            # Each of old, new is a named triple of .path, .mode and
            # .sha; kind is the change type, in ('add', 'modify',
            # 'delete', 'rename', 'copy', 'unchanged'), although we
            # shouldn't get the last.  If new.path is None, file was
            # removed, not renamed; otherwise, if new has a
            # disclaimer, it's private despite its name and path.
            if new.path and not ignore(new.path, complain.write):
                assert kind not in ('unchanged', 'delete'), kind
                if kind != 'add':
                    # Filter out boring changes
                    index[new.path] = Selector(store, new.sha, old.sha,
                                               old.mode or new.mode).refine()
            elif old.path:  # disclaimed or removed: ignore by restoring
                assert new.path or kind == 'delete', (kind, new.path)
                index[old.path] = Selector.restore(store[old.sha], old.mode)
                talk.write(old.path + '\n')
                if new.path and new.path != old.path:
                    talk.write(new.path + '\n')
            else:  # new but disclaimed: ignore by discarding
                assert kind == 'add' and new.path, (kind, new.path)
                del index[new.path]
                talk.write(new.path + '\n')

        index.write()
    except IOError:  # ... and any other errors that just mean failure.
        return 1
    return 0
예제 #4
0
파일: klaus.py 프로젝트: zauguin/klaus
def last_commit_renamed_path(repo, history, path):
    """ Check if the last commit of this history renames the given path
        If so, return the new path, otherwise None """
    if len(history) <= 1:
        return None;
    
    newtree = history[0].tree
    oldtree = history[1].tree
    
    rd = RenameDetector(repo)
    result = "";
    for change in rd.changes_with_renames(oldtree, newtree):
      if change.type == 'rename' and change.old.path == path:
        return change.new.path 

    return None
예제 #5
0
def main(args, hear, talk, complain):
    # Future: we may want to parse more args, query the user or wrap
    # talk, complain for verbosity control.
    ignore = Scanner.disclaimed if '--disclaim' in args else (
        lambda p, w: False)

    # We're in the root directory of the module:
    repo = Repo('.')
    store, index = repo.object_store, repo.open_index()
    renamer = RenameDetector(store)
    try:
        # TODO: demand stronger similarity for a copy than for rename;
        # our huge copyright headers (and common boilerplate) make
        # small header files look very similar despite their real
        # content all being quite different.  Probably need to hack
        # dulwich (find_copies_harder is off by default anyway).
        for kind, old, new in \
            renamer.changes_with_renames(store[repo.refs['HEAD']].tree,
                                         index.commit(store)):
            # Each of old, new is a named triple of .path, .mode and
            # .sha; kind is the change type, in ('add', 'modify',
            # 'delete', 'rename', 'copy', 'unchanged'), although we
            # shouldn't get the last.  If new.path is None, file was
            # removed, not renamed; otherwise, if new has a
            # disclaimer, it's private despite its name and path.
            if new.path and not ignore(new.path, complain.write):
                assert kind not in ('unchanged', 'delete'), kind
                if kind != 'add':
                    # Filter out boring changes
                    index[new.path] = Selector(store, new.sha, old.sha,
                                               old.mode or new.mode).refine()
            elif old.path:  # disclaimed or removed: ignore by restoring
                assert new.path or kind == 'delete', (kind, new.path)
                index[old.path] = Selector.restore(store[old.sha], old.mode)
            else:  # new but disclaimed: ignore by discarding
                assert kind == 'add' and new.path, (kind, new.path)
                del index[new.path]

        index.write()
    except IOError:  # ... and any other errors that just mean failure.
        return 1
    return 0
예제 #6
0
 def detect_renames(self, tree1, tree2, want_unchanged=False, **kwargs):
     detector = RenameDetector(self.store, **kwargs)
     return detector.changes_with_renames(tree1.id, tree2.id,
                                          want_unchanged=want_unchanged)
예제 #7
0
 def detect_renames(self, tree1, tree2, want_unchanged=False, **kwargs):
     detector = RenameDetector(self.store, **kwargs)
     return detector.changes_with_renames(tree1.id, tree2.id,
                                          want_unchanged=want_unchanged)
예제 #8
0
 def detect_renames(self, tree1, tree2, **kwargs):
     detector = RenameDetector(self.store, tree1.id, tree2.id, **kwargs)
     return detector.changes_with_renames()