Changeset 3236
- Timestamp:
- 02/15/08 03:36:31 (10 months ago)
- Files:
-
- gitplugin/0.11/tracext/git/PyGIT.py (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
gitplugin/0.11/tracext/git/PyGIT.py
r3213 r3236 17 17 import os, re, sys, time, weakref, threading 18 18 from collections import deque 19 from functools import partial 19 20 #from traceback import print_stack 20 21 … … 25 26 pass 26 27 27 GIT_ CMD= "git"28 GIT_BIN = "git" 28 29 GIT_VERSION_MIN_REQUIRED = (1,5,2) 29 GIT_PROFILE = False 30 31 def _git_execute(gitcmd, git_dir=None, *args):32 if GIT_PROFILE:33 t = time.time()34 35 # construct command tuple36 cmd = [GIT_CMD]37 if git_dir:38 cmd.append('--git-dir=%s' % git_dir)39 cmd.append(gitcmd)40 cmd.extend(args)41 42 # fds = (input, output, error) 43 fds = os.popen3(cmd)44 45 if GIT_PROFILE: 46 t = time.time() - t # doesn't work actually, as popen3 runs async47 print >>sys.stderr, "GIT: took %6.2fs for '%s'" % (t, cmd)48 pass 49 50 return fds30 31 class GitCore: 32 def __init__(self, git_dir=None, git_bin=GIT_BIN): 33 self.__git_bin = git_bin 34 self.__git_dir = git_dir 35 36 def __execute2(self, gitcmd, *args): 37 # construct command tuple 38 cmd = [self.__git_bin] 39 if self.__git_dir: 40 cmd.append('--git-dir=%s' % self.__git_dir) 41 cmd.append(gitcmd) 42 cmd.extend(args) 43 44 #print >>sys.stderr, "GitCore '%s'" % str(cmd) 45 return os.popen3(cmd) # (input, output, error) 46 47 def __execute(self, git_cmd, *cmd_args): 48 return self.__execute2(git_cmd, *cmd_args)[1] 49 50 def __getattr__(self, name): 51 return partial(self.__execute, name.replace('_','-')) 51 52 52 53 def git_version(): 53 54 try: 54 output = _git_execute("version")[1] 55 g = GitCore() 56 output = g.version() 55 57 [v] = output.readlines() 56 58 [a,b,version] = v.strip().split() … … 101 103 102 104 class Storage: 103 def __init__(self, repo, log):105 def __init__(self, git_dir, log): 104 106 self.logger = log 105 107 self.logger.debug("PyGIT.Storage instance %d constructed" % id(self)) 106 108 107 self.repo = repo 109 self.git_dir = git_dir 110 self.repo = GitCore(git_dir) 111 108 112 self.commit_encoding = None 109 113 … … 114 118 def __del__(self): 115 119 self.logger.debug("PyGIT.Storage instance %d destructed" % id(self)) 116 117 def _git_call_f(self, gitcmd, args=[]):118 (input, output, error) = _git_execute(gitcmd, self.repo, *args)119 return output120 121 def _git_call(self, cmd, args=[]):122 return self._git_call_f(cmd, args).read()123 120 124 121 def _invalidate_caches(self,youngest_rev=None): … … 143 140 youngest = None 144 141 ord_rev = 0 145 for revs in self. _git_call_f("rev-parse", ["--tags"]).readlines():142 for revs in self.repo.rev_parse("--tags").readlines(): 146 143 new_tags.add(revs.strip()) 147 144 148 for revs in self. _git_call_f("rev-list", ["--parents", "--all"]).readlines():145 for revs in self.repo.rev_list("--parents", "--all").readlines(): 149 146 revs = revs.strip().split() 150 147 … … 184 181 185 182 def sync(self): 186 rev = self. _git_call("rev-list", ["--max-count=1", "--all"]).strip()183 rev = self.repo.rev_list("--max-count=1", "--all").read().strip() 187 184 return self._invalidate_caches(rev) 188 185 … … 224 221 def get_commit_encoding(self): 225 222 if self.commit_encoding is None: 226 self.commit_encoding = self._git_call("repo-config", 227 ["--get", "i18n.commitEncoding"]).strip() 228 if ''==self.commit_encoding: 229 self.commit_encoding = 'utf-8' 223 self.commit_encoding = \ 224 self.repo.repo_config("--get", "i18n.commitEncoding").read().strip() or 'utf-8' 225 230 226 return self.commit_encoding 231 232 227 233 228 def head(self): … … 245 240 return rev 246 241 247 rc = self. _git_call("rev-parse", ["--verify", rev]).strip()248 if len(rc)==0:242 rc = self.repo.rev_parse("--verify", rev).read().strip() 243 if not rc: 249 244 return None 250 245 251 246 if db.has_key(rc): 252 247 return rc 253 elif rc in tag_db: 254 sha=self._git_call("cat-file", ["tag", rc]).split(None, 2)[:2] 248 249 if rc in tag_db: 250 sha=self.repo.cat_file("tag", rc).read().split(None, 2)[:2] 255 251 if sha[0] != 'object': 256 252 self.logger.debug("unexpected result from 'git-cat-file tag %s'" % rc) … … 262 258 def shortrev(self, rev): 263 259 "try to shorten sha id" 264 return self. _git_call("rev-parse", ["--short", str(rev)]).strip()260 return self.repo.rev_parse("--short", str(rev)).read().strip() 265 261 266 262 def get_branches(self): 267 263 "returns list of (local) branches, with active (= HEAD) one being the first item" 268 264 result=[] 269 for e in self. _git_call_f("branch", ["-v", "--no-abbrev"]).readlines():265 for e in self.repo.branch("-v", "--no-abbrev").readlines(): 270 266 (bname,bsha)=e[1:].strip().split()[:2] 271 267 if e.startswith('*'): … … 276 272 277 273 def get_tags(self): 278 return [e.strip() for e in self. _git_call_f("tag", ["-l"]).readlines()]274 return [e.strip() for e in self.repo.tag("-l").readlines()] 279 275 280 276 def ls_tree(self, rev, path=""): … … 282 278 if path.startswith('/'): 283 279 path = path[1:] 284 return [e.split(None, 3) for e in self._git_call("ls-tree", 285 ["-z", rev, "--", 286 path]).split('\0') if e] 280 return [e.split(None, 3) for e in \ 281 self.repo.ls_tree("-z", rev, "--", path).read().split('\0') if e] 287 282 288 283 def read_commit(self, sha): … … 295 290 raise GitErrorSha 296 291 297 raw = self. _git_call("cat-file", ["commit", str(sha)])292 raw = self.repo.cat_file("commit", str(sha)).read() 298 293 raw = unicode(raw, self.get_commit_encoding(), 'replace') 299 294 lines = raw.splitlines() … … 312 307 313 308 def get_file(self, sha): 314 return self. _git_call_f("cat-file", ["blob", str(sha)])309 return self.repo.cat_file("blob", str(sha)) 315 310 316 311 def get_obj_size(self, sha): 317 312 sha = str(sha) 318 313 try: 319 return int(self. _git_call("cat-file", ["-s", sha]).strip())314 return int(self.repo.cat_file("-s", sha).read().strip()) 320 315 except ValueError: 321 316 raise GitErrorSha("object '%s' not found" % sha) … … 342 337 yield p 343 338 344 #_children = db[p][0]345 339 _children = db[p][0] - seen 346 340 … … 361 355 if limit is None: 362 356 limit = -1 363 for rev in self._git_call_f("rev-list", 364 ["--max-count=%d" % limit, 365 str(sha), "--", path]).readlines(): 357 for rev in self.repo.rev_list("--max-count=%d" % limit, 358 str(sha), "--", path).readlines(): 366 359 yield rev.strip() 367 360 … … 370 363 371 364 def history_timerange(self, start, stop): 372 for rev in self. _git_call_f("rev-list", ["--reverse",373 "--max-age=%d" % start,374 "--min-age=%d" % stop,375 "--all"]).readlines():365 for rev in self.repo.rev_list("--reverse", 366 "--max-age=%d" % start, 367 "--min-age=%d" % stop, 368 "--all").readlines(): 376 369 yield rev.strip() 377 370 … … 384 377 def blame(self, commit_sha, path): 385 378 in_metadata = False 386 args = ["-p", "--", path, str(commit_sha)] 387 for line in self. _git_call_f("blame", args).readlines():379 380 for line in self.repo.blame("-p", "--", path, str(commit_sha)).readlines(): 388 381 assert line 389 382 if in_metadata: … … 403 396 404 397 def last_change(self, sha, path): 405 last_rev = self._git_call("rev-list", 406 ["--max-count=1", sha, "--", path]) 407 return last_rev.strip() 398 return self.repo.rev_list("--max-count=1", sha, "--", path).read().strip() or None 408 399 409 400 def diff_tree(self, tree1, tree2, path="", find_renames=False): … … 421 412 "--", path]) 422 413 423 lines = self. _git_call("diff-tree", diff_tree_args).split('\0')414 lines = self.repo.diff_tree(*diff_tree_args).read().split('\0') 424 415 425 416 assert lines[-1] == ""
