def get_paths(): matcher = match.exact(self.repository.basedir, self.repository.basedir, [subdir]) walk = self._getRepo().dirstate.walk for path in walk(matcher, True, False): yield path
def commit_multi(proj, asset, filenames, text, username=None): """Commit multiple files to the repository and returns the revision id.""" repo_path = os.path.join(G.REPOSITORY, proj) repo = repo_get(proj) if not isinstance(filenames, list): raise SPAMRepoError('expected a list of files for asset %s' % asset.id) text = 'asset %s - %s' % (asset.id, text) encodedtext = text.encode('utf-8') target_sequence_path = asset.path.replace('#', '%04d') targets = [] for i, filename in enumerate(filenames): n = i + 1 uploadedfile = os.path.join(G.UPLOAD, filename) target_path = (target_sequence_path % n).encode() target_repo_path = os.path.join(repo_path, target_path) if not os.path.exists(os.path.dirname(target_repo_path)): os.makedirs(os.path.dirname(target_repo_path)) shutil.move(uploadedfile, target_repo_path) if not target_path in repo['tip']: commands.add(repo_ui, repo, target_repo_path) targets.append(target_path) matched = match.exact(repo.root, repo.getcwd(), targets) commit_id = repo.commit(encodedtext, user=username, match=matched) if commit_id: return repo[commit_id].hex() else: return None
def diffs(repo, tmpl, ctx, basectx, files, parity, style): def countgen(): start = 1 while True: yield start start += 1 blockcount = countgen() def prettyprintlines(diff, blockno): for lineno, l in enumerate(diff.splitlines(True)): difflineno = "%d.%d" % (blockno, lineno + 1) if l.startswith('+'): ltype = "difflineplus" elif l.startswith('-'): ltype = "difflineminus" elif l.startswith('@'): ltype = "difflineat" else: ltype = "diffline" yield tmpl(ltype, line=l, lineno=lineno + 1, lineid="l%s" % difflineno, linenumber="% 8s" % difflineno) if files: m = match.exact(repo.root, repo.getcwd(), files) else: m = match.always(repo.root, repo.getcwd()) diffopts = patch.diffopts(repo.ui, untrusted=True) if basectx is None: parents = ctx.parents() if parents: node1 = parents[0].node() else: node1 = nullid else: node1 = basectx.node() node2 = ctx.node() block = [] for chunk in patch.diff(repo, node1, node2, m, opts=diffopts): if chunk.startswith('diff') and block: blockno = blockcount.next() yield tmpl('diffblock', parity=parity.next(), blockno=blockno, lines=prettyprintlines(''.join(block), blockno)) block = [] if chunk.startswith('diff') and style != 'raw': chunk = ''.join(chunk.splitlines(True)[1:]) block.append(chunk) blockno = blockcount.next() yield tmpl('diffblock', parity=parity.next(), blockno=blockno, lines=prettyprintlines(''.join(block), blockno))
def getstatus(repo, n1, n2, wfile): m = match.exact(repo.root, repo.getcwd(), [wfile]) modified, added, removed = repo.status(n1, n2, match=m)[:3] if wfile in modified: return 'M' if wfile in added: return 'A' if wfile in removed: return 'R' if wfile in ctx: return 'C' return None
def applyone(self, repo, node, cl, patchfile, merge=False, log=False, filter=None): '''apply the patch in patchfile to the repository as a transplant''' (manifest, user, (time, timezone), files, message) = cl[:5] date = "%d %d" % (time, timezone) extra = {'transplant_source': node} if filter: (user, date, message) = self.filter(filter, node, cl, patchfile) if log: # we don't translate messages inserted into commits message += '\n(transplanted from %s)' % nodemod.hex(node) self.ui.status(_('applying %s\n') % nodemod.short(node)) self.ui.note('%s %s\n%s\n' % (user, date, message)) if not patchfile and not merge: raise error.Abort(_('can only omit patchfile if merging')) if patchfile: try: files = set() patch.patch(self.ui, repo, patchfile, files=files, eolmode=None) files = list(files) except Exception as inst: seriespath = os.path.join(self.path, 'series') if os.path.exists(seriespath): os.unlink(seriespath) p1 = repo.dirstate.p1() p2 = node self.log(user, date, message, p1, p2, merge=merge) self.ui.write(str(inst) + '\n') raise TransplantError(_('fix up the working directory and run ' 'hg transplant --continue')) else: files = None if merge: p1, p2 = repo.dirstate.parents() repo.setparents(p1, node) m = match.always(repo.root, '') else: m = match.exact(repo.root, '', files) n = repo.commit(message, user, date, extra=extra, match=m, editor=self.getcommiteditor()) if not n: self.ui.warn(_('skipping emptied changeset %s\n') % nodemod.short(node)) return None if not merge: self.transplants.set(n, node) return n
def _makematcher(repo, ctx, pat, changedonly): cwd = '' # always relative to repo root patterns = [] if pat and ':' not in pat and '*' not in pat: # mimic case-insensitive partial string match patterns.append('relre:(?i)' + re.escape(pat)) elif pat: patterns.append(pat) include = [] if changedonly: include.extend('path:%s' % p for p in ctx.files()) if not include: # no match return matchmod.exact(repo.root, cwd, []) try: return matchmod.match(repo.root, cwd, patterns, include=include, default='relglob', auditor=repo.auditor, ctx=ctx) except (error.Abort, error.ParseError): # no match return matchmod.exact(repo.root, cwd, [])
def buildmatch(ui, repo, user, key): '''return tuple of (match function, list enabled).''' if not ui.has_section(key): ui.debug(_('acl: %s not enabled\n') % key) return None pats = [pat for pat, users in ui.configitems(key) if user in users.replace(',', ' ').split()] ui.debug(_('acl: %s enabled, %d entries for user %s\n') % (key, len(pats), user)) if pats: return match.match(repo.root, '', pats) return match.exact(repo.root, '', [])
def _checkRenamed(self, repo, ctx, pctx, wfile): m = match.exact(repo, '', [wfile]) copy = copies.pathcopies(pctx, ctx, match=m) oldname = copy.get(wfile) if not oldname: self.flabel += _(' <i>(was added)</i>') return fr = hglib.tounicode(oldname) if oldname in ctx: self.flabel += _(' <i>(copied from %s)</i>') % fr else: self.flabel += _(' <i>(renamed from %s)</i>') % fr return oldname
def buildmatch(ui, repo, user, key): '''return tuple of (match function, list enabled).''' if not ui.has_section(key): ui.debug('acl: %s not enabled\n' % key) return None pats = [pat for pat, users in ui.configitems(key) if _usermatch(ui, user, users)] ui.debug('acl: %s enabled, %d entries for user %s\n' % (key, len(pats), user)) if not repo: if pats: return lambda b: '*' in pats or b in pats return lambda b: False if pats: return match.match(repo.root, '', pats) return match.exact(repo.root, '', [])
def diffs(repo, tmpl, ctx, files, parity, style): def countgen(): start = 1 while True: yield start start += 1 blockcount = countgen() def prettyprintlines(diff): blockno = blockcount.next() for lineno, l in enumerate(diff.splitlines(True)): lineno = "%d.%d" % (blockno, lineno + 1) if l.startswith("+"): ltype = "difflineplus" elif l.startswith("-"): ltype = "difflineminus" elif l.startswith("@"): ltype = "difflineat" else: ltype = "diffline" yield tmpl(ltype, line=l, lineid="l%s" % lineno, linenumber="% 8s" % lineno) if files: m = match.exact(repo.root, repo.getcwd(), files) else: m = match.always(repo.root, repo.getcwd()) diffopts = patch.diffopts(repo.ui, untrusted=True) parents = ctx.parents() node1 = parents and parents[0].node() or nullid node2 = ctx.node() block = [] for chunk in patch.diff(repo, node1, node2, m, opts=diffopts): if chunk.startswith("diff") and block: yield tmpl("diffblock", parity=parity.next(), lines=prettyprintlines("".join(block))) block = [] if chunk.startswith("diff") and style != "raw": chunk = "".join(chunk.splitlines(True)[1:]) block.append(chunk) yield tmpl("diffblock", parity=parity.next(), lines=prettyprintlines("".join(block)))
def repo_init(proj): """Init a new mercurial repository for ``proj``.""" repo_path = os.path.join(G.REPOSITORY, proj) try: repo = repo_get(proj) except SPAMRepoNotFound: commands.init(repo_ui, repo_path) repo = repo_get(proj) hgignore_path = os.path.join(G.REPOSITORY, proj, '.hgignore') if not os.path.exists(hgignore_path): hgignore = open(hgignore_path, 'w') hgignore.write('syntax: regexp\n') hgignore.write('^.previews/') hgignore.close() if not '.hgignore' in repo['tip']: commands.add(repo_ui, repo, hgignore_path) matched = match.exact(repo.root, repo.getcwd(), ['.hgignore']) commit_id = repo.commit('add .hgignore', user='******', match=matched)
def getChunksForFile(self, wfile): repo = self.repo ctx = self.ctx if isinstance(ctx, patchctx): if wfile in ctx._files: return ctx._files[wfile] else: return [] else: buf = cStringIO.StringIO() diffopts = patch.diffopts(repo.ui, {'git':True}) m = matchmod.exact(repo.root, repo.root, [wfile]) for p in patch.diff(repo, ctx.p1().node(), None, match=m, opts=diffopts): buf.write(p) buf.seek(0) chunks = record.parsepatch(buf) if chunks: header = chunks[0] return [header] + header.hunks else: return []
def sign(ui, repo, *revs, **opts): """add a signature for the current or given revision If no revision is given, the parent of the working directory is used, or tip if no revision is checked out. See 'hg help dates' for a list of formats valid for -d/--date. """ mygpg = SSHAuthority.from_ui(ui) sigver = "0" sigmessage = "" date = opts.get('date') if date: opts['date'] = util.parsedate(date) if revs: nodes = [repo.lookup(n) for n in revs] else: nodes = [node for node in repo.dirstate.parents() if node != hgnode.nullid] if len(nodes) > 1: raise util.Abort(_('uncommitted merge - please provide a ' 'specific revision')) if not nodes: nodes = [repo.changelog.tip()] for n in nodes: hexnode = hgnode.hex(n) ui.write(_("Signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n))) # build data data = node2txt(repo, n, sigver) sig = mygpg.sign(data) if not sig: raise util.Abort(_("Error while signing")) sig = binascii.b2a_base64(sig) sig = sig.replace("\n", "") sigmessage += "%s %s %s\n" % (hexnode, sigver, sig) # write it if opts['local']: repo.opener("localsigs", "ab").write(sigmessage) return msigs = match.exact(repo.root, '', ['.hgsshsigs']) s = repo.status(match=msigs, unknown=True, ignored=True)[:6] if util.any(s) and not opts["force"]: raise util.Abort(_("working copy of .hgsshsigs is changed " "(please commit .hgsshsigs manually " "or use --force)")) repo.wfile(".hgsshsigs", "ab").write(sigmessage) if '.hgsshsigs' not in repo.dirstate: repo.add([".hgsshsigs"]) if opts["no_commit"]: return message = opts['message'] if not message: # we don't translate commit messages message = "\n".join(["Added signature for changeset %s" % hgnode.short(n) for n in nodes]) try: repo.commit(message, opts['user'], opts['date'], match=msigs) except ValueError, inst: raise util.Abort(str(inst))
def versions(self, item): local_repo = self._local_repo instance_match = match.exact(local_repo.root, local_repo.getcwd(), [item]) change_contexts = walkchangerevs(local_repo, instance_match, {'rev': None}, lambda ctx, fns: ctx) for change_context in change_contexts: yield Version(change_context)
if os.path.exists(seriespath): os.unlink(seriespath) p1 = repo.dirstate.p1() p2 = node self.log(user, date, message, p1, p2, merge=merge) self.ui.write(str(inst) + '\n') raise TransplantError(_('fix up the merge and run ' 'hg transplant --continue')) else: files = None if merge: p1, p2 = repo.dirstate.parents() repo.setparents(p1, node) m = match.always(repo.root, '') else: m = match.exact(repo.root, '', files) n = repo.commit(message, user, date, extra=extra, match=m, editor=self.editor) if not n: self.ui.warn(_('skipping emptied changeset %s\n') % short(node)) return None if not merge: self.transplants.set(n, node) return n def resume(self, repo, source, opts): '''recover last transaction and apply remaining changesets''' if os.path.exists(os.path.join(self.path, 'journal')): n, node = self.recover(repo, source, opts)
def sign(ui, repo, *revs, **opts): """add a signature for the current or given revision If no revision is given, the parent of the working directory is used, or tip if no revision is checked out. See :hg:`help dates` for a list of formats valid for -d/--date. """ mygpg = newgpg(ui, **opts) sigver = "0" sigmessage = "" date = opts.get('date') if date: opts['date'] = util.parsedate(date) if revs: nodes = [repo.lookup(n) for n in revs] else: nodes = [ node for node in repo.dirstate.parents() if node != hgnode.nullid ] if len(nodes) > 1: raise util.Abort( _('uncommitted merge - please provide a ' 'specific revision')) if not nodes: nodes = [repo.changelog.tip()] for n in nodes: hexnode = hgnode.hex(n) ui.write( _("signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n))) # build data data = node2txt(repo, n, sigver) sig = mygpg.sign(data) if not sig: raise util.Abort(_("error while signing")) sig = binascii.b2a_base64(sig) sig = sig.replace("\n", "") sigmessage += "%s %s %s\n" % (hexnode, sigver, sig) # write it if opts['local']: repo.opener.append("localsigs", sigmessage) return msigs = match.exact(repo.root, '', ['.hgsigs']) s = repo.status(match=msigs, unknown=True, ignored=True)[:6] if util.any(s) and not opts["force"]: raise util.Abort( _("working copy of .hgsigs is changed " "(please commit .hgsigs manually " "or use --force)")) sigsfile = repo.wfile(".hgsigs", "ab") sigsfile.write(sigmessage) sigsfile.close() if '.hgsigs' not in repo.dirstate: repo[None].add([".hgsigs"]) if opts["no_commit"]: return message = opts['message'] if not message: # we don't translate commit messages message = "\n".join([ "Added signature for changeset %s" % hgnode.short(n) for n in nodes ]) try: repo.commit(message, opts['user'], opts['date'], match=msigs) except ValueError, inst: raise util.Abort(str(inst))
def sign(ui, repo, *revs, **opts): """add a signature for the current or given revision If no revision is given, the parent of the working directory is used, or tip if no revision is checked out. See :hg:`help dates` for a list of formats valid for -d/--date. """ mygpg = newgpg(ui, **opts) sigver = "0" sigmessage = "" date = opts.get("date") if date: opts["date"] = util.parsedate(date) if revs: nodes = [repo.lookup(n) for n in revs] else: nodes = [node for node in repo.dirstate.parents() if node != hgnode.nullid] if len(nodes) > 1: raise util.Abort(_("uncommitted merge - please provide a " "specific revision")) if not nodes: nodes = [repo.changelog.tip()] for n in nodes: hexnode = hgnode.hex(n) ui.write(_("signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n))) # build data data = node2txt(repo, n, sigver) sig = mygpg.sign(data) if not sig: raise util.Abort(_("error while signing")) sig = binascii.b2a_base64(sig) sig = sig.replace("\n", "") sigmessage += "%s %s %s\n" % (hexnode, sigver, sig) # write it if opts["local"]: repo.vfs.append("localsigs", sigmessage) return if not opts["force"]: msigs = match.exact(repo.root, "", [".hgsigs"]) if util.any(repo.status(match=msigs, unknown=True, ignored=True)): raise util.Abort(_("working copy of .hgsigs is changed "), hint=_("please commit .hgsigs manually")) sigsfile = repo.wfile(".hgsigs", "ab") sigsfile.write(sigmessage) sigsfile.close() if ".hgsigs" not in repo.dirstate: repo[None].add([".hgsigs"]) if opts["no_commit"]: return message = opts["message"] if not message: # we don't translate commit messages message = "\n".join(["Added signature for changeset %s" % hgnode.short(n) for n in nodes]) try: editor = cmdutil.getcommiteditor(editform="gpg.sign", **opts) repo.commit(message, opts["user"], opts["date"], match=msigs, editor=editor) except ValueError, inst: raise util.Abort(str(inst))
def _dosign(ui, repo, *revs, **opts): mygpg = newgpg(ui, **opts) sigver = "0" sigmessage = "" date = opts.get('date') if date: opts['date'] = util.parsedate(date) if revs: nodes = [repo.lookup(n) for n in revs] else: nodes = [node for node in repo.dirstate.parents() if node != hgnode.nullid] if len(nodes) > 1: raise error.Abort(_('uncommitted merge - please provide a ' 'specific revision')) if not nodes: nodes = [repo.changelog.tip()] for n in nodes: hexnode = hgnode.hex(n) ui.write(_("signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n))) # build data data = node2txt(repo, n, sigver) sig = mygpg.sign(data) if not sig: raise error.Abort(_("error while signing")) sig = binascii.b2a_base64(sig) sig = sig.replace("\n", "") sigmessage += "%s %s %s\n" % (hexnode, sigver, sig) # write it if opts['local']: repo.vfs.append("localsigs", sigmessage) return if not opts["force"]: msigs = match.exact(repo.root, '', ['.hgsigs']) if any(repo.status(match=msigs, unknown=True, ignored=True)): raise error.Abort(_("working copy of .hgsigs is changed "), hint=_("please commit .hgsigs manually")) sigsfile = repo.wfile(".hgsigs", "ab") sigsfile.write(sigmessage) sigsfile.close() if '.hgsigs' not in repo.dirstate: repo[None].add([".hgsigs"]) if opts["no_commit"]: return message = opts['message'] if not message: # we don't translate commit messages message = "\n".join(["Added signature for changeset %s" % hgnode.short(n) for n in nodes]) try: editor = cmdutil.getcommiteditor(editform='gpg.sign', **opts) repo.commit(message, opts['user'], opts['date'], match=msigs, editor=editor) except ValueError as inst: raise error.Abort(str(inst))
seriespath = os.path.join(self.path, "series") if os.path.exists(seriespath): os.unlink(seriespath) p1 = repo.dirstate.p1() p2 = node self.log(user, date, message, p1, p2, merge=merge) self.ui.write(str(inst) + "\n") raise TransplantError(_("fix up the merge and run " "hg transplant --continue")) else: files = None if merge: p1, p2 = repo.dirstate.parents() repo.setparents(p1, node) m = match.always(repo.root, "") else: m = match.exact(repo.root, "", files) n = repo.commit(message, user, date, extra=extra, match=m, editor=self.editor) if not n: self.ui.warn(_("skipping emptied changeset %s\n") % short(node)) return None if not merge: self.transplants.set(n, node) return n def resume(self, repo, source, opts): """recover last transaction and apply remaining changesets""" if os.path.exists(os.path.join(self.path, "journal")): n, node = self.recover(repo, source, opts) self.ui.status(_("%s transplanted as %s\n") % (short(node), short(n)))
def applyone(self, repo, node, cl, patchfile, merge=False, log=False, filter=None): '''apply the patch in patchfile to the repository as a transplant''' (manifest, user, (time, timezone), files, message) = cl[:5] date = "%d %d" % (time, timezone) extra = {'transplant_source': node} if filter: (user, date, message) = self.filter(filter, node, cl, patchfile) if log: # we don't translate messages inserted into commits message += '\n(transplanted from %s)' % revlog.hex(node) self.ui.status(_('applying %s\n') % short(node)) self.ui.note('%s %s\n%s\n' % (user, date, message)) if not patchfile and not merge: raise util.Abort(_('can only omit patchfile if merging')) if patchfile: try: files = set() patch.patch(self.ui, repo, patchfile, files=files, eolmode=None) files = list(files) except Exception as inst: seriespath = os.path.join(self.path, 'series') if os.path.exists(seriespath): os.unlink(seriespath) p1 = repo.dirstate.p1() p2 = node self.log(user, date, message, p1, p2, merge=merge) self.ui.write(str(inst) + '\n') raise TransplantError( _('fix up the merge and run ' 'hg transplant --continue')) else: files = None if merge: p1, p2 = repo.dirstate.parents() repo.setparents(p1, node) m = match.always(repo.root, '') else: m = match.exact(repo.root, '', files) n = repo.commit(message, user, date, extra=extra, match=m, editor=self.getcommiteditor()) if not n: self.ui.warn(_('skipping emptied changeset %s\n') % short(node)) return None if not merge: self.transplants.set(n, node) return n
os.unlink(seriespath) p1 = repo.dirstate.parents()[0] p2 = node self.log(user, date, message, p1, p2, merge=merge) self.ui.write(str(inst) + '\n') raise util.Abort( _('fix up the merge and run ' 'hg transplant --continue')) else: files = None if merge: p1, p2 = repo.dirstate.parents() repo.dirstate.setparents(p1, node) m = match.always(repo.root, '') else: m = match.exact(repo.root, '', files) n = repo.commit(message, user, date, extra=extra, match=m) if not n: # Crash here to prevent an unclear crash later, in # transplants.write(). This can happen if patch.patch() # does nothing but claims success or if repo.status() fails # to report changes done by patch.patch(). These both # appear to be bugs in other parts of Mercurial, but dying # here, as soon as we can detect the problem, is preferable # to silently dropping changesets on the floor. raise RuntimeError('nothing committed after transplant') if not merge: self.transplants.set(n, node) return n
olddata = repo.filectx(oldname, fileid=node).data() elif status == 'M': if wfile not in ctx2: # merge situation where file was added in other branch self.flabel += _(' <i>(was added)</i>') return oldname = wfile olddata = ctx2[wfile].data() else: return self.olddata = olddata if changeselect: diffopts = patch.diffopts(repo.ui, {}) diffopts.git = True m = match.exact(repo.root, repo.root, [wfile]) fp = cStringIO.StringIO() for c in patch.diff(repo, ctx.node(), None, match=m, opts=diffopts): fp.write(c) fp.seek(0) # feed diffs through record.parsepatch() for more fine grained # chunk selection filediffs = record.parsepatch(fp) if filediffs: self.changes = filediffs[0] else: self.diff = '' return self.changes.excludecount = 0 values = []
def _dosign(ui, repo, *revs, **opts): mygpg = newgpg(ui, **opts) sigver = "0" sigmessage = "" date = opts.get('date') if date: opts['date'] = util.parsedate(date) if revs: nodes = [repo.lookup(n) for n in revs] else: nodes = [ node for node in repo.dirstate.parents() if node != hgnode.nullid ] if len(nodes) > 1: raise error.Abort( _('uncommitted merge - please provide a ' 'specific revision')) if not nodes: nodes = [repo.changelog.tip()] for n in nodes: hexnode = hgnode.hex(n) ui.write( _("signing %d:%s\n") % (repo.changelog.rev(n), hgnode.short(n))) # build data data = node2txt(repo, n, sigver) sig = mygpg.sign(data) if not sig: raise error.Abort(_("error while signing")) sig = binascii.b2a_base64(sig) sig = sig.replace("\n", "") sigmessage += "%s %s %s\n" % (hexnode, sigver, sig) # write it if opts['local']: repo.vfs.append("localsigs", sigmessage) return if not opts["force"]: msigs = match.exact(repo.root, '', ['.hgsigs']) if any(repo.status(match=msigs, unknown=True, ignored=True)): raise error.Abort(_("working copy of .hgsigs is changed "), hint=_("please commit .hgsigs manually")) sigsfile = repo.wvfs(".hgsigs", "ab") sigsfile.write(sigmessage) sigsfile.close() if '.hgsigs' not in repo.dirstate: repo[None].add([".hgsigs"]) if opts["no_commit"]: return message = opts['message'] if not message: # we don't translate commit messages message = "\n".join([ "Added signature for changeset %s" % hgnode.short(n) for n in nodes ]) try: editor = cmdutil.getcommiteditor(editform='gpg.sign', **opts) repo.commit(message, opts['user'], opts['date'], match=msigs, editor=editor) except ValueError as inst: raise error.Abort(str(inst))
def _readStatus(self, ctx, ctx2, wfile, status, changeselect, force): def getstatus(repo, n1, n2, wfile): m = match.exact(repo.root, repo.getcwd(), [wfile]) modified, added, removed = repo.status(n1, n2, match=m)[:3] if wfile in modified: return 'M' if wfile in added: return 'A' if wfile in removed: return 'R' if wfile in ctx: return 'C' return None isbfile = False repo = ctx._repo maxdiff = repo.maxdiff self.flabel = u'<b>%s</b>' % self.filePath() if ctx2: # If a revision to compare to was provided, we must put it in # the context of the subrepo as well if ctx2._repo.root != ctx._repo.root: wsub2, wfileinsub2, sctx2 = \ hglib.getDeepestSubrepoContainingFile(wfile, ctx2) if wsub2: ctx2 = sctx2 absfile = repo.wjoin(wfile) if (wfile in ctx and 'l' in ctx.flags(wfile)) or \ os.path.islink(absfile): if wfile in ctx: data = ctx[wfile].data() else: data = os.readlink(absfile) self.contents = data self.flabel += _(' <i>(is a symlink)</i>') return if ctx2 is None: ctx2 = ctx.p1() if status is None: status = getstatus(repo, ctx2.node(), ctx.node(), wfile) mde = _('File or diffs not displayed: ' 'File is larger than the specified max size.\n' 'maxdiff = %s KB') % (maxdiff // 1024) if status in ('R', '!'): if wfile in ctx.p1(): fctx = ctx.p1()[wfile] if fctx._filelog.rawsize(fctx.filerev()) > maxdiff: self.error = mde else: olddata = fctx.data() if '\0' in olddata: self.error = 'binary file' else: self.contents = olddata self.flabel += _(' <i>(was deleted)</i>') elif hasattr(ctx.p1(), 'hasStandin') and ctx.p1().hasStandin(wfile): self.error = 'binary file' self.flabel += _(' <i>(was deleted)</i>') else: self.flabel += _(' <i>(was added, now missing)</i>') return if status in ('I', '?'): assert ctx.rev() is None self.flabel += _(' <i>(is unversioned)</i>') if os.path.getsize(absfile) > maxdiff: self.error = mde return data = util.posixfile(absfile, 'r').read() if not force and '\0' in data: self.error = 'binary file' else: self.contents = data return if status in ('M', 'A', 'C'): if ctx.hasStandin(wfile): wfile = ctx.findStandin(wfile) isbfile = True try: fctx, newdata = self._checkMaxDiff(ctx, wfile, maxdiff, force) except _BadContent: if status == 'A': self._checkRenamed(repo, ctx, ctx2, wfile) raise self.contents = newdata if status == 'C': # no further comparison is necessary return for pctx in ctx.parents(): if 'x' in fctx.flags() and 'x' not in pctx.flags(wfile): self.elabel = _("exec mode has been " "<font color='red'>set</font>") elif 'x' not in fctx.flags() and 'x' in pctx.flags(wfile): self.elabel = _("exec mode has been " "<font color='red'>unset</font>") if status == 'A': oldname = self._checkRenamed(repo, ctx, ctx2, wfile) if not oldname: return olddata = ctx2[oldname].data() elif status == 'M': if wfile not in ctx2: # merge situation where file was added in other branch self.flabel += _(' <i>(was added)</i>') return oldname = wfile olddata = ctx2[wfile].data() else: return self.olddata = olddata if changeselect: diffopts = patch.diffopts(repo.ui, {}) diffopts.git = True m = match.exact(repo.root, repo.root, [wfile]) fp = cStringIO.StringIO() for c in patch.diff(repo, ctx.node(), None, match=m, opts=diffopts): fp.write(c) fp.seek(0) # feed diffs through parsepatch() for more fine grained # chunk selection filediffs = patch.parsepatch(fp) if filediffs and filediffs[0].hunks: self.changes = filediffs[0] else: self.diff = '' return self.changes.excludecount = 0 values = [] lines = 0 for chunk in self.changes.hunks: buf = cStringIO.StringIO() chunk.write(buf) chunk.excluded = False val = buf.getvalue() values.append(val) chunk.lineno = lines chunk.linecount = len(val.splitlines()) lines += chunk.linecount self.diff = ''.join(values) else: diffopts = patch.diffopts(repo.ui, {}) diffopts.git = False newdate = util.datestr(ctx.date()) olddate = util.datestr(ctx2.date()) if isbfile: olddata += '\0' newdata += '\0' difftext = mdiff.unidiff(olddata, olddate, newdata, newdate, oldname, wfile, opts=diffopts) if difftext: self.diff = ('diff -r %s -r %s %s\n' % (ctx, ctx2, oldname) + difftext) else: self.diff = ''