Beispiel #1
0
def statbfile(repo, proto, sha):
    """statbfile sends '2\n' if the bfile is missing, '1\n' if it has a
    mismatched checksum, or '0\n' if it is in good condition"""
    filename = bfutil.findfile(repo, sha)
    if not filename:
        return '2\n'
    fd = None
    try:
        fd = open(filename, 'rb')
        return bfutil.hexsha1(fd) == sha and '0\n' or '1\n'
    finally:
        if fd:
            fd.close()
Beispiel #2
0
def getbfile(repo, proto, sha):
    """getbfile retrieves a bfile from the repository-local cache or system
    cache."""
    filename = bfutil.findfile(repo, sha)
    if not filename:
        raise util.Abort(_('requested bfile %s not present in cache') % sha)
    f = open(filename, 'rb')
    length = os.fstat(f.fileno())[6]
    # since we can't set an HTTP content-length header here, and mercurial core
    # provides no way to give the length of a streamres (and reading the entire
    # file into RAM would be ill-advised), we just send the length on the first
    # line of the response, like the ssh proto does for string responses.
    def generator():
        yield '%d\n' % length
        for chunk in f:
            yield chunk
    return wireproto.streamres(generator())
Beispiel #3
0
    def getfilectx(repo, memctx, f):
        if bfutil.standin(f) in files:
            # if the file isn't in the manifest then it was removed
            # or renamed, raise IOError to indicate this
            try:
                fctx = ctx.filectx(bfutil.standin(f))
            except error.LookupError:
                raise IOError()
            renamed = fctx.renamed()
            if renamed:
                renamed = bfutil.splitstandin(renamed[0])

            hash = fctx.data().strip()
            path = bfutil.findfile(rsrc, hash)
            ### TODO: What if the file is not cached?
            data = ''
            fd = None
            try:
                fd = open(path, 'rb')
                data = fd.read()
            finally:
                if fd: fd.close()
            return context.memfilectx(f, data, 'l' in fctx.flags(),
                                      'x' in fctx.flags(), renamed)
        else:
            try:
                fctx = ctx.filectx(f)
            except error.LookupError:
                raise IOError()
            renamed = fctx.renamed()
            if renamed:
                renamed = renamed[0]
            data = fctx.data()
            if f == '.hgtags':
                newdata = []
                for line in data.splitlines():
                    id, name = line.split(' ', 1)
                    newdata.append('%s %s\n' % (node.hex(revmap[node.bin(id)]),
                        name))
                data = ''.join(newdata)
            return context.memfilectx(f, data, 'l' in fctx.flags(),
                                      'x' in fctx.flags(), renamed)
Beispiel #4
0
def uploadbfiles(ui, rsrc, rdst, files):
    '''upload big files to the central store'''

    # Don't upload locally. All bfiles are in the system wide cache
    # so the other repo can just get them from there.
    if not files or rdst.local():
        return

    store = basestore._openstore(rsrc, rdst, put=True)

    at = 0
    for hash in files:
        ui.progress(_('uploading bfiles'), at, unit='bfile', total=len(files))
        if store.exists(hash):
            at += 1
            continue
        source = bfutil.findfile(rsrc, hash)
        if not source:
            raise util.Abort(_('Missing bfile %s needs to be uploaded') % hash)
        # XXX check for errors here
        store.put(source, hash)
        at += 1
    ui.progress('uploading bfiles', None)
Beispiel #5
0
def updatebfiles(ui, repo):
    wlock = repo.wlock()
    try:
        bfdirstate = bfutil.openbfdirstate(ui, repo)
        s = bfdirstate.status(match_.always(repo.root, repo.getcwd()), [],
            False, False, False)
        unsure, modified, added, removed, missing, unknown, ignored, clean = s

        bfiles = bfutil.listbfiles(repo)
        toget = []
        at = 0
        updated = 0
        removed = 0
        printed = False
        if bfiles:
            ui.status(_('getting changed bfiles\n'))
            printed = True

        for bfile in bfiles:
            at += 1
            if os.path.exists(repo.wjoin(bfile)) and not \
                    os.path.exists(repo.wjoin(bfutil.standin(bfile))):
                os.unlink(repo.wjoin(bfile))
                removed += 1
                bfdirstate.forget(bfutil.unixpath(bfile))
                continue
            expectedhash = repo[None][bfutil.standin(bfile)].data().strip()
            mode = os.stat(repo.wjoin(bfutil.standin(bfile))).st_mode
            if not os.path.exists(repo.wjoin(bfile)) or expectedhash != \
                    bfutil.hashfile(repo.wjoin(bfile)):
                path = bfutil.findfile(repo, expectedhash)
                if not path:
                    toget.append((bfile, expectedhash))
                else:
                    util.makedirs(os.path.dirname(repo.wjoin(bfile)))
                    shutil.copy(path,  repo.wjoin(bfile))
                    os.chmod(repo.wjoin(bfile), mode)
                    updated += 1
                    bfdirstate.normal(bfutil.unixpath(bfile))
            elif os.path.exists(repo.wjoin(bfile)) and mode != \
                    os.stat(repo.wjoin(bfile)).st_mode:
                os.chmod(repo.wjoin(bfile), mode)
                updated += 1
                bfdirstate.normal(bfutil.unixpath(bfile))

        if toget:
            store = basestore._openstore(repo)
            (success, missing) = store.get(toget)
        else:
            success, missing = [],[]

        for (filename, hash) in success:
            mode = os.stat(repo.wjoin(bfutil.standin(filename))).st_mode
            os.chmod(repo.wjoin(filename), mode)
            updated += 1
            bfdirstate.normal(bfutil.unixpath(filename))

        for bfile in bfdirstate:
            if bfile not in bfiles:
                if os.path.exists(repo.wjoin(bfile)):
                    if not printed:
                        ui.status(_('getting changed bfiles\n'))
                        printed = True
                    os.unlink(repo.wjoin(bfile))
                    removed += 1
                    path = bfutil.unixpath(bfile)
                    try:
                        # Mercurial >= 1.9
                        bfdirstate.drop(path)
                    except AttributeError:
                        # Mercurial <= 1.8
                        bfdirstate.forget(path)

        bfdirstate.write()
        if printed:
            ui.status(_('%d big files updated, %d removed\n') % (updated,
                removed))
    finally:
        wlock.release()
Beispiel #6
0
def revertbfiles(ui, repo, filelist=None):
    wlock = repo.wlock()
    try:
        bfdirstate = bfutil.openbfdirstate(ui, repo)
        s = bfdirstate.status(match_.always(repo.root, repo.getcwd()), [],
            False, False, False)
        unsure, modified, added, removed, missing, unknown, ignored, clean = s

        bfiles = bfutil.listbfiles(repo)
        toget = []
        at = 0
        updated = 0
        for bfile in bfiles:
            if filelist is None or bfile in filelist:
                if not os.path.exists(repo.wjoin(bfutil.standin(bfile))):
                    bfdirstate.remove(bfile)
                    continue
                if os.path.exists(repo.wjoin(bfutil.standin(os.path.join(bfile\
                    + '.orig')))):
                    shutil.copyfile(repo.wjoin(bfile), repo.wjoin(bfile + \
                        '.orig'))
                at += 1
                expectedhash = repo[None][bfutil.standin(bfile)].data().strip()
                mode = os.stat(repo.wjoin(bfutil.standin(bfile))).st_mode
                if not os.path.exists(repo.wjoin(bfile)) or expectedhash != \
                        bfutil.hashfile(repo.wjoin(bfile)):
                    path = bfutil.findfile(repo, expectedhash)
                    if path is None:
                        toget.append((bfile, expectedhash))
                    else:
                        util.makedirs(os.path.dirname(repo.wjoin(bfile)))
                        shutil.copy(path, repo.wjoin(bfile))
                        os.chmod(repo.wjoin(bfile), mode)
                        updated += 1
                        if bfutil.standin(bfile) not in repo['.']:
                            bfdirstate.add(bfutil.unixpath(bfile))
                        elif expectedhash == repo['.'][bfutil.standin(bfile)] \
                                .data().strip():
                            bfdirstate.normal(bfutil.unixpath(bfile))
                        else:
                            bfutil.dirstate_normaldirty(bfdirstate,
                                bfutil.unixpath(bfile))
                elif os.path.exists(repo.wjoin(bfile)) and mode != \
                        os.stat(repo.wjoin(bfile)).st_mode:
                    os.chmod(repo.wjoin(bfile), mode)
                    updated += 1
                    if bfutil.standin(bfile) not in repo['.']:
                        bfdirstate.add(bfutil.unixpath(bfile))
                    elif expectedhash == \
                            repo['.'][bfutil.standin(bfile)].data().strip():
                        bfdirstate.normal(bfutil.unixpath(bfile))
                    else:
                        bfutil.dirstate_normaldirty(bfdirstate,
                            bfutil.unixpath(bfile))

        if toget:
            store = basestore._openstore(repo)
            success, missing = store.get(toget)
        else:
            success, missing = [], []

        for (filename, hash) in success:
            mode = os.stat(repo.wjoin(bfutil.standin(filename))).st_mode
            os.chmod(repo.wjoin(filename), mode)
            updated += 1
            if bfutil.standin(filename) not in repo['.']:
                bfdirstate.add(bfutil.unixpath(filename))
            elif hash == repo['.'][bfutil.standin(filename)].data().strip():
                bfdirstate.normal(bfutil.unixpath(filename))
            else:
                bfutil.dirstate_normaldirty(bfdirstate,
                    bfutil.unixpath(filename))

        removed = 0
        for bfile in bfdirstate:
            if filelist is None or bfile in filelist:
                if not os.path.exists(repo.wjoin(bfutil.standin(bfile))):
                    if os.path.exists(repo.wjoin(bfile)):
                        os.unlink(repo.wjoin(bfile))
                        removed += 1
                        if bfutil.standin(bfile) in repo['.']:
                            bfdirstate.remove(bfutil.unixpath(bfile))
                        else:
                            bfdirstate.forget(bfutil.unixpath(bfile))
                else:
                    state = repo.dirstate[bfutil.standin(bfile)]
                    if state == 'n':
                        bfdirstate.normal(bfile)
                    elif state == 'r':
                        bfdirstate.remove(bfile)
                    elif state == 'a':
                        bfdirstate.add(bfile)
                    elif state == '?':
                        try:
                            # Mercurial >= 1.9
                            bfdirstate.drop(bfile)
                        except AttributeError:
                            # Mercurial <= 1.8
                            bfdirstate.forget(bfile)
        bfdirstate.write()
    finally:
        wlock.release()