Mercurial > kallithea
comparison rhodecode/lib/vcs/backends/git/repository.py @ 4116:ffd45b185016 rhodecode-2.2.5-gpl
Imported some of the GPLv3'd changes from RhodeCode v2.2.5.
This imports changes between changesets 21af6c4eab3d and 6177597791c2 in
RhodeCode's original repository, including only changes to Python files and HTML.
RhodeCode clearly licensed its changes to these files under GPLv3
in their /LICENSE file, which states the following:
The Python code and integrated HTML are licensed under the GPLv3 license.
(See:
https://code.rhodecode.com/rhodecode/files/v2.2.5/LICENSE
or
http://web.archive.org/web/20140512193334/https://code.rhodecode.com/rhodecode/files/f3b123159901f15426d18e3dc395e8369f70ebe0/LICENSE
for an online copy of that LICENSE file)
Conservancy reviewed these changes and confirmed that they can be licensed as
a whole to the Kallithea project under GPLv3-only.
While some of the contents committed herein are clearly licensed
GPLv3-or-later, on the whole we must assume the are GPLv3-only, since the
statement above from RhodeCode indicates that they intend GPLv3-only as their
license, per GPLv3ยง14 and other relevant sections of GPLv3.
author | Bradley M. Kuhn <bkuhn@sfconservancy.org> |
---|---|
date | Wed, 02 Jul 2014 19:03:13 -0400 |
parents | a5888ca796b5 |
children | 7e5f8c12a3fc |
comparison
equal
deleted
inserted
replaced
4115:8b7294a804a0 | 4116:ffd45b185016 |
---|---|
18 import posixpath | 18 import posixpath |
19 import string | 19 import string |
20 | 20 |
21 from dulwich.objects import Tag | 21 from dulwich.objects import Tag |
22 from dulwich.repo import Repo, NotGitRepository | 22 from dulwich.repo import Repo, NotGitRepository |
23 from dulwich.config import ConfigFile | |
23 | 24 |
24 from rhodecode.lib.vcs import subprocessio | 25 from rhodecode.lib.vcs import subprocessio |
25 from rhodecode.lib.vcs.backends.base import BaseRepository, CollectionGenerator | 26 from rhodecode.lib.vcs.backends.base import BaseRepository, CollectionGenerator |
26 from rhodecode.lib.vcs.conf import settings | 27 from rhodecode.lib.vcs.conf import settings |
27 | 28 |
37 from rhodecode.lib.vcs.utils.hgcompat import ( | 38 from rhodecode.lib.vcs.utils.hgcompat import ( |
38 hg_url, httpbasicauthhandler, httpdigestauthhandler | 39 hg_url, httpbasicauthhandler, httpdigestauthhandler |
39 ) | 40 ) |
40 | 41 |
41 from .changeset import GitChangeset | 42 from .changeset import GitChangeset |
42 from .config import ConfigFile | |
43 from .inmemory import GitInMemoryChangeset | 43 from .inmemory import GitInMemoryChangeset |
44 from .workdir import GitWorkdir | 44 from .workdir import GitWorkdir |
45 | 45 |
46 SHA_PATTERN = re.compile(r'^[[0-9a-fA-F]{12}|[0-9a-fA-F]{40}]$') | 46 SHA_PATTERN = re.compile(r'^[[0-9a-fA-F]{12}|[0-9a-fA-F]{40}]$') |
47 | 47 |
163 return self._run_git_command(cmd, **opts) | 163 return self._run_git_command(cmd, **opts) |
164 | 164 |
165 @classmethod | 165 @classmethod |
166 def _check_url(cls, url): | 166 def _check_url(cls, url): |
167 """ | 167 """ |
168 Functon will check given url and try to verify if it's a valid | 168 Function will check given url and try to verify if it's a valid |
169 link. Sometimes it may happened that mercurial will issue basic | 169 link. Sometimes it may happened that git will issue basic |
170 auth request that can cause whole API to hang when used from python | 170 auth request that can cause whole API to hang when used from python |
171 or other external calls. | 171 or other external calls. |
172 | 172 |
173 On failures it'll raise urllib2.HTTPError | 173 On failures it'll raise urllib2.HTTPError, exception is also thrown |
174 when the return code is non 200 | |
174 """ | 175 """ |
175 | 176 |
176 # check first if it's not an local url | 177 # check first if it's not an local url |
177 if os.path.isdir(url) or url.startswith('file:'): | 178 if os.path.isdir(url) or url.startswith('file:'): |
178 return True | 179 return True |
179 | 180 |
180 if('+' in url[:url.find('://')]): | 181 if '+' in url[:url.find('://')]: |
181 url = url[url.find('+') + 1:] | 182 url = url[url.find('+') + 1:] |
182 | 183 |
183 handlers = [] | 184 handlers = [] |
184 test_uri, authinfo = hg_url(url).authinfo() | 185 url_obj = hg_url(url) |
186 test_uri, authinfo = url_obj.authinfo() | |
187 url_obj.passwd = '*****' | |
188 cleaned_uri = str(url_obj) | |
189 | |
185 if not test_uri.endswith('info/refs'): | 190 if not test_uri.endswith('info/refs'): |
186 test_uri = test_uri.rstrip('/') + '/info/refs' | 191 test_uri = test_uri.rstrip('/') + '/info/refs' |
192 | |
187 if authinfo: | 193 if authinfo: |
188 #create a password manager | 194 #create a password manager |
189 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() | 195 passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm() |
190 passmgr.add_password(*authinfo) | 196 passmgr.add_password(*authinfo) |
191 | 197 |
200 cu = "%s%s" % (test_uri, qs) | 206 cu = "%s%s" % (test_uri, qs) |
201 req = urllib2.Request(cu, None, {}) | 207 req = urllib2.Request(cu, None, {}) |
202 | 208 |
203 try: | 209 try: |
204 resp = o.open(req) | 210 resp = o.open(req) |
205 return resp.code == 200 | 211 if resp.code != 200: |
212 raise Exception('Return Code is not 200') | |
206 except Exception, e: | 213 except Exception, e: |
207 # means it cannot be cloned | 214 # means it cannot be cloned |
208 raise urllib2.URLError("[%s] %s" % (url, e)) | 215 raise urllib2.URLError("[%s] org_exc: %s" % (cleaned_uri, e)) |
216 | |
217 # now detect if it's proper git repo | |
218 gitdata = resp.read() | |
219 if not 'service=git-upload-pack' in gitdata: | |
220 raise urllib2.URLError( | |
221 "url [%s] does not look like an git" % (cleaned_uri)) | |
222 | |
223 return True | |
209 | 224 |
210 def _get_repo(self, create, src_url=None, update_after_clone=False, | 225 def _get_repo(self, create, src_url=None, update_after_clone=False, |
211 bare=False): | 226 bare=False): |
212 if create and os.path.exists(self.path): | 227 if create and os.path.exists(self.path): |
213 raise RepositoryError("Location already exist") | 228 raise RepositoryError("Location already exist") |
218 if create and src_url: | 233 if create and src_url: |
219 GitRepository._check_url(src_url) | 234 GitRepository._check_url(src_url) |
220 self.clone(src_url, update_after_clone, bare) | 235 self.clone(src_url, update_after_clone, bare) |
221 return Repo(self.path) | 236 return Repo(self.path) |
222 elif create: | 237 elif create: |
223 os.mkdir(self.path) | 238 os.makedirs(self.path) |
224 if bare: | 239 if bare: |
225 return Repo.init_bare(self.path) | 240 return Repo.init_bare(self.path) |
226 else: | 241 else: |
227 return Repo.init(self.path) | 242 return Repo.init(self.path) |
228 else: | 243 else: |
272 if ((is_bstr and revision.isdigit() and len(revision) < 12) | 287 if ((is_bstr and revision.isdigit() and len(revision) < 12) |
273 or isinstance(revision, int) or is_null(revision)): | 288 or isinstance(revision, int) or is_null(revision)): |
274 try: | 289 try: |
275 revision = self.revisions[int(revision)] | 290 revision = self.revisions[int(revision)] |
276 except Exception: | 291 except Exception: |
277 raise ChangesetDoesNotExistError("Revision %s does not exist " | 292 msg = ("Revision %s does not exist for %s" % (revision, self)) |
278 "for this repository" % (revision)) | 293 raise ChangesetDoesNotExistError(msg) |
279 | 294 |
280 elif is_bstr: | 295 elif is_bstr: |
281 # get by branch/tag name | 296 # get by branch/tag name |
282 _ref_revision = self._parsed_refs.get(revision) | 297 _ref_revision = self._parsed_refs.get(revision) |
283 if _ref_revision: # and _ref_revision[1] in ['H', 'RH', 'T']: | 298 if _ref_revision: # and _ref_revision[1] in ['H', 'RH', 'T']: |
287 # maybe it's a tag ? we don't have them in self.revisions | 302 # maybe it's a tag ? we don't have them in self.revisions |
288 if revision in _tags_shas: | 303 if revision in _tags_shas: |
289 return _tags_shas[_tags_shas.index(revision)] | 304 return _tags_shas[_tags_shas.index(revision)] |
290 | 305 |
291 elif not SHA_PATTERN.match(revision) or revision not in self.revisions: | 306 elif not SHA_PATTERN.match(revision) or revision not in self.revisions: |
292 raise ChangesetDoesNotExistError("Revision %s does not exist " | 307 msg = ("Revision %s does not exist for %s" % (revision, self)) |
293 "for this repository" % (revision)) | 308 raise ChangesetDoesNotExistError(msg) |
294 | 309 |
295 # Ensure we return full id | 310 # Ensure we return full id |
296 if not SHA_PATTERN.match(str(revision)): | 311 if not SHA_PATTERN.match(str(revision)): |
297 raise ChangesetDoesNotExistError("Given revision %s not recognized" | 312 raise ChangesetDoesNotExistError("Given revision %s not recognized" |
298 % revision) | 313 % revision) |
346 else: | 361 else: |
347 return os.stat(he_path).st_mtime | 362 return os.stat(he_path).st_mtime |
348 | 363 |
349 @LazyProperty | 364 @LazyProperty |
350 def description(self): | 365 def description(self): |
351 idx_loc = '' if self.bare else '.git' | |
352 undefined_description = u'unknown' | 366 undefined_description = u'unknown' |
353 description_path = os.path.join(self.path, idx_loc, 'description') | 367 _desc = self._repo.get_description() |
354 if os.path.isfile(description_path): | 368 return safe_unicode(_desc or undefined_description) |
355 return safe_unicode(open(description_path).read()) | |
356 else: | |
357 return undefined_description | |
358 | 369 |
359 @LazyProperty | 370 @LazyProperty |
360 def contact(self): | 371 def contact(self): |
361 undefined_contact = u'Unknown' | 372 undefined_contact = u'Unknown' |
362 return undefined_contact | 373 return undefined_contact |
629 working directory | 640 working directory |
630 :param bare: If set to ``True``, repository would be cloned into | 641 :param bare: If set to ``True``, repository would be cloned into |
631 *bare* git repository (no working directory at all). | 642 *bare* git repository (no working directory at all). |
632 """ | 643 """ |
633 url = self._get_url(url) | 644 url = self._get_url(url) |
634 cmd = ['clone'] | 645 cmd = ['clone', '-q'] |
635 if bare: | 646 if bare: |
636 cmd.append('--bare') | 647 cmd.append('--bare') |
637 elif not update_after_clone: | 648 elif not update_after_clone: |
638 cmd.append('--no-checkout') | 649 cmd.append('--no-checkout') |
639 cmd += ['--', '"%s"' % url, '"%s"' % self.path] | 650 cmd += ['--', '"%s"' % url, '"%s"' % self.path] |
663 refs.append(ref) | 674 refs.append(ref) |
664 refs = ' '.join(('+%s:%s' % (r, r) for r in refs)) | 675 refs = ' '.join(('+%s:%s' % (r, r) for r in refs)) |
665 cmd = '''fetch %s -- %s''' % (url, refs) | 676 cmd = '''fetch %s -- %s''' % (url, refs) |
666 self.run_git_command(cmd) | 677 self.run_git_command(cmd) |
667 | 678 |
679 def _update_server_info(self): | |
680 """ | |
681 runs gits update-server-info command in this repo instance | |
682 """ | |
683 from dulwich.server import update_server_info | |
684 update_server_info(self._repo) | |
685 | |
668 @LazyProperty | 686 @LazyProperty |
669 def workdir(self): | 687 def workdir(self): |
670 """ | 688 """ |
671 Returns ``Workdir`` instance for this repository. | 689 Returns ``Workdir`` instance for this repository. |
672 """ | 690 """ |