Beispiel #1
0
 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
Beispiel #2
0
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
Beispiel #3
0
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))
Beispiel #4
0
 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
Beispiel #5
0
    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
Beispiel #6
0
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, [])
Beispiel #7
0
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, '', [])
Beispiel #8
0
 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
Beispiel #9
0
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, '', [])
Beispiel #10
0
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)))
Beispiel #11
0
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)
Beispiel #12
0
 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 []
Beispiel #13
0
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))
Beispiel #14
0
 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)
Beispiel #15
0
                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)
Beispiel #16
0
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))
Beispiel #17
0
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))
Beispiel #18
0
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)))
Beispiel #20
0
    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
Beispiel #21
0
                    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
Beispiel #22
0
            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 = []
Beispiel #23
0
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))
Beispiel #24
0
    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 = ''