root/0.10/gitplugin/git_fs.py

Revision 8d3d445ef5102f3286ee81ae431f3c23c49dcbdd, 5.2 kB (checked in by hvr <hvr@7322e99d-02ea-0310-aa39-e9a107903beb>, 8 years ago)

GitPlugin?:

initial import

git-svn-id: http://trac-hacks.org/svn/gitplugin@1319 7322e99d-02ea-0310-aa39-e9a107903beb

  • Property mode set to 100644
Line 
1 # -*- coding: iso-8859-1 -*-
2 #
3 # Copyright (C) 2006 Herbert Valerio Riedel <hvr@gnu.org>
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 from trac.core import *
16 from trac.util import TracError, shorten_line, escape
17 from trac.versioncontrol import Changeset, Node, Repository, \
18                                 IRepositoryConnector
19
20 import PyGIT
21
22 class GitConnector(Component):
23         implements(IRepositoryConnector)
24
25         def get_supported_types(self):
26                 yield ("git", 8)
27
28         def get_repository(self, type, dir, authname):
29                 return GitRepository(dir, self.log)
30
31 class GitRepository(Repository):
32         def __init__(self, path, log):
33                 self.gitrepo = path
34                 self.git = PyGIT.GIT(path)
35                 Repository.__init__(self, "git:"+path, None, log)
36
37         def get_youngest_rev(self):
38                 return self.git.head()
39
40         def normalize_path(self, path):
41                 return path and path.strip('/') or ''
42
43         def normalize_rev(self, rev):
44                 if rev=='None' or rev == None or rev == '':
45                         return self.get_youngest_rev()
46                 return rev
47
48         def get_oldest_rev(self):
49                 return ""
50
51         def get_node(self, path, rev=None):
52                 #print "get_node", path, rev
53                 return GitNode(self.git, path, rev)
54
55         def get_changeset(self, rev):
56                 #print "get_changeset", rev
57                 return GitChangeset(self.git, rev)
58
59         def get_changes(self, old_path, old_rev, new_path, new_rev):
60                 if old_path != new_path:
61                         raise TracError("not supported in git_fs")
62                 #print "get_changes", (old_path, old_rev, new_path, new_rev)
63
64                 for chg in self.git.diff_tree(old_rev, new_rev, self.normalize_path(new_path)):
65                         #print chg
66                         (mode1,mode2,obj1,obj2,action,path) = chg
67                         kind = Node.FILE
68                         if mode2[0] == '1' or mode2[0] == '1':
69                                 kind = Node.DIRECTORY
70                                
71                         if action == 'A':
72                                 change = Changeset.ADD
73                         elif action == 'M':
74                                 change = Changeset.EDIT
75                         elif action == 'D':
76                                 change = Changeset.DELETE
77                         else:
78                                 raise "OhOh"
79
80                         old_node = None
81                         new_node = None
82
83                         if change != Changeset.ADD:
84                                 old_node = self.get_node(path, old_rev)
85                         if change != Changeset.DELETE:
86                                 new_node = self.get_node(path, new_rev)
87
88                         yield (old_node, new_node, kind, change)
89
90         def next_rev(self, rev, path=''):
91                 #print "next_rev"
92                 for c in self.git.children(rev):
93                         return c
94                 return None
95
96         def previous_rev(self, rev):
97                 #print "previous_rev"
98                 for p in self.git.parents(rev):
99                         return p
100                 return None
101
102         def rev_older_than(self, rev1, rev2):
103                 rc = rev1 in self.git.history(rev2, '', 1)
104                 #print "rev_older_than", (rev1, rev2, rc)
105                 return rc
106
107         def sync(self):
108                 #print "GitRepository.sync"
109                 pass
110
111
112 class GitNode(Node):
113         def __init__(self, git, path, rev):
114                 self.git = git
115                 self.sha = rev;
116                 self.perm = None;
117                 kind = Node.DIRECTORY
118                 p = path.strip('/')
119                 if p != "":
120                         [(self.perm,k,self.sha,fn)]=git.tree_ls(rev, p)
121                         rev=self.git.last_change(rev, p)
122                         if k=='tree':
123                                 pass
124                         elif k=='blob':
125                                 kind = Node.FILE
126                         else:
127                                 self.log.debug("kind is "+k)
128                        
129                 Node.__init__(self, path, rev, kind)
130
131                 self.created_path = path
132                 self.created_rev = rev
133
134         def get_content(self):
135                 #print "get_content ", self.path, self.sha
136                 if self.isfile:
137                         return self.git.get_file(self.sha)
138                        
139                 return None
140
141         def get_properties(self):
142                 if self.perm:
143                         return {'mode': self.perm }
144                 return {}
145
146         def get_entries(self):
147                 if self.isfile:
148                         return
149                 if not self.isdir:
150                         return
151                
152                 p = self.path.strip('/')
153                 if p != '': p = p + '/'
154                 for e in self.git.tree_ls(self.rev, p):
155                         yield GitNode(self.git, e[3], self.rev)
156        
157         def get_content_type(self):
158                 if self.isdir:
159                         return None
160                 return ''
161
162         def get_content_length(self):
163                 if self.isfile:
164                         return len(self.get_content().read())
165                 return None
166
167         def get_history(self, limit=None):
168                 p = self.path.strip('/')
169                 for rev in self.git.history(self.rev, p):
170                         yield (self.path, rev, Changeset.EDIT)
171
172
173 class GitChangeset(Changeset):
174         def __init__(self, git, sha):
175                 self.git = git
176                 (msg,props) = git.read_commit(sha)
177                 self.props = props
178
179                 committer = props['committer'][0]
180                 (user,time,tz) = committer.rsplit(None, 2)
181                
182                 Changeset.__init__(self, sha, msg, user, float(time))
183
184         def get_properties(self):
185                 for k in self.props:
186                         v = self.props[k]
187                         if k in ['committer', 'author']:
188                                 yield("git-"+k, ", ".join(v), False, 'author')
189                         if k in ['parent']:
190                                 yield("git-"+k, ", ".join(("[%s]" % c) for c in v), True, 'changeset')
191
192         def get_changes(self):
193                 #print "GitChangeset.get_changes"
194                 prev = self.props.has_key('parent') and self.props['parent'][0] or None
195                 for chg in self.git.diff_tree(prev, self.rev):
196                         #print chg
197                         (mode1,mode2,obj1,obj2,action,path) = chg
198                         kind = Node.FILE
199                         if mode1[0:1] == '04' or mode2[0:1] == '04':
200                                 kind = Node.DIRECTORY
201                                
202                         if action == 'A':
203                                 change = Changeset.ADD
204                         elif action == 'M':
205                                 change = Changeset.EDIT
206                         elif action == 'D':
207                                 change = Changeset.DELETE
208                         else:
209                                 raise "OhOh"
210
211                         yield (path, kind, change, path, prev)
Note: See TracBrowser for help on using the browser.