Пример #1
0
    def _resolve_entry(self, path):
        """Given a path, load its node and flags, or raise KeyError if missing.

        This takes into account any pending writes in the builder.
        """
        upath = pycompat.fsdecode(path)
        ent = None
        if path in self._pending_changes:
            val = self._pending_changes[path]
            if val is None:
                raise KeyError
            return val
        t = self._tree
        comps = upath.split('/')
        te = self._tree
        for comp in comps[:-1]:
            te = te[comp]
            t = self._git_repo[te.id]
        ent = t[comps[-1]]
        if ent.filemode == pygit2.GIT_FILEMODE_BLOB:
            flags = b''
        elif ent.filemode == pygit2.GIT_FILEMODE_BLOB_EXECUTABLE:
            flags = b'x'
        elif ent.filemode == pygit2.GIT_FILEMODE_LINK:
            flags = b'l'
        else:
            raise ValueError('unsupported mode %s' % oct(ent.filemode))
        return ent.id.raw, flags
Пример #2
0
 def drop(self, f):
     index = self.git.index
     index.read()
     fs = pycompat.fsdecode(f)
     if fs in index:
         index.remove(fs)
         index.write()
def _promptvctextension(ui, cw, ext, msg):
    ext_path = _vctextpath(pycompat.sysstr(ext))

    # Do nothing (return) if the user has configured this extension, unless it
    # points to the directory that we manage and that directory is missing.
    users_ext_path = ui.config(b'extensions', ext)
    if users_ext_path != None:
        users_ext_path = pycompat.fsdecode(
            util.normpath(util.expandpath(users_ext_path)))
        if users_ext_path != ext_path or os.path.exists(ext_path):
            return

    # Verify the extension loads before prompting to enable it. This is
    # done out of paranoia.

    # Even if we launch hg.exe, sys.argv[0] is "hg" on Windows. Since "hg" isn't
    # a Windows application, we can't simply run it. So change to the ".exe"
    # variant if necessary.
    hg = sys.argv[0]
    if sys.platform in ('win32', 'msys') and hg.endswith('hg'):
        hg += '.exe'

    result = subprocess.check_output([
        hg, '--config',
        'extensions.testmodule=%s' % ext_path, '--config', 'ui.traceback=true'
    ],
                                     stderr=subprocess.STDOUT)
    if b'Traceback' in result:
        return

    if uipromptchoice(ui, b'%s (Yn) $$ &Yes $$ &No' % msg):
        return

    _enableext(cw, pycompat.sysstr(ext), ext_path)
Пример #4
0
 def applychanges(self, repo, tr, changes):
     """Apply a list of changes to bookmarks"""
     # TODO: this should respect transactions, but that's going to
     # require enlarging the gitbmstore to know how to do in-memory
     # temporary writes and read those back prior to transaction
     # finalization.
     for name, node in changes:
         if node is None:
             self.gitrepo.references.delete(_BMS_PREFIX +
                                            pycompat.fsdecode(name))
         else:
             self.gitrepo.references.create(
                 _BMS_PREFIX + pycompat.fsdecode(name),
                 gitutil.togitnode(node),
                 force=True,
             )
Пример #5
0
    def parents(self, node):
        gn = gitutil.togitnode(node)
        gp = pycompat.fsdecode(self.path)
        ps = []
        for p in self._db.execute(
            '''SELECT p1filenode, p2filenode FROM changedfiles
WHERE filenode = ? AND filename = ?
''',
            (gn, gp),
        ).fetchone():
            if p is None:
                commit = self._db.execute(
                    "SELECT node FROM changedfiles "
                    "WHERE filenode = ? AND filename = ?",
                    (gn, gp),
                ).fetchone()[0]
                # This filelog is missing some data. Build the
                # filelog, then recurse (which will always find data).
                if pycompat.ispy3:
                    commit = commit.decode('ascii')
                index.fill_in_filelog(self.gitrepo, self._db, commit, gp, gn)
                return self.parents(node)
            else:
                ps.append(bin(p))
        return ps
Пример #6
0
 def set_untracked(self, f):
     index = self.git.index
     index.read()
     fs = pycompat.fsdecode(f)
     if fs in index:
         index.remove(fs)
         index.write()
         return True
     return False
Пример #7
0
 def set_tracked(self, f):
     uf = pycompat.fsdecode(f)
     if uf in self.git.index:
         return False
     index = self.git.index
     index.read()
     index.add(uf)
     index.write()
     return True
Пример #8
0
    def __iter__(self):
        for clrev in self._db.execute(
            '''
SELECT rev FROM changelog
INNER JOIN changedfiles ON changelog.node = changedfiles.node
WHERE changedfiles.filename = ? AND changedfiles.filenode != ?
        ''',
            (pycompat.fsdecode(self.path), gitutil.nullgit),
        ):
            yield clrev[0]
Пример #9
0
def _checkevolve(ui, cw, hg_version):
    if hg_version < (4, 3, 0):
        ui.warn(EVOLVE_INCOMPATIBLE)
        return

    remote_evolve_path = b'https://www.mercurial-scm.org/repo/evolve/'
    # Install to the same dir as v-c-t, unless the mozbuild directory path is passed (testing)
    evolve_clone_dir = ui.config(b'mozilla', b'mozbuild_state_path', _vcthome())

    local_evolve_path = b'%(evolve_clone_dir)s/evolve' % {b'evolve_clone_dir': evolve_clone_dir}
    evolve_config_value = os.path.normpath('%(evolve_path)s/hgext3rd/evolve' % \
                                           {'evolve_path': pycompat.sysstr(local_evolve_path)})

    users_evolve_path = ui.config(b'extensions', b'evolve')
    if users_evolve_path:
        users_evolve_path = os.path.normpath(pycompat.fsdecode(util.normpath(util.expandpath(users_evolve_path))))

    # If evolve is not installed, install it. (If the user's path to evolve is
    # the path that we manage, but it doesn't exist yet, assume that their
    # config file has been copied to a new machine and we need to clone evolve.
    if users_evolve_path == None or \
            (users_evolve_path == evolve_config_value and not os.path.exists(evolve_config_value)):
        if uipromptchoice(ui, EVOLVE_INFO_WARNING):
            return

        try:
            # Clone the evolve extension and enable
            hg.clone(ui, {}, remote_evolve_path, branch=(b'stable',), dest=local_evolve_path)
            _enableext(cw, 'evolve', evolve_config_value)

            ui.write(b'Evolve was downloaded successfully.\n')

        except error.Abort as hg_err:
            ui.write(pycompat.bytestr(hg_err))
            ui.write(EVOLVE_CLONE_ERROR)

        return

    # If evolve is installed and managed by this wizard,
    # update it via pull/update
    if users_evolve_path == evolve_config_value:
        if uipromptchoice(ui, EVOLVE_UPDATE_PROMPT % {b'evolve_dir': local_evolve_path}):
            return

        try:
            local_evolve_repo = hg.repository(ui, local_evolve_path)

            # Pull the latest stable, update to tip
            hgpull(ui, local_evolve_repo, source=remote_evolve_path, branch=(b'stable',))
            hgupdate(ui, local_evolve_repo, rev=b'stable')

            ui.write(b'Evolve was updated successfully.\n')

        except error.Abort as hg_err:
            ui.write(EVOLVE_CLONE_ERROR)
Пример #10
0
    def rev(self, node):
        row = self._db.execute(
            '''
SELECT rev FROM changelog
INNER JOIN changedfiles ON changelog.node = changedfiles.node
WHERE changedfiles.filename = ? AND changedfiles.filenode = ?''',
            (pycompat.fsdecode(self.path), gitutil.togitnode(node)),
        ).fetchone()
        if row is None:
            raise error.LookupError(self.path, node, _(b'no such node'))
        return int(row[0])
Пример #11
0
    def node(self, rev):
        maybe = self._db.execute(
            '''SELECT filenode FROM changedfiles
INNER JOIN changelog ON changelog.node = changedfiles.node
WHERE changelog.rev = ? AND filename = ?
''',
            (rev, pycompat.fsdecode(self.path)),
        ).fetchone()
        if maybe is None:
            raise IndexError('gitlog %r out of range %d' % (self.path, rev))
        return bin(maybe[0])
Пример #12
0
 def inner(*args, **kwargs):
     cassette = pycompat.fsdecode(kwargs.pop(r'test_vcr', None))
     if cassette:
         import hgdemandimport
         with hgdemandimport.deactivated():
             import vcr as vcrmod
             import vcr.stubs as stubs
             vcr = vcrmod.VCR(serializer=r'json',
                              before_record_request=sanitiserequest,
                              before_record_response=sanitiseresponse,
                              custom_patches=[
                                  (urlmod, r'httpconnection',
                                   stubs.VCRHTTPConnection),
                                  (urlmod, r'httpsconnection',
                                   stubs.VCRHTTPSConnection),
                              ])
             vcr.register_matcher(r'hgmatcher', hgmatcher)
             with vcr.use_cassette(cassette, match_on=[r'hgmatcher']):
                 return fn(*args, **kwargs)
     return fn(*args, **kwargs)
Пример #13
0
 def remove(self, f):
     index = self.git.index
     index.read()
     index.remove(pycompat.fsdecode(f))
     index.write()
Пример #14
0
def getgid(groupname):
    try:
        gid = grp.getgrnam(pycompat.fsdecode(groupname)).gr_gid
        return gid
    except KeyError:
        return None
Пример #15
0
 def __getitem__(self, k):
     return (
         self.gitrepo.references[_BMS_PREFIX + pycompat.fsdecode(k)]
         .peel()
         .id.raw
     )
Пример #16
0
 def __contains__(self, name):
     return (
         _BMS_PREFIX + pycompat.fsdecode(name)
     ) in self.gitrepo.references
Пример #17
0
 def add(self, f):
     index = self.git.index
     index.read()
     index.add(pycompat.fsdecode(f))
     index.write()
Пример #18
0
    def write(self, transaction, link, p1, p2, added, removed, match=None):
        # We're not (for now, anyway) going to audit filenames, so we
        # can ignore added and removed.

        # TODO what does this match argument get used for? hopefully
        # just narrow?
        assert not match or isinstance(match, matchmod.alwaysmatcher)

        touched_dirs = pathutil.dirs(list(self._pending_changes))
        trees = {
            b'': self._tree,
        }
        # path: treebuilder
        builders = {
            b'': self._repo.TreeBuilder(self._tree),
        }
        # get a TreeBuilder for every tree in the touched_dirs set
        for d in sorted(touched_dirs, key=lambda x: (len(x), x)):
            if d == b'':
                # loaded root tree above
                continue
            comps = d.split(b'/')
            full = b''
            for part in comps:
                parent = trees[full]
                try:
                    parent_tree_id = parent[pycompat.fsdecode(part)].id
                    new = self._repo[parent_tree_id]
                except KeyError:
                    # new directory
                    new = None
                full += b'/' + part
                if new is not None:
                    # existing directory
                    trees[full] = new
                    builders[full] = self._repo.TreeBuilder(new)
                else:
                    # new directory, use an empty dict to easily
                    # generate KeyError as any nested new dirs get
                    # created.
                    trees[full] = {}
                    builders[full] = self._repo.TreeBuilder()
        for f, info in self._pending_changes.items():
            if b'/' not in f:
                dirname = b''
                basename = f
            else:
                dirname, basename = f.rsplit(b'/', 1)
                dirname = b'/' + dirname
            if info is None:
                builders[dirname].remove(pycompat.fsdecode(basename))
            else:
                n, fl = info
                mode = {
                    b'': pygit2.GIT_FILEMODE_BLOB,
                    b'x': pygit2.GIT_FILEMODE_BLOB_EXECUTABLE,
                    b'l': pygit2.GIT_FILEMODE_LINK,
                }[fl]
                builders[dirname].insert(
                    pycompat.fsdecode(basename), gitutil.togitnode(n), mode
                )
        # This visits the buffered TreeBuilders in deepest-first
        # order, bubbling up the edits.
        for b in sorted(builders, key=len, reverse=True):
            if b == b'':
                break
            cb = builders[b]
            dn, bn = b.rsplit(b'/', 1)
            builders[dn].insert(
                pycompat.fsdecode(bn), cb.write(), pygit2.GIT_FILEMODE_TREE
            )
        return builders[b''].write().raw