Changeset 3213

Show
Ignore:
Timestamp:
02/11/08 05:23:48 (10 months ago)
Author:
hvr
Message:

GitPlugin: added support for best-guess detection of renames in changeset-view

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • gitplugin/0.11/tracext/git/git_fs.py

    r3212 r3213  
    202202 
    203203        def get_changesets(self, start, stop): 
    204                 #print "get_changesets", start, stop 
    205204                for rev in self.git.history_timerange(to_timestamp(start), to_timestamp(stop)): 
    206205                        yield self.get_changeset(rev) 
     
    211210 
    212211        def get_changes(self, old_path, old_rev, new_path, new_rev): 
     212                # TODO: handle renames/copies 
    213213                if old_path != new_path: 
    214214                        raise TracError("not supported in git_fs") 
    215                 #print "get_changes", (old_path, old_rev, new_path, new_rev) 
    216215 
    217216                for chg in self.git.diff_tree(old_rev, new_rev, self.normalize_path(new_path)): 
     
    344343 
    345344        def get_history(self, limit=None): 
     345                # TODO: find a way to follow renames/copies 
    346346                for is_last,rev in _last_iterable(self.git.history(self.rev, self.__git_path(), limit)): 
    347347                        yield (self.path, rev, Changeset.EDIT if not is_last else Changeset.ADD) 
     
    365365                'A': Changeset.ADD, 
    366366                'M': Changeset.EDIT, 
    367                 'D': Changeset.DELETE  
     367                'D': Changeset.DELETE, 
     368                'R': Changeset.MOVE, 
     369                'C': Changeset.COPY 
    368370                } 
    369371 
     
    403405 
    404406        def get_changes(self): 
    405                 # TODO: handle renames/removals 
     407                paths_seen = set() 
    406408                for parent in self.props.get('parent', [None]): 
    407                         for mode1,mode2,obj1,obj2,action,path,path2 in \ 
    408                                     self.git.diff_tree(parent, self.rev): 
    409                                 p_path, p_rev = path, parent 
     409                        for mode1,mode2,obj1,obj2,action,path1,path2 in \ 
     410                                    self.git.diff_tree(parent, self.rev, find_renames=True): 
     411                                path = path2 or path1 
     412                                p_path, p_rev = path1, parent 
    410413 
    411414                                kind = Node.FILE 
     
    413416                                        kind = Node.DIRECTORY 
    414417 
    415                                 action = GitChangeset.action_map[action
     418                                action = GitChangeset.action_map[action[0]
    416419 
    417420                                if action == Changeset.ADD: 
     
    419422                                        p_rev = None 
    420423 
     424                                # CachedRepository expects unique (rev, path, change_type) key 
     425                                # this is only an issue in case of merges where files required editing 
     426                                if path in paths_seen: 
     427                                        continue 
     428 
     429                                paths_seen.add(path) 
     430 
    421431                                yield (path, kind, action, p_path, p_rev) 
  • gitplugin/0.11/tracext/git/PyGIT.py

    r3212 r3213  
    303303 
    304304        line = lines.pop(0) 
    305         d = {} 
    306         while line != "": 
    307             (key,value)=line.split(None, 1) 
    308             if not d.has_key(key): 
    309                 d[key] = [] 
    310             d[key].append(value.strip()) 
     305        props = {} 
     306        while line: 
     307            (key,value) = line.split(None, 1) 
     308            props.setdefault(key,[]).append(value.strip()) 
    311309            line = lines.pop(0) 
    312310 
    313         return ("\n".join(lines),d
     311        return ("\n".join(lines), props
    314312 
    315313    def get_file(self, sha): 
     
    409407        return last_rev.strip() 
    410408 
    411     def diff_tree(self, tree1, tree2, path=""): 
     409    def diff_tree(self, tree1, tree2, path="", find_renames=False): 
    412410        """calls `git diff-tree` and returns tuples of the kind 
    413         (mode1,mode2,obj1,obj2,action,path,path2)""" 
     411        (mode1,mode2,obj1,obj2,action,path1,path2)""" 
    414412 
    415413        # diff-tree returns records with the following structure: 
    416         # :<old-mode> <new-mode> <old-sha> <new-sha> <change> NUL <path> NUL [ <src-path> NUL ] 
    417  
    418         lines = self._git_call("diff-tree", 
    419                                ["-z", "-r", 
    420                                 str(tree1) if tree1 else "--root", 
    421                                 str(tree2), 
    422                                 "--", path]).split('\0') 
     414        # :<old-mode> <new-mode> <old-sha> <new-sha> <change> NUL <old-path> NUL [ <new-path> NUL ] 
     415 
     416        diff_tree_args = ["-z", "-r"] 
     417        if find_renames: 
     418            diff_tree_args.append("-M") 
     419        diff_tree_args.extend([str(tree1) if tree1 else "--root", 
     420                               str(tree2), 
     421                               "--", path]) 
     422 
     423        lines = self._git_call("diff-tree", diff_tree_args).split('\0') 
    423424 
    424425        assert lines[-1] == ""