Changeset 3236

Show
Ignore:
Timestamp:
02/15/08 03:36:31 (10 months ago)
Author:
hvr
Message:

GitPlugin: refactorized git-core execution by introducing a new class GitCore

Files:

Legend:

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

    r3213 r3236  
    1717import os, re, sys, time, weakref, threading 
    1818from collections import deque 
     19from functools import partial 
    1920#from traceback import print_stack 
    2021 
     
    2526    pass 
    2627 
    27 GIT_CMD = "git" 
     28GIT_BIN = "git" 
    2829GIT_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 tuple 
    36     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 async 
    47         print >>sys.stderr, "GIT: took %6.2fs for '%s'" % (t, cmd) 
    48         pass 
    49  
    50     return fds 
     30 
     31class 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('_','-')) 
    5152 
    5253def git_version(): 
    5354    try: 
    54         output = _git_execute("version")[1] 
     55        g = GitCore() 
     56        output = g.version() 
    5557        [v] = output.readlines() 
    5658        [a,b,version] = v.strip().split() 
     
    101103 
    102104class Storage: 
    103     def __init__(self, repo, log): 
     105    def __init__(self, git_dir, log): 
    104106        self.logger = log 
    105107        self.logger.debug("PyGIT.Storage instance %d constructed" % id(self)) 
    106108 
    107         self.repo = repo 
     109        self.git_dir = git_dir 
     110        self.repo = GitCore(git_dir) 
     111 
    108112        self.commit_encoding = None 
    109113 
     
    114118    def __del__(self): 
    115119        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 output 
    120  
    121     def _git_call(self, cmd, args=[]): 
    122         return self._git_call_f(cmd, args).read() 
    123120 
    124121    def _invalidate_caches(self,youngest_rev=None): 
     
    143140                youngest = None 
    144141                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(): 
    146143                    new_tags.add(revs.strip()) 
    147144 
    148                 for revs in self._git_call_f("rev-list", ["--parents", "--all"]).readlines(): 
     145                for revs in self.repo.rev_list("--parents", "--all").readlines(): 
    149146                    revs = revs.strip().split() 
    150147 
     
    184181 
    185182    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() 
    187184        return self._invalidate_caches(rev) 
    188185 
     
    224221    def get_commit_encoding(self): 
    225222        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 
    230226        return self.commit_encoding 
    231  
    232227 
    233228    def head(self): 
     
    245240            return rev 
    246241 
    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
    249244            return None 
    250245 
    251246        if db.has_key(rc): 
    252247            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] 
    255251            if sha[0] != 'object': 
    256252                self.logger.debug("unexpected result from 'git-cat-file tag %s'" % rc) 
     
    262258    def shortrev(self, rev): 
    263259        "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() 
    265261 
    266262    def get_branches(self): 
    267263        "returns list of (local) branches, with active (= HEAD) one being the first item" 
    268264        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(): 
    270266            (bname,bsha)=e[1:].strip().split()[:2] 
    271267            if e.startswith('*'): 
     
    276272 
    277273    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()] 
    279275 
    280276    def ls_tree(self, rev, path=""): 
     
    282278        if path.startswith('/'): 
    283279            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] 
    287282 
    288283    def read_commit(self, sha): 
     
    295290            raise GitErrorSha 
    296291 
    297         raw = self._git_call("cat-file", ["commit", str(sha)]
     292        raw = self.repo.cat_file("commit", str(sha)).read(
    298293        raw = unicode(raw, self.get_commit_encoding(), 'replace') 
    299294        lines = raw.splitlines() 
     
    312307 
    313308    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)
    315310 
    316311    def get_obj_size(self, sha): 
    317312        sha = str(sha) 
    318313        try: 
    319             return int(self._git_call("cat-file", ["-s", sha]).strip()) 
     314            return int(self.repo.cat_file("-s", sha).read().strip()) 
    320315        except ValueError: 
    321316            raise GitErrorSha("object '%s' not found" % sha) 
     
    342337            yield p 
    343338 
    344             #_children = db[p][0] 
    345339            _children = db[p][0] - seen 
    346340 
     
    361355        if limit is None: 
    362356            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(): 
    366359            yield rev.strip() 
    367360 
     
    370363 
    371364    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(): 
    376369            yield rev.strip() 
    377370 
     
    384377    def blame(self, commit_sha, path): 
    385378        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(): 
    388381            assert line 
    389382            if in_metadata: 
     
    403396 
    404397    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 
    408399 
    409400    def diff_tree(self, tree1, tree2, path="", find_renames=False): 
     
    421412                               "--", path]) 
    422413 
    423         lines = self._git_call("diff-tree", diff_tree_args).split('\0') 
     414        lines = self.repo.diff_tree(*diff_tree_args).read().split('\0') 
    424415 
    425416        assert lines[-1] == ""