| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
7 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -20,6 +20,7 @@ | |||
| 20 | 20 | from git.stats import Stats | |
| 21 | 21 | from git.utils import dashify | |
| 22 | 22 | from git.utils import touch | |
| 23 | + from git.remote import Remote | ||
| 23 | 24 | ||
| 24 | 25 | ||
| 25 | 26 | __all__ = [ name for name, obj in locals().items() | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -13,6 +13,7 @@ | |||
| 13 | 13 | import ConfigParser as cp | |
| 14 | 14 | from git.odict import OrderedDict | |
| 15 | 15 | import inspect | |
| 16 | + import cStringIO | ||
| 16 | 17 | ||
| 17 | 18 | class _MetaParserBuilder(type): | |
| 18 | 19 | """ | |
@@ -221,15 +222,88 @@ def optionxform(self, optionstr): | |||
| 221 | 222 | """ | |
| 222 | 223 | return optionstr | |
| 223 | 224 | ||
| 225 | + def _read(self, fp, fpname): | ||
| 226 | + """ | ||
| 227 | + A direct copy of the py2.4 version of the super class's _read method | ||
| 228 | + to assure it uses ordered dicts. Had to change one line to make it work. | ||
| 229 | + | ||
| 230 | + Future versions have this fixed, but in fact its quite embarassing for the | ||
| 231 | + guys not to have done it right in the first place ! | ||
| 232 | + | ||
| 233 | + Removed big comments to make it more compact. | ||
| 234 | + | ||
| 235 | + Made sure it ignores initial whitespace as git uses tabs | ||
| 236 | + """ | ||
| 237 | + cursect = None # None, or a dictionary | ||
| 238 | + optname = None | ||
| 239 | + lineno = 0 | ||
| 240 | + e = None # None, or an exception | ||
| 241 | + while True: | ||
| 242 | + line = fp.readline() | ||
| 243 | + if not line: | ||
| 244 | + break | ||
| 245 | + lineno = lineno + 1 | ||
| 246 | + # comment or blank line? | ||
| 247 | + if line.strip() == '' or line[0] in '#;': | ||
| 248 | + continue | ||
| 249 | + if line.split(None, 1)[0].lower() == 'rem' and line[0] in "rR": | ||
| 250 | + # no leading whitespace | ||
| 251 | + continue | ||
| 252 | + else: | ||
| 253 | + # is it a section header? | ||
| 254 | + mo = self.SECTCRE.match(line) | ||
| 255 | + if mo: | ||
| 256 | + sectname = mo.group('header') | ||
| 257 | + if sectname in self._sections: | ||
| 258 | + cursect = self._sections[sectname] | ||
| 259 | + elif sectname == cp.DEFAULTSECT: | ||
| 260 | + cursect = self._defaults | ||
| 261 | + else: | ||
| 262 | + # THE ONLY LINE WE CHANGED ! | ||
| 263 | + cursect = OrderedDict((('__name__', sectname),)) | ||
| 264 | + self._sections[sectname] = cursect | ||
| 265 | + # So sections can't start with a continuation line | ||
| 266 | + optname = None | ||
| 267 | + # no section header in the file? | ||
| 268 | + elif cursect is None: | ||
| 269 | + raise cp.MissingSectionHeaderError(fpname, lineno, line) | ||
| 270 | + # an option line? | ||
| 271 | + else: | ||
| 272 | + mo = self.OPTCRE.match(line) | ||
| 273 | + if mo: | ||
| 274 | + optname, vi, optval = mo.group('option', 'vi', 'value') | ||
| 275 | + if vi in ('=', ':') and ';' in optval: | ||
| 276 | + pos = optval.find(';') | ||
| 277 | + if pos != -1 and optval[pos-1].isspace(): | ||
| 278 | + optval = optval[:pos] | ||
| 279 | + optval = optval.strip() | ||
| 280 | + if optval == '""': | ||
| 281 | + optval = '' | ||
| 282 | + optname = self.optionxform(optname.rstrip()) | ||
| 283 | + cursect[optname] = optval | ||
| 284 | + else: | ||
| 285 | + if not e: | ||
| 286 | + e = cp.ParsingError(fpname) | ||
| 287 | + e.append(lineno, repr(line)) | ||
| 288 | + # END | ||
| 289 | + # END ? | ||
| 290 | + # END ? | ||
| 291 | + # END while reading | ||
| 292 | + # if any parsing errors occurred, raise an exception | ||
| 293 | + if e: | ||
| 294 | + raise e | ||
| 295 | + | ||
| 296 | + | ||
| 224 | 297 | def read(self): | |
| 225 | 298 | """ | |
| 226 | - Reads the data stored in the files we have been initialized with | ||
| 299 | + Reads the data stored in the files we have been initialized with. It will | ||
| 300 | + ignore files that cannot be read, possibly leaving an empty configuration | ||
| 227 | 301 | ||
| 228 | 302 | Returns | |
| 229 | 303 | Nothing | |
| 230 | 304 | ||
| 231 | 305 | Raises | |
| 232 | - IOError if not all files could be read | ||
| 306 | + IOError if a file cannot be handled | ||
| 233 | 307 | """ | |
| 234 | 308 | if self._is_initialized: | |
| 235 | 309 | return | |
@@ -244,7 +318,10 @@ def read(self): | |||
| 244 | 318 | close_fp = False | |
| 245 | 319 | # assume a path if it is not a file-object | |
| 246 | 320 | if not hasattr(file_object, "seek"): | |
| 247 | - fp = open(file_object) | ||
| 321 | + try: | ||
| 322 | + fp = open(file_object) | ||
| 323 | + except IOError,e: | ||
| 324 | + continue | ||
| 248 | 325 | close_fp = True | |
| 249 | 326 | # END fp handling | |
| 250 | 327 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,6 +15,7 @@ class Reference(LazyMixin, Iterable): | |||
| 15 | 15 | Represents a named reference to any object | |
| 16 | 16 | """ | |
| 17 | 17 | __slots__ = ("repo", "path") | |
| 18 | + _common_path_default = "refs" | ||
| 18 | 19 | ||
| 19 | 20 | def __init__(self, repo, path, object = None): | |
| 20 | 21 | """ | |
@@ -75,7 +76,7 @@ def object(self): | |||
| 75 | 76 | return Object.new(self.repo, self.path) | |
| 76 | 77 | ||
| 77 | 78 | @classmethod | |
| 78 | - def iter_items(cls, repo, common_path = "refs", **kwargs): | ||
| 79 | + def iter_items(cls, repo, common_path = None, **kwargs): | ||
| 79 | 80 | """ | |
| 80 | 81 | Find all refs in the repository | |
| 81 | 82 | ||
@@ -84,7 +85,9 @@ def iter_items(cls, repo, common_path = "refs", **kwargs): | |||
| 84 | 85 | ||
| 85 | 86 | ``common_path`` | |
| 86 | 87 | Optional keyword argument to the path which is to be shared by all | |
| 87 | - returned Ref objects | ||
| 88 | + returned Ref objects. | ||
| 89 | + Defaults to class specific portion if None assuring that only | ||
| 90 | + refs suitable for the actual class are returned. | ||
| 88 | 91 | ||
| 89 | 92 | ``kwargs`` | |
| 90 | 93 | Additional options given as keyword arguments, will be passed | |
@@ -100,7 +103,10 @@ def iter_items(cls, repo, common_path = "refs", **kwargs): | |||
| 100 | 103 | ||
| 101 | 104 | options = {'sort': "committerdate", | |
| 102 | 105 | 'format': "%(refname)%00%(objectname)%00%(objecttype)%00%(objectsize)"} | |
| 103 | - | ||
| 106 | + | ||
| 107 | + if common_path is None: | ||
| 108 | + common_path = cls._common_path_default | ||
| 109 | + | ||
| 104 | 110 | options.update(kwargs) | |
| 105 | 111 | ||
| 106 | 112 | output = repo.git.for_each_ref(common_path, **options) | |
@@ -157,7 +163,8 @@ class Head(Reference): | |||
| 157 | 163 | >>> head.commit.id | |
| 158 | 164 | '1c09f116cbc2cb4100fb6935bb162daa4723f455' | |
| 159 | 165 | """ | |
| 160 | - | ||
| 166 | + _common_path_default = "refs/heads" | ||
| 167 | + | ||
| 161 | 168 | @property | |
| 162 | 169 | def commit(self): | |
| 163 | 170 | """ | |
@@ -166,20 +173,6 @@ def commit(self): | |||
| 166 | 173 | """ | |
| 167 | 174 | return self.object | |
| 168 | 175 | ||
| 169 | - @classmethod | ||
| 170 | - def iter_items(cls, repo, common_path = "refs/heads", **kwargs): | ||
| 171 | - """ | ||
| 172 | - Returns | ||
| 173 | - Iterator yielding Head items | ||
| 174 | - | ||
| 175 | - For more documentation, please refer to git.base.Ref.list_items | ||
| 176 | - """ | ||
| 177 | - return super(Head,cls).iter_items(repo, common_path, **kwargs) | ||
| 178 | - | ||
| 179 | - def __repr__(self): | ||
| 180 | - return '<git.Head "%s">' % self.name | ||
| 181 | - | ||
| 182 | - | ||
| 183 | 176 | ||
| 184 | 177 | class TagRef(Reference): | |
| 185 | 178 | """ | |
@@ -197,6 +190,7 @@ class TagRef(Reference): | |||
| 197 | 190 | """ | |
| 198 | 191 | ||
| 199 | 192 | __slots__ = tuple() | |
| 193 | + _common_path_default = "refs/tags" | ||
| 200 | 194 | ||
| 201 | 195 | @property | |
| 202 | 196 | def commit(self): | |
@@ -223,16 +217,35 @@ def tag(self): | |||
| 223 | 217 | return self.object | |
| 224 | 218 | return None | |
| 225 | 219 | ||
| 226 | - @classmethod | ||
| 227 | - def iter_items(cls, repo, common_path = "refs/tags", **kwargs): | ||
| 220 | + | ||
| 221 | + # provide an alias | ||
| 222 | + Tag = TagRef | ||
| 223 | + | ||
| 224 | + class RemoteRef(Head): | ||
| 225 | + """ | ||
| 226 | + Represents a reference pointing to a remote head. | ||
| 227 | + """ | ||
| 228 | + _common_path_default = "refs/remotes" | ||
| 229 | + | ||
| 230 | + @property | ||
| 231 | + def remote_name(self): | ||
| 228 | 232 | """ | |
| 229 | 233 | Returns | |
| 230 | - Iterator yielding commit items | ||
| 231 | - | ||
| 232 | - For more documentation, please refer to git.base.Ref.list_items | ||
| 234 | + Name of the remote we are a reference of, such as 'origin' for a reference | ||
| 235 | + named 'origin/master' | ||
| 233 | 236 | """ | |
| 234 | - return super(TagRef,cls).iter_items(repo, common_path, **kwargs) | ||
| 235 | - | ||
| 237 | + tokens = self.path.split('/') | ||
| 238 | + # /refs/remotes/<remote name>/<branch_name> | ||
| 239 | + return tokens[2] | ||
| 236 | 240 | ||
| 237 | - # provide an alias | ||
| 238 | - Tag = TagRef | ||
| 241 | + @property | ||
| 242 | + def remote_branch(self): | ||
| 243 | + """ | ||
| 244 | + Returns | ||
| 245 | + Name of the remote branch itself, i.e. master. | ||
| 246 | + | ||
| 247 | + NOTE: The returned name is usually not qualified enough to uniquely identify | ||
| 248 | + a branch | ||
| 249 | + """ | ||
| 250 | + tokens = self.path.split('/') | ||
| 251 | + return '/'.join(tokens[3:]) | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments