Changeset 3209

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

GitPlugin: cleanups, factorizations, and minor fixes

Files:

Legend:

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

    r3208 r3209  
    3434import PyGIT 
    3535 
     36 
     37# helper 
     38def _parse_user_time(s): 
     39        """parse author/committer attribute lines and return 
     40        (user,timestamp)""" 
     41        (user,time,tz_str) = s.rsplit(None, 2) 
     42        tz = FixedOffset((int(tz_str)*6)/10, tz_str) 
     43        time = datetime.fromtimestamp(float(time), tz) 
     44        return (user,time) 
     45 
    3646class GitConnector(Component): 
    3747        implements(IRepositoryConnector, IWikiSyntaxProvider, IPropertyRenderer) 
     
    6878        # relied upon by GitChangeset 
    6979 
    70         _rendered_props = ('Parents','Children','git-committer','git-author') 
    71  
    7280        def match_property(self, name, mode): 
    7381                if name in ('Parents','Children','git-committer','git-author') \ 
     
    163171 
    164172        def normalize_rev(self, rev): 
    165                 if rev=='None' or rev == None or rev == '': 
     173                if not rev or rev=='None': 
    166174                        return self.get_youngest_rev() 
    167175                normrev=self.git.verifyrev(rev) 
     
    174182 
    175183        def get_node(self, path, rev=None): 
    176                 return GitNode(self.git, path, rev
     184                return GitNode(self.git, path, rev, self.log
    177185 
    178186        def get_quickjump_entries(self, rev): 
     
    202210                        (mode1,mode2,obj1,obj2,action,path) = chg 
    203211 
    204                         if mode2[0] == '1' or mode2[0] == '1': 
     212                        kind = Node.FILE 
     213                        if mode2.startswith('04') or mode1.startswith('04'): 
    205214                                kind = Node.DIRECTORY 
    206                         else: 
    207                                 kind = Node.FILE 
    208215 
    209216                        change = GitChangeset.action_map[action] 
     
    245252 
    246253class GitNode(Node): 
    247         def __init__(self, git, path, rev, ls_tree_info=None): 
     254        def __init__(self, git, path, rev, log, ls_tree_info=None): 
     255                self.log = log 
    248256                self.git = git 
    249                 self.sha = None 
    250                 self.perm = None 
    251                 self.data_len = None 
     257                self.fs_sha = None # points to either tree or blobs 
     258                self.fs_perm = None 
     259                self.fs_size = None 
    252260 
    253261                kind = Node.DIRECTORY 
    254262                p = path.strip('/') 
    255                 if p != "": 
    256                         if ls_tree_info == None or ls_tree_info == ""
    257                                 ls_tree_info = git.ls_tree(rev, p) 
    258                                 if ls_tree_info != []
     263                if p: # ie. not the root-tree 
     264                        if not ls_tree_info
     265                                ls_tree_info = git.ls_tree(rev, p) or None 
     266                                if ls_tree_info
    259267                                        [ls_tree_info] = ls_tree_info 
    260                                 else: 
    261                                         ls_tree_info = None 
    262  
    263                         if ls_tree_info != None: 
    264                                 (self.perm, k, self.sha, fn) = ls_tree_info 
    265                         else: 
    266                                 k = 'blob' 
    267  
    268                         rev = self.git.last_change(rev, p) # FIXME 
     268 
     269                        if not ls_tree_info: 
     270                                raise NoSuchNode(path, rev) 
     271 
     272                        (self.fs_perm, k, self.fs_sha, fn) = ls_tree_info 
     273 
     274                        # fix-up to the last commit-rev that touched this node 
     275                        rev = self.git.last_change(rev, p) 
    269276 
    270277                        if k=='tree': 
     
    273280                                kind = Node.FILE 
    274281                        else: 
    275                                 self.log.debug("kind is "+k) 
    276  
    277                 Node.__init__(self, path, rev, kind) 
     282                                raise TracError("internal error (got unexpected object kind '%s')" % k) 
    278283 
    279284                self.created_path = path 
    280285                self.created_rev = rev 
    281286 
     287                Node.__init__(self, path, rev, kind) 
     288 
     289        def __git_path(self): 
     290                "return path as expected by PyGIT" 
     291                p = self.path.strip('/') 
     292                if self.isfile: 
     293                        assert p 
     294                        return p 
     295                if self.isdir: 
     296                        return p and (p + '/') 
     297 
     298                raise TracError("internal error") 
     299 
    282300        def get_content(self): 
    283                 #print "get_content ", self.path, self.sha 
    284                 if self.isfile: 
    285                         return self.git.get_file(self.sha) 
    286  
    287                 return None 
     301                if not self.isfile: 
     302                        return None 
     303 
     304                return self.git.get_file(self.fs_sha) 
    288305 
    289306        def get_properties(self): 
    290                 if self.perm: 
    291                         return {'mode': self.perm } 
    292                 return {} 
     307                return self.fs_perm and {'mode': self.fs_perm } or {} 
    293308 
    294309        def get_annotations(self): 
    295                 p = self.path.strip('/') 
    296310                if not self.isfile: 
    297311                        return 
    298312 
    299                 result = [] 
    300                 for brev,blineno in self.git.blame(self.rev, p): 
    301                         result.append(brev) 
    302  
    303                 return result 
     313                return [ rev for (rev,lineno) in self.git.blame(self.rev, self.__git_path()) ] 
    304314 
    305315        def get_entries(self): 
     
    307317                        return 
    308318 
    309                 p = self.path.strip('/') 
    310                 if p != '': p = p + '/' 
    311                 for e in self.git.ls_tree(self.rev, p): 
    312                         yield GitNode(self.git, e[3], self.rev, e) 
     319                for e in self.git.ls_tree(self.rev, self.__git_path()): 
     320                        yield GitNode(self.git, e[3], self.rev, self.log, e) 
    313321 
    314322        def get_content_type(self): 
    315323                if self.isdir: 
    316324                        return None 
     325 
    317326                return '' 
    318327 
    319328        def get_content_length(self): 
    320                 if self.isfile: 
    321                         if not self.data_len: 
    322                                 self.data_len = self.git.get_obj_size(self.sha) 
    323                         return self.data_len 
    324                 return None 
     329                if not self.isfile: 
     330                        return None 
     331 
     332                if self.fs_size is None: 
     333                        self.fs_size = self.git.get_obj_size(self.fs_sha) 
     334 
     335                return self.fs_size 
    325336 
    326337        def get_history(self, limit=None): 
    327                 #print "get_history", limit, self.path 
    328                 p = self.path.strip('/') 
    329                 for rev in self.git.history(self.rev, p, limit): 
     338                for rev in self.git.history(self.rev, self.__git_path(), limit): 
    330339                        yield (self.path, rev, Changeset.EDIT) 
    331340 
     
    340349                'D': Changeset.DELETE  
    341350                } 
    342  
    343         # helper 
    344         def __parse_user_time(self, s): 
    345                 """parse author/committer attribute lines and return 
    346                 (user,timestamp)""" 
    347                 (user,time,tz_str) = s.rsplit(None, 2) 
    348                 tz = FixedOffset((int(tz_str)*6)/10, tz_str) 
    349                 time = datetime.fromtimestamp(float(time), tz) 
    350                 return (user,time) 
    351351 
    352352        def __init__(self, git, sha): 
     
    364364 
    365365                # use 1st committer as changeset owner/timestamp 
    366                 (user_, time_) = self.__parse_user_time(props['committer'][0]) 
     366                (user_, time_) = _parse_user_time(props['committer'][0]) 
    367367 
    368368                Changeset.__init__(self, sha, msg, user_, time_) 
     
    376376                if 'committer' in self.props: 
    377377                        properties['git-committer'] = \ 
    378                             self.__parse_user_time(self.props['committer'][0]) 
     378                            _parse_user_time(self.props['committer'][0]) 
    379379                if 'author' in self.props: 
    380                         git_author = self.__parse_user_time(self.props['author'][0]) 
     380                        git_author = _parse_user_time(self.props['author'][0]) 
    381381                        if not (properties.has_key('git-committer') and 
    382382                                properties['git-committer'] == git_author): 
     
    390390                for chg in self.git.diff_tree(prev, self.rev): 
    391391                        (mode1,mode2,obj1,obj2,action,path) = chg 
     392 
    392393                        kind = Node.FILE 
    393                         if mode1[0:1] == '04' or mode2[0:1] == '04'
     394                        if mode2.startswith('04') or mode1.startswith('04')
    394395                                kind = Node.DIRECTORY 
    395396