root/0.10/gitplugin/git_fs.py

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

Add a quick hack to prevent code 500 errors and tracebacks when viewing deleted files.
Instead shows an empty file, for now.

  • 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 == None or tree_ls_info == "":
129                                 tree_ls_info = git.tree_ls(rev, p)
130                                 if tree_ls_info != []:
131                                         [tree_ls_info] = tree_ls_info
132                                 else:
133                                         tree_ls_info = None
134
135                         if tree_ls_info != None:
136                                 (self.perm,k,self.sha,fn) = tree_ls_info
137                         else:
138                                 k = 'blob'
139
140                         rev=self.git.last_change(rev, p)
141
142                         if k=='tree':
143                                 pass
144                         elif k=='blob':
145                                 kind = Node.FILE
146                         else:
147                                 self.log.debug("kind is "+k)
148                        
149                 Node.__init__(self, path, rev, kind)
150
151                 self.created_path = path
152                 self.created_rev = rev
153
154         def get_content(self):
155                 #print "get_content ", self.path, self.sha
156                 if self.isfile:
157                         return self.git.get_file(self.sha)
158                        
159                 return None
160
161         def get_properties(self):
162                 if self.perm:
163                         return {'mode': self.perm }
164                 return {}
165
166         def get_entries(self):
167                 if self.isfile:
168                         return
169                 if not self.isdir:
170                         return
171                
172                 p = self.path.strip('/')
173                 if p != '': p = p + '/'
174                 for e in self.git.tree_ls(self.rev, p):
175                         yield GitNode(self.git, e[3], self.rev, e)
176        
177         def get_content_type(self):
178                 if self.isdir:
179                         return None
180                 return ''
181
182         def get_content_length(self):
183                 if self.isfile:
184                         if not self.data_len:
185                                 self.data_len = self.git.get_obj_size(self.sha)
186                         return self.data_len
187                 return None
188
189         def get_history(self, limit=None):
190                 p = self.path.strip('/')
191                 for rev in self.git.history(self.rev, p):
192                         yield (self.path, rev, Changeset.EDIT)
193
194         def get_last_modified(self):
195                 return None
196
197 class GitChangeset(Changeset):
198         def __init__(self, git, sha):
199                 self.git = git
200                 (msg,props) = git.read_commit(sha)
201                 self.props = props
202
203                 committer = props['committer'][0]
204                 (user,time,tz) = committer.rsplit(None, 2)
205                
206                 Changeset.__init__(self, sha, msg, user, float(time))
207
208         def get_properties(self):
209                 for k in self.props:
210                         v = self.props[k]
211                         if k in ['committer', 'author']:
212                                 yield("git-"+k, ", ".join(v), False, 'author')
213                         if k in ['parent']:
214                                 yield("git-"+k, ", ".join(("[%s]" % c) for c in v), True, 'changeset')
215
216         def get_changes(self):
217                 #print "GitChangeset.get_changes"
218                 prev = self.props.has_key('parent') and self.props['parent'][0] or None
219                 for chg in self.git.diff_tree(prev, self.rev):
220                         #print chg
221                         (mode1,mode2,obj1,obj2,action,path) = chg
222                         kind = Node.FILE
223                         if mode1[0:1] == '04' or mode2[0:1] == '04':
224                                 kind = Node.DIRECTORY
225                                
226                         if action == 'A':
227                                 change = Changeset.ADD
228                         elif action == 'M':
229                                 change = Changeset.EDIT
230                         elif action == 'D':
231                                 change = Changeset.DELETE
232                         else:
233                                 raise "OhOh"
234
235                         yield (path, kind, change, path, prev)
Note: See TracBrowser for help on using the browser.