Changeset 3211
- Timestamp:
- 02/11/08 05:23:35 (10 months ago)
- Files:
-
- gitplugin/0.11/tracext/git/git_fs.py (modified) (6 diffs)
- gitplugin/0.11/tracext/git/PyGIT.py (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gitplugin/0.11/tracext/git/git_fs.py
r3210 r3211 27 27 28 28 from datetime import datetime 29 import time 29 import time, sys 30 31 if not sys.version_info[:2] >= (2,5): 32 raise TracError("python >= 2.5 dependancy not met") 30 33 31 34 import pkg_resources … … 34 37 import PyGIT 35 38 39 def _last_iterable(iterable): 40 "helper for detecting last iteration in for-loop" 41 i = iter(iterable) 42 v = i.next() 43 for nextv in i: 44 yield False, v 45 v = nextv 46 yield True, v 36 47 37 48 # helper … … 208 219 209 220 for chg in self.git.diff_tree(old_rev, new_rev, self.normalize_path(new_path)): 210 (mode1,mode2,obj1,obj2,action,path ) = chg221 (mode1,mode2,obj1,obj2,action,path,path2) = chg 211 222 212 223 kind = Node.FILE … … 336 347 337 348 def get_history(self, limit=None): 338 for rev in self.git.history(self.rev, self.__git_path(), limit):339 yield (self.path, rev, Changeset.EDIT )349 for is_last,rev in _last_iterable(self.git.history(self.rev, self.__git_path(), limit)): 350 yield (self.path, rev, Changeset.EDIT if not is_last else Changeset.ADD) 340 351 341 352 def get_last_modified(self): … … 389 400 if 'author' in self.props: 390 401 git_author = _parse_user_time(self.props['author'][0]) 391 if not (properties.has_key('git-committer') and 392 properties['git-committer'] == git_author): 402 if not properties.get('git-committer') == git_author: 393 403 properties['git-author'] = git_author 394 404 … … 396 406 397 407 def get_changes(self): 398 #print "GitChangeset.get_changes" 399 prev = self.props.has_key('parent') and self.props['parent'][0] or None 400 for chg in self.git.diff_tree(prev, self.rev): 401 (mode1,mode2,obj1,obj2,action,path) = chg 402 403 kind = Node.FILE 404 if mode2.startswith('04') or mode1.startswith('04'): 405 kind = Node.DIRECTORY 406 407 change = GitChangeset.action_map[action] 408 409 yield (path, kind, change, path, prev) 408 # TODO: handle renames/removals 409 for parent in self.props.get('parent', [None]): 410 for mode1,mode2,obj1,obj2,action,path,path2 in \ 411 self.git.diff_tree(parent, self.rev): 412 p_path, p_rev = path, parent 413 414 kind = Node.FILE 415 if mode2.startswith('04') or mode1.startswith('04'): 416 kind = Node.DIRECTORY 417 418 action = GitChangeset.action_map[action] 419 420 if action == Changeset.ADD: 421 p_path = '' 422 p_rev = None 423 424 yield (path, kind, action, p_path, p_rev) gitplugin/0.11/tracext/git/PyGIT.py
r3205 r3211 13 13 # GNU General Public License for more details. 14 14 15 from __future__ import with_statement 16 15 17 import os, re, sys, time, weakref, threading 16 18 from collections import deque … … 73 75 self.logger = log 74 76 75 StorageFactory.__dict_lock.acquire() 76 77 try: 78 i = StorageFactory.__dict[repo] 79 except KeyError: 80 i = Storage(repo, log) 81 StorageFactory.__dict[repo] = i 82 83 # create or remove additional reference depending on 'weak' argument 84 if weak: 77 with StorageFactory.__dict_lock: 85 78 try: 86 del StorageFactory.__dict_nonweak[repo]79 i = StorageFactory.__dict[repo] 87 80 except KeyError: 88 pass 89 else: 90 StorageFactory.__dict_nonweak[repo] = i 91 92 StorageFactory.__dict_lock.release() 81 i = Storage(repo, log) 82 StorageFactory.__dict[repo] = i 83 84 # create or remove additional reference depending on 'weak' argument 85 if weak: 86 try: 87 del StorageFactory.__dict_nonweak[repo] 88 except KeyError: 89 pass 90 else: 91 StorageFactory.__dict_nonweak[repo] = i 93 92 94 93 self.__inst = i … … 124 123 125 124 def _invalidate_caches(self,youngest_rev=None): 126 self._lock.acquire() 127 128 rc = False 129 130 if self.last_youngest_rev != youngest_rev: 131 self.logger.debug("invalidated caches (%s != %s)" % (self.last_youngest_rev, youngest_rev)) 132 rc = True 133 self._commit_db = None 134 self._oldest_rev = None 135 self.last_youngest_rev = None 136 137 self._lock.release() 138 return rc 125 with self._lock: 126 rc = False 127 if self.last_youngest_rev != youngest_rev: 128 self.logger.debug("invalidated caches (%s != %s)" % (self.last_youngest_rev, youngest_rev)) 129 rc = True 130 self._commit_db = None 131 self._oldest_rev = None 132 self.last_youngest_rev = None 133 134 return rc 139 135 140 136 def get_commits(self): 141 self._lock.acquire() 142 if self._commit_db is None: 143 self.logger.debug("triggered rebuild of commit tree db for %d" % id(self)) 144 new_db = {} 145 new_tags = set([]) 146 parent = None 147 youngest = None 148 ord_rev = 0 149 for revs in self._git_call_f("rev-parse", ["--tags"]).readlines(): 150 new_tags.add(revs.strip()) 151 152 for revs in self._git_call_f("rev-list", ["--parents", "--all"]).readlines(): 153 revs = revs.strip().split() 154 155 rev = revs[0] 156 parents = set(revs[1:]) 157 158 ord_rev += 1 159 160 if not youngest: 161 youngest = rev 162 163 # new_db[rev] = (children(rev), parents(rev), ordinal_id(rev)) 164 if new_db.has_key(rev): 165 _children,_parents,_ord_rev = new_db[rev] 166 assert _children 167 assert not _parents 168 assert _ord_rev == 0 169 new_db[rev] = (_children, parents, ord_rev) 170 else: 171 new_db[rev] = (set(), parents, ord_rev) 172 173 # update all parents(rev)'s children 174 for parent in parents: 175 if new_db.has_key(parent): 176 new_db[parent][0].add(rev) 137 with self._lock: 138 if self._commit_db is None: 139 self.logger.debug("triggered rebuild of commit tree db for %d" % id(self)) 140 new_db = {} 141 new_tags = set([]) 142 parent = None 143 youngest = None 144 ord_rev = 0 145 for revs in self._git_call_f("rev-parse", ["--tags"]).readlines(): 146 new_tags.add(revs.strip()) 147 148 for revs in self._git_call_f("rev-list", ["--parents", "--all"]).readlines(): 149 revs = revs.strip().split() 150 151 rev = revs[0] 152 parents = set(revs[1:]) 153 154 ord_rev += 1 155 156 if not youngest: 157 youngest = rev 158 159 # new_db[rev] = (children(rev), parents(rev), ordinal_id(rev)) 160 if new_db.has_key(rev): 161 _children,_parents,_ord_rev = new_db[rev] 162 assert _children 163 assert not _parents 164 assert _ord_rev == 0 165 new_db[rev] = (_children, parents, ord_rev) 177 166 else: 178 new_db[parent] = (set([rev]), set(), 0) # dummy ordinal_id 179 180 self._commit_db = new_db, parent, new_tags 181 self.last_youngest_rev = youngest 182 self.logger.debug("rebuilt commit tree db for %d with %d entries" % (id(self),len(new_db))) 183 184 self._lock.release() 185 186 assert self._commit_db[1] is not None 187 assert self._commit_db[0] is not None 188 189 return self._commit_db[0] 167 new_db[rev] = (set(), parents, ord_rev) 168 169 # update all parents(rev)'s children 170 for parent in parents: 171 if new_db.has_key(parent): 172 new_db[parent][0].add(rev) 173 else: 174 new_db[parent] = (set([rev]), set(), 0) # dummy ordinal_id 175 176 self._commit_db = new_db, parent, new_tags 177 self.last_youngest_rev = youngest 178 self.logger.debug("rebuilt commit tree db for %d with %d entries" % (id(self),len(new_db))) 179 180 assert self._commit_db[1] is not None 181 assert self._commit_db[0] is not None 182 183 return self._commit_db[0] 190 184 191 185 def sync(self): … … 419 413 420 414 def diff_tree(self, tree1, tree2, path=""): 415 """calls `git diff-tree` and returns tuples of the kind 416 (mode1,mode2,obj1,obj2,action,path,path2)""" 417 418 # diff-tree returns records with the following structure: 419 # :<old-mode> <new-mode> <old-sha> <new-sha> <change> NUL <path> NUL [ <src-path> NUL ] 420 421 lines = self._git_call("diff-tree", 422 ["-z", "-r", 423 str(tree1) if tree1 else "--root", 424 str(tree2), 425 "--", path]).split('\0') 426 427 assert lines[-1] == "" 428 del lines[-1] 429 421 430 if tree1 is None: 422 tree1 = "--root"423 424 next_is_path = False425 for chg in self._git_call("diff-tree", ["-z", "-r",426 str(tree1), 427 str(tree2),428 "--", path]).split('\0'): 429 if not chg:430 assert not next_is_path431 c ontinue432 433 if next_is_path:434 next_is_path = False 435 path = chg436 yield (mode1,mode2,obj1,obj2,action,path)437 continue438 439 if not chg.startswith(':'): 440 c ontinue441 442 (mode1,mode2,obj1,obj2,action) = chg.split(None)443 mode1 = mode1[1:]444 next_is_path = True 445 446 assert not next_is_path431 # if only one tree-sha is given on commandline, 432 # the first line is just the redundant tree-sha itself... 433 assert not lines[0].startswith(':') 434 del lines[0] 435 436 chg = None 437 438 def __chg_tuple(): 439 if len(chg) == 6: 440 chg.append(None) 441 assert len(chg) == 7 442 return tuple(chg) 443 444 for line in lines: 445 if line.startswith(':'): 446 if chg: 447 yield __chg_tuple() 448 449 chg = line[1:].split() 450 assert len(chg) == 5 451 else: 452 chg.append(line) 453 454 if chg: 455 yield __chg_tuple() 447 456 448 457 if __name__ == '__main__':
