root/0.10/gitplugin/git_fs.py

Revision 1cb54953fbcf6974f3a587598db9fd7e59dcbbbe, 5.6 kB (checked in by Hans Petter Jansson <hpj@kzerza.site>, 6 years ago)

Add a dummy get_last_modified() to avoid an exception in Trac.

  • 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, NoSuchChangeset, NoSuchNode
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.Storage(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                 normrev=self.git.verifyrev(rev)
47                 if normrev is None:
48                         raise NoSuchChangeset(rev)
49                 return normrev
50
51         def short_rev(self, rev):
52                 return self.git.shortrev(self.normalize_rev(rev))
53
54         def get_oldest_rev(self):
55                 return ""
56
57         def get_node(self, path, rev=None):
58                 #print "get_node", path, rev
59                 return GitNode(self.git, path, rev)
60
61         def get_changeset(self, rev):
62                 #print "get_changeset", rev
63                 return GitChangeset(self.git, rev)
64
65         def get_changes(self, old_path, old_rev, new_path, new_rev):
66                 if old_path != new_path:
67                         raise TracError("not supported in git_fs")
68                 #print "get_changes", (old_path, old_rev, new_path, new_rev)
69
70                 for chg in self.git.diff_tree(old_rev, new_rev, self.normalize_path(new_path)):
71                         #print chg
72                         (mode1,mode2,obj1,obj2,action,path) = chg
73                         kind = Node.FILE
74                         if mode2[0] == '1' or mode2[0] == '1':
75                                 kind = Node.DIRECTORY
76                                
77                         if action == 'A':
78                                 change = Changeset.ADD
79                         elif action == 'M':
80                                 change = Changeset.EDIT
81                         elif action == 'D':
82                                 change = Changeset.DELETE
83                         else:
84                                 raise "OhOh"
85
86                         old_node = None
87                         new_node = None
88
89                         if change != Changeset.ADD:
90                                 old_node = self.get_node(path, old_rev)
91                         if change != Changeset.DELETE:
92                                 new_node = self.get_node(path, new_rev)
93
94                         yield (old_node, new_node, kind, change)
95
96         def next_rev(self, rev, path=''):
97                 #print "next_rev"
98                 for c in self.git.children(rev):
99                         return c
100                 return None
101
102         def previous_rev(self, rev):
103                 #print "previous_rev"
104                 for p in self.git.parents(rev):
105                         return p
106                 return None
107
108         def rev_older_than(self, rev1, rev2):
109                 rc = rev1 in self.git.history(rev2, '', 1)
110                 #print "rev_older_than", (rev1, rev2, rc)
111                 return rc
112
113         def sync(self):
114                 #print "GitRepository.sync"
115                 pass
116
117
118 class GitNode(Node):
119         def __init__(self, git, path, rev, tree_ls_info=None):
120                 self.git = git
121                 self.sha = rev
122                 self.perm = None
123                 self.data_len = None
124                
125                 kind = Node.DIRECTORY
126                 p = path.strip('/')
127                 if p != "":
128                         if tree_ls_info:
129                                 (self.perm,k,self.sha,fn)=tree_ls_info
130                         else:
131                                 [(self.perm,k,self.sha,fn)]=git.tree_ls(rev, p)
132                         rev=self.git.last_change(rev, p)
133                         if k=='tree':
134                                 pass
135                         elif k=='blob':
136                                 kind = Node.FILE
137                         else:
138                                 self.log.debug("kind is "+k)
139                        
140                 Node.__init__(self, path, rev, kind)
141
142                 self.created_path = path
143                 self.created_rev = rev
144
145         def get_content(self):
146                 #print "get_content ", self.path, self.sha
147                 if self.isfile:
148                         return self.git.get_file(self.sha)
149                        
150                 return None
151
152         def get_properties(self):
153                 if self.perm:
154                         return {'mode': self.perm }
155                 return {}
156
157         def get_entries(self):
158                 if self.isfile:
159                         return
160                 if not self.isdir:
161                         return
162                
163                 p = self.path.strip('/')
164                 if p != '': p = p + '/'
165                 for e in self.git.tree_ls(self.rev, p):
166                         yield GitNode(self.git, e[3], self.rev, e)
167        
168         def get_content_type(self):
169                 if self.isdir:
170                         return None
171                 return ''
172
173         def get_content_length(self):
174                 if self.isfile:
175                         if not self.data_len:
176                                 self.data_len = self.git.get_obj_size(self.sha)
177                         return self.data_len
178                 return None
179
180         def get_history(self, limit=None):
181                 p = self.path.strip('/')
182                 for rev in self.git.history(self.rev, p):
183                         yield (self.path, rev, Changeset.EDIT)
184
185         def get_last_modified(self):
186                 return None
187
188 class GitChangeset(Changeset):
189         def __init__(self, git, sha):
190                 self.git = git
191                 (msg,props) = git.read_commit(sha)
192                 self.props = props
193
194                 committer = props['committer'][0]
195                 (user,time,tz) = committer.rsplit(None, 2)
196                
197                 Changeset.__init__(self, sha, msg, user, float(time))
198
199         def get_properties(self):
200                 for k in self.props:
201                         v = self.props[k]
202                         if k in ['committer', 'author']:
203                                 yield("git-"+k, ", ".join(v), False, 'author')
204                         if k in ['parent']:
205                                 yield("git-"+k, ", ".join(("[%s]" % c) for c in v), True, 'changeset')
206
207         def get_changes(self):
208                 #print "GitChangeset.get_changes"
209                 prev = self.props.has_key('parent') and self.props['parent'][0] or None
210                 for chg in self.git.diff_tree(prev, self.rev):
211                         #print chg
212                         (mode1,mode2,obj1,obj2,action,path) = chg
213                         kind = Node.FILE
214                         if mode1[0:1] == '04' or mode2[0:1] == '04':
215                                 kind = Node.DIRECTORY
216                                
217                         if action == 'A':
218                                 change = Changeset.ADD
219                         elif action == 'M':
220                                 change = Changeset.EDIT
221                         elif action == 'D':
222                                 change = Changeset.DELETE
223                         else:
224                                 raise "OhOh"
225
226                         yield (path, kind, change, path, prev)
Note: See TracBrowser for help on using the browser.