def handle(self, *args, **options): self.verbosity = options.pop('verbosity', 1) self.handleOptions(**options) from mercurial.ui import ui as _ui from mercurial.hg import repository repos = self.repos_for_names(*args) ui = _ui() for dbrepo in repos: repopath = str(resolve(dbrepo.name)) if not os.path.isdir(os.path.join(repopath, '.hg')): self.minimal(("\n Cannot process %s, " "there's no local clone\n\n") % dbrepo.name) continue hgrepo = repository(ui, repopath) try: self.handleRepo(dbrepo, hgrepo) except StopIteration: # allow subclass to stop our loop over repositories break except StandardError: print logging.error('%s\tError while processing' % dbrepo.name, exc_info=True) self._needsNewline = False if self._needsNewline: print
def handle(self, *args, **options): self.verbosity = options.pop('verbosity', 1) self.handleOptions(**options) from mercurial.ui import ui as _ui from mercurial.hg import repository repos = self.repos_for_names(*options['repos']) ui = _ui() for dbrepo in repos: repopath = str(resolve(dbrepo.name)) if not os.path.isdir(os.path.join(repopath, '.hg')): self.minimal(("\n Cannot process %s, " "there's no local clone\n\n") % dbrepo.name) continue hgrepo = repository(ui, repopath) try: self.handleRepo(dbrepo, hgrepo) except StopIteration: # allow subclass to stop our loop over repositories break except Exception: self.stdout.write('') logging.error('%s\tError while processing' % dbrepo.name, exc_info=True) self._needsNewline = False if self._needsNewline: self.stdout.write('')
def contextAndRepo(self, rev, repo): '''Get a hg changectx for the given rev, preferably in the given repo. ''' try: # Convert the 'from' and 'to' to strings (instead of unicode) # in case mercurial needs to look for the key in binary data. # This prevents UnicodeWarning messages. ctx = repo.changectx(str(rev)) return ctx, repo, self.repo except RepoLookupError as e: # the favored repo doesn't have a changeset, look for an # active repo that does. try: dbrepo = (Repository.objects.filter( changesets__revision__startswith=rev).annotate( last_changeset=Max('changesets')).order_by( '-last_changeset'))[0] except IndexError: # can't find the changeset in other repos, raise the # original error raise e # ok, new repo repopath = settings.REPOSITORY_BASE + '/' + dbrepo.name otherrepo = repository(_ui(), repopath) return otherrepo.changectx(str(rev)), otherrepo, dbrepo
def contextAndRepo(self, rev, repo): '''Get a hg changectx for the given rev, preferably in the given repo. ''' try: # Convert the 'from' and 'to' to strings (instead of unicode) # in case mercurial needs to look for the key in binary data. # This prevents UnicodeWarning messages. ctx = repo.changectx(str(rev)) return ctx, repo, self.repo except RepoLookupError as e: # the favored repo doesn't have a changeset, look for an # active repo that does. try: dbrepo = ( Repository.objects .filter(changesets__revision__startswith=rev) .annotate(last_changeset=Max('changesets')) .order_by('-last_changeset') )[0] except IndexError: # can't find the changeset in other repos, raise the # original error raise e # ok, new repo repopath = settings.REPOSITORY_BASE + '/' + dbrepo.name otherrepo = repository(_ui(), repopath) return otherrepo.changectx(str(rev)), otherrepo, dbrepo
def handlePushes(repo_id, submits, do_update=True): if not submits: return repo = Repository.objects.get(id=repo_id) revisions = reduce(lambda r, l: r + l, [p.changesets for p in submits], []) ui = _ui() repopath = os.path.join(settings.REPOSITORY_BASE, repo.name) configpath = os.path.join(repopath, '.hg', 'hgrc') if not os.path.isfile(configpath): if not os.path.isdir(os.path.dirname(repopath)): os.makedirs(os.path.dirname(repopath)) clone(ui, str(repo.url), str(repopath), pull=False, uncompressed=False, rev=[], noupdate=False) cfg = open(configpath, 'a') cfg.write('default-push = ssh%s\n' % str(repo.url)[4:]) cfg.close() ui.readconfig(configpath) hgrepo = repository(ui, repopath) else: ui.readconfig(configpath) hgrepo = repository(ui, repopath) cs = submits[-1].changesets[-1] try: hgrepo.changectx(cs) except RepoError: pull(ui, hgrepo, source=str(repo.url), force=False, update=False, rev=[]) if do_update: update(ui, hgrepo) for data in submits: changesets = [] for revision in data.changesets: try: cs = getChangeset(repo, hgrepo, revision) transaction.commit() changesets.append(cs) except Exception, e: transaction.rollback() raise print repo.name, e p = Push.objects.create(repository=repo, push_id=data.id, user=data.user, push_date=datetime.utcfromtimestamp(data.date)) p.changesets = changesets p.save() transaction.commit()
def contextsAndPaths(self, _from, _to, suggested_repo): repopath = settings.REPOSITORY_BASE + '/' + suggested_repo ui = _ui() repo = repository(ui, repopath) # Convert the 'from' and 'to' to strings (instead of unicode) # in case mercurial needs to look for the key in binary data. # This prevents UnicodeWarning messages. try: self.ctx1, fromrepo, dbfrom = self.contextAndRepo(_from, repo) except RepoLookupError: raise BadRevision("Unrecognized 'from' parameter") try: self.ctx2, torepo, dbto = self.contextAndRepo(_to, repo) except RepoLookupError: raise BadRevision("Unrecognized 'to' parameter") if fromrepo == torepo: copies = pathcopies(self.ctx1, self.ctx2) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(self.ctx1, self.ctx2, match=match)[:3] else: # find descent ancestor for ctx1 and ctx2 try: anc_rev = (Changeset.objects .exclude(id=1) # exclude rev 0000 .filter(repositories=dbfrom) .filter(repositories=dbto) .filter(branch=1) .order_by('-pk') .values_list('revision', flat=True))[0] # mercurial doesn't like unicode anc_rev = str(anc_rev) except IndexError: raise BadRevision("from and to parameter are not connected") changed, added, removed, copies = \ self.processFork(fromrepo, self.ctx1, torepo, self.ctx2, anc_rev) # split up the copies info into thos that were renames and those that # were copied. self.moved = {} self.copied = {} for new_name, old_name in copies.items(): if old_name in removed: self.moved[new_name] = old_name else: self.copied[new_name] = old_name paths = ([(f, 'changed') for f in changed] + [(f, 'removed') for f in removed if f not in self.moved.values()] + [(f, (f in self.moved and 'moved') or (f in self.copied and 'copied') or 'added') for f in added]) return paths
def handlePushes(repo_id, submits, do_update=True): if not submits: return repo = Repository.objects.get(id=repo_id) revisions = reduce(lambda r,l: r+l, [p.changesets for p in submits], []) ui = _ui() repopath = os.path.join(settings.REPOSITORY_BASE, repo.name) configpath = os.path.join(repopath, '.hg', 'hgrc') if not os.path.isfile(configpath): if not os.path.isdir(os.path.dirname(repopath)): os.makedirs(os.path.dirname(repopath)) clone(ui, str(repo.url), str(repopath), pull=False, uncompressed=False, rev=[], noupdate=False) cfg = open(configpath, 'a') cfg.write('default-push = ssh%s\n' % str(repo.url)[4:]) cfg.close() ui.readconfig(configpath) hgrepo = repository(ui, repopath) else: ui.readconfig(configpath) hgrepo = repository(ui, repopath) cs = submits[-1].changesets[-1] try: hgrepo.changectx(cs) except RepoError: pull(ui, hgrepo, source = str(repo.url), force=False, update=False, rev=[]) if do_update: update(ui, hgrepo) for data in submits: changesets = [] for revision in data.changesets: try: cs = getChangeset(repo, hgrepo, revision) transaction.commit() changesets.append(cs) except Exception, e: transaction.rollback() raise print repo.name, e p = Push.objects.create(repository = repo, push_id = data.id, user = data.user, push_date = datetime.utcfromtimestamp(data.date)) p.changesets = changesets p.save() transaction.commit()
def content(self, request, signoffs): sos = signoffs.annotate(tip=Max('push__changesets__id')) tips = dict(sos.values_list('locale__code', 'tip')) revmap = dict(Changeset.objects .filter(id__in=tips.values()) .values_list('id', 'revision')) platforms = re.split('[ ,]+', request.GET['platforms']) multis = defaultdict(dict) for k, v in request.GET.iteritems(): if not k.startswith('multi_'): continue plat, prop = k.split('_')[1:3] multis[plat][prop] = v extra_plats = defaultdict(list) try: from mercurial.hg import repository from mercurial.ui import ui as _ui _ui # silence pyflakes except: _ui = None if _ui is not None: for plat in sorted(multis.keys()): try: props = multis[plat] path = os.path.join(settings.REPOSITORY_BASE, props['repo']) repo = repository(_ui(), path) ctx = repo[str(props['rev'])] fctx = ctx.filectx(str(props['path'])) locales = fctx.data().split() for loc in locales: extra_plats[loc].append(plat) except: pass tmpl = ''' "%(loc)s": { "revision": "%(rev)s", "platforms": ["%(plats)s"] }''' content = [ '{\n', ',\n'.join(tmpl % {'loc': l, 'rev': revmap[tips[l]][:12], 'plats': '", "'.join(platforms + extra_plats[l])} for l in sorted(tips.keys()) ), '\n}\n' ] content = ''.join(content) return content
def content(self, request, signoffs): sos = signoffs.annotate(tip=Max('push__changesets__id')) tips = dict(sos.values_list('locale__code', 'tip')) revmap = dict(Changeset.objects .filter(id__in=tips.values()) .values_list('id', 'revision')) platforms = re.split('[ ,]+', request.GET.get('platforms', '')) multis = defaultdict(dict) for k, v in request.GET.iteritems(): if not k.startswith('multi_'): continue plat, prop = k.split('_')[1:3] multis[plat][prop] = v extra_plats = defaultdict(list) try: from mercurial.hg import repository from mercurial.ui import ui as _ui _ui # silence pyflakes except: _ui = None if _ui is not None: for plat in sorted(multis.keys()): try: props = multis[plat] path = os.path.join(settings.REPOSITORY_BASE, props['repo']) repo = repository(_ui(), path) ctx = repo[str(props['rev'])] fctx = ctx.filectx(str(props['path'])) locales = fctx.data().split() for loc in locales: extra_plats[loc].append(plat) except: pass tmpl = ''' "%(loc)s": { "revision": "%(rev)s", "platforms": ["%(plats)s"] }''' content = [ '{\n', ',\n'.join(tmpl % {'loc': l, 'rev': revmap[tips[l]][:12], 'plats': '", "'.join(platforms + extra_plats[l])} for l in sorted(tips.keys()) ), '\n}\n' ] content = ''.join(content) return content
def json_changesets(request): """Create a json l10n-changesets. This takes optional arguments of triples to link to files in repos specifying a special platform build. Used for multi-locale builds for fennec so far. multi_PLATFORM_repo: repository to load maemo-locales from multi_PLATFORM_rev: revision of file to load (default is usually fine) multi_PLATFORM_path: path inside the repo, say locales/maemo-locales XXX: For use in Firefox, this needs to learn about Japanese, still. """ if request.GET.has_key('ms'): av_or_m = Milestone.objects.get(code=request.GET['ms']) elif request.GET.has_key('av'): av_or_m = AppVersion.objects.get(code=request.GET['av']) else: return HttpResponse('No milestone or appversion given') sos = _signoffs(av_or_m).annotate(tip=Max('push__changesets__id')) tips = dict(sos.values_list('locale__code', 'tip')) revmap = dict(Changeset.objects.filter(id__in=tips.values()).values_list('id', 'revision')) platforms = re.split('[ ,]+', request.GET['platforms']) multis = defaultdict(dict) for k, v in request.GET.iteritems(): if not k.startswith('multi_'): continue plat, prop = k.split('_')[1:3] multis[plat][prop] = v extra_plats = defaultdict(list) try: from mercurial.hg import repository from mercurial.ui import ui as _ui except: _ui = None if _ui is not None: for plat in sorted(multis.keys()): try: props = multis[plat] path = os.path.join(settings.REPOSITORY_BASE, props['repo']) repo = repository(_ui(), path) ctx = repo[props['rev']] fctx = ctx.filectx(props['path']) locales = fctx.data().split() for loc in locales: extra_plats[loc].append(plat) except: pass tmpl = ''' "%(loc)s": { "revision": "%(rev)s", "platforms": ["%(plats)s"] }''' content = ('{\n' + ',\n'.join(tmpl % {'loc': l, 'rev': revmap[tips[l]][:12], 'plats': '", "'.join(platforms+extra_plats[l]) } for l in sorted(tips.keys()) ) + '\n}\n') r = HttpResponse(content, content_type='text/plain; charset=utf-8') r['Content-Disposition'] = 'inline; filename=l10n-changesets.json' return r
def diff_app(request): # XXX TODO: error handling if 'repo' not in request.GET: raise Http404("repo must be supplied") reponame = request.GET['repo'] repopath = settings.REPOSITORY_BASE + '/' + reponame repo_url = Repository.objects.filter(name=reponame).values_list('url', flat=True)[0] from mercurial.ui import ui as _ui from mercurial.hg import repository ui = _ui() repo = repository(ui, repopath) ctx1 = repo.changectx(request.GET['from']) ctx2 = repo.changectx(request.GET['to']) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(ctx1, ctx2, match=match)[:3] paths = ([(f, 'changed') for f in changed] + [(f, 'removed') for f in removed] + [(f, 'added') for f in added]) diffs = DataTree(dict) for path, action in paths: lines = [] try: p = getParser(path) except UserWarning: diffs[path].update({'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action}) continue if action == 'added': a_entities = [] a_map = {} else: data = ctx1.filectx(path).data() data = _universal_newlines(data) try: p.readContents(data) a_entities, a_map = p.parse() except: diffs[path].update({'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action}) continue if action == 'removed': c_entities = [] c_map = {} else: data = ctx2.filectx(path).data() data = _universal_newlines(data) try: p.readContents(data) c_entities, c_map = p.parse() except: diffs[path].update({'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action}) continue a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair}) elif action == 'add': lines.append({'class': 'added', 'oldval': '', 'newval':[{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair}) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class':op, 'value':oldval[o1:o2]}) if n1 != n2: newhtml.append({'class':op, 'value':newval[n1:n2]}) lines.append({'class':'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) container_class = lines and 'file' or 'empty-diff' diffs[path].update({'path': path, 'class': container_class, 'lines': lines}) diffs = diffs.toJSON().get('children', []) return render_to_response('shipping/diff.html', {'given_title': request.GET.get('title', None), 'repo': reponame, 'repo_url': repo_url, 'old_rev': request.GET['from'], 'new_rev': request.GET['to'], 'diffs': diffs}, context_instance=RequestContext(request))
def diff(request): if not request.GET.get('repo'): return http.HttpResponseBadRequest("Missing 'repo' parameter") reponame = request.GET['repo'] repopath = settings.REPOSITORY_BASE + '/' + reponame try: repo_url = Repository.objects.get(name=reponame).url except Repository.DoesNotExist: raise http.Http404("Repository not found") if not request.GET.get('from'): return http.HttpResponseBadRequest("Missing 'from' parameter") if not request.GET.get('to'): return http.HttpResponseBadRequest("Missing 'to' parameter") ui = _ui() repo = repository(ui, repopath) # Convert the 'from' and 'to' to strings (instead of unicode) # in case mercurial needs to look for the key in binary data. # This prevents UnicodeWarning messages. ctx1 = repo.changectx(str(request.GET['from'])) ctx2 = repo.changectx(str(request.GET['to'])) copies = pathcopies(ctx1, ctx2) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(ctx1, ctx2, match=match)[:3] # split up the copies info into thos that were renames and those that # were copied. moved = {} copied = {} for new_name, old_name in copies.items(): if old_name in removed: moved[new_name] = old_name else: copied[new_name] = old_name paths = ([(f, 'changed') for f in changed] + [(f, 'removed') for f in removed if f not in moved.values()] + [(f, (f in moved and 'moved') or (f in copied and 'copied') or 'added') for f in added]) diffs = DataTree(dict) for path, action in paths: lines = [] try: p = getParser(path) except UserWarning: diffs[path].update({ 'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action, 'renamed': moved.get(path), 'copied': copied.get(path) }) continue if action == 'added': a_entities = [] a_map = {} else: realpath = (action == 'moved' and moved[path] or action == 'copied' and copied[path] or path) data = ctx1.filectx(realpath).data() data = _universal_newlines(data) try: p.readContents(data) a_entities, a_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) diffs[path].update({ 'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action, 'renamed': moved.get(path), 'copied': copied.get(path) }) continue if action == 'removed': c_entities, c_map = [], {} else: data = ctx2.filectx(path).data() data = _universal_newlines(data) try: p.readContents(data) c_entities, c_map = p.parse() except: # consider doing something like: # logging.warn('Unable to parse %s', path, exc_info=True) diffs[path].update({ 'path': path, 'isFile': True, 'rev': ((action == 'removed') and request.GET['from'] or request.GET['to']), 'class': action }) continue a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({ 'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair }) elif action == 'add': lines.append({ 'class': 'added', 'oldval': '', 'newval': [{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair }) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class': op, 'value': oldval[o1:o2]}) if n1 != n2: newhtml.append({'class': op, 'value': newval[n1:n2]}) lines.append({'class': 'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) container_class = lines and 'file' or 'empty-diff' diffs[path].update({'path': path, 'class': container_class, 'lines': lines, 'renamed': moved.get(path), 'copied': copied.get(path) }) diffs = diffs.toJSON().get('children', []) return render(request, 'shipping/diff.html', { 'given_title': request.GET.get('title', None), 'repo': reponame, 'repo_url': repo_url, 'old_rev': request.GET['from'], 'new_rev': request.GET['to'], 'diffs': diffs })
return ctx, repo, self.repo except RepoLookupError, e: # the favored repo doesn't have a changeset, look for an # active repo that does. try: dbrepo = (Repository.objects.filter( changesets__revision__startswith=rev).annotate( last_push=Max('push__push_date')).order_by( '-last_push'))[0] except IndexError: # can't find the changeset in other repos, raise the # original error raise e # ok, new repo repopath = settings.REPOSITORY_BASE + '/' + dbrepo.name otherrepo = repository(_ui(), repopath) return otherrepo.changectx(str(rev)), otherrepo, dbrepo def processFork(self, fromrepo, ctx1, torepo, ctx2, anc_rev): # piece together changed, removed, added, and copies match = None # keep in sync with match above ctx3 = fromrepo.changectx(anc_rev) first_copies = pathcopies(ctx1, ctx3) changed, added, removed = fromrepo.status(ctx1, ctx3, match=match)[:3] logging.debug('changed, added, removed, copies:\n %r %r %r %r', changed, added, removed, first_copies) ctx3 = torepo.changectx(anc_rev) more_copies = pathcopies(ctx3, ctx2) more_reverse = dict((v, k) for k, v in more_copies.iteritems()) more_changed, more_added, more_removed = torepo.status(ctx3, ctx2,
# the favored repo doesn't have a changeset, look for an # active repo that does. try: dbrepo = ( Repository.objects .filter(changesets__revision__startswith=rev) .annotate(last_changeset=Max('changesets')) .order_by('-last_changeset') )[0] except IndexError: # can't find the changeset in other repos, raise the # original error raise e # ok, new repo repopath = settings.REPOSITORY_BASE + '/' + dbrepo.name otherrepo = repository(_ui(), repopath) return otherrepo.changectx(str(rev)), otherrepo, dbrepo def processFork(self, fromrepo, ctx1, torepo, ctx2, anc_rev): # piece together changed, removed, added, and copies match = None # keep in sync with match above ctx3 = fromrepo.changectx(anc_rev) first_copies = pathcopies(ctx1, ctx3) changed, added, removed = fromrepo.status(ctx1, ctx3, match=match)[:3] logging.debug('changed, added, removed, copies:\n %r %r %r %r', changed, added, removed, first_copies) ctx3 = torepo.changectx(anc_rev) more_copies = pathcopies(ctx3, ctx2) more_reverse = dict((v, k) for k, v in more_copies.iteritems()) more_changed, more_added, more_removed = torepo.status(ctx3, ctx2,
def diff_app(request): # XXX TODO: error handling reponame = request.GET['repo'] repopath = settings.REPOSITORY_BASE + '/' + reponame repo_url = Repository.objects.filter(name=reponame).values_list('url', flat=True)[0] from mercurial.ui import ui as _ui from mercurial.hg import repository ui = _ui() repo = repository(ui, repopath) ctx1 = repo.changectx(request.GET['from']) ctx2 = repo.changectx(request.GET['to']) match = None # maybe get something from l10n.ini and cmdutil changed, added, removed = repo.status(ctx1, ctx2, match=match)[:3] diffs = DataTree(dict) for path in added: diffs[path].update({'path': path, 'isFile': True, 'rev': request.GET['to'], 'desc': ' (File added)', 'class': 'added'}) for path in removed: diffs[path].update({'path': path, 'isFile': True, 'rev': request.GET['from'], 'desc': ' (File removed)', 'class': 'removed'}) for path in changed: lines = [] try: p = getParser(path) except UserWarning: diffs[path].update({'path': path, 'lines': [{'class': 'issue', 'oldval': '', 'newval': '', 'entity': 'cannot parse ' + path}]}) continue data1 = ctx1.filectx(path).data() data2 = ctx2.filectx(path).data() try: # parsing errors or such can break this, catch those and fail # gracefully # fake reading with universal line endings, too p.readContents(__universal_le(data1)) a_entities, a_map = p.parse() p.readContents(__universal_le(data2)) c_entities, c_map = p.parse() del p except: diffs[path].update({'path': path, 'lines': [{'class': 'issue', 'oldval': '', 'newval': '', 'entity': 'cannot parse ' + path}]}) continue a_list = sorted(a_map.keys()) c_list = sorted(c_map.keys()) ar = AddRemove() ar.set_left(a_list) ar.set_right(c_list) for action, item_or_pair in ar: if action == 'delete': lines.append({'class': 'removed', 'oldval': [{'value':a_entities[a_map[item_or_pair]].val}], 'newval': '', 'entity': item_or_pair}) elif action == 'add': lines.append({'class': 'added', 'oldval': '', 'newval':[{'value': c_entities[c_map[item_or_pair]].val}], 'entity': item_or_pair}) else: oldval = a_entities[a_map[item_or_pair[0]]].val newval = c_entities[c_map[item_or_pair[1]]].val if oldval == newval: continue sm = SequenceMatcher(None, oldval, newval) oldhtml = [] newhtml = [] for op, o1, o2, n1, n2 in sm.get_opcodes(): if o1 != o2: oldhtml.append({'class':op, 'value':oldval[o1:o2]}) if n1 != n2: newhtml.append({'class':op, 'value':newval[n1:n2]}) lines.append({'class':'changed', 'oldval': oldhtml, 'newval': newhtml, 'entity': item_or_pair[0]}) container_class = lines and 'file' or 'empty-diff' diffs[path].update({'path': path, 'class': container_class, 'lines': lines}) diffs = diffs.toJSON().get('children', []) return render_to_response('shipping/diff.html', {'given_title': request.GET.get('title', None), 'repo': reponame, 'repo_url': repo_url, 'old_rev': request.GET['from'], 'new_rev': request.GET['to'], 'diffs': diffs})
def __init__(self, path): self.ui = _ui() self.ui.readconfig(os.path.join(path, ".hg", "hgrc")) self.repo = repository(self.ui, path)