Retrieves file identified by ``name``.

           The file is saved as ``save_to``. If ``add_to_cache`` is ``True``,
           the file is added to the local store. If ``force_refresh`` is
           ``True``, local cache is not examined if a remote store is
           configured.

           If a remote store is configured, but ``name`` does not contain a
           version, the local data store is not used, as we cannot guarantee
           that the version there is fresh.

           Local data store implemented in :class:`LocalDataStore` tries to not
           copy the entire file to ``save_to`` if possible, but instead uses
           hardlinking. Therefore you should not modify the file if you don't
           want to totally blow something.

           This method returns the full versioned name of the retrieved file.

def get_file(self, name, save_to, add_to_cache=True,
                 force_refresh=False, _lock_exclusive=False):
        """Retrieves file identified by ``name``.

           The file is saved as ``save_to``. If ``add_to_cache`` is ``True``,
           the file is added to the local store. If ``force_refresh`` is
           ``True``, local cache is not examined if a remote store is
           configured.

           If a remote store is configured, but ``name`` does not contain a
           version, the local data store is not used, as we cannot guarantee
           that the version there is fresh.

           Local data store implemented in :class:`LocalDataStore` tries to not
           copy the entire file to ``save_to`` if possible, but instead uses
           hardlinking. Therefore you should not modify the file if you don't
           want to totally blow something.

           This method returns the full versioned name of the retrieved file.
        """

        uname, version = split_name(name)

        lock = None
        if self.local_store:
            lock = self.lock_manager.lock_for(uname)
            if _lock_exclusive:
                lock.lock_exclusive()
            else:
                lock.lock_shared()
        else:
            add_to_cache = False

        t = time.time()
        logger.debug('    downloading %s', name)
        try:
            if not self.remote_store or (version is not None
                                         and not force_refresh):
                try:
                    if self.local_store and self.local_store.exists(name):
                        return self.local_store.get_file(name, save_to)
                except Exception:
                    if self.remote_store:
                        logger.warning("Error getting '%s' from local store",
                                name, exc_info=True)
                    else:
                        raise
            if self.remote_store:
                if not _lock_exclusive and add_to_cache:
                    if lock:
                        lock.unlock()
                    return self.get_file(name, save_to, add_to_cache,
                                         _lock_exclusive=True)
                vname = self.remote_store.get_file(name, save_to)
                if add_to_cache:
                    self._add_to_cache(vname, save_to)
                return vname
            raise FiletrackerError("File not available: %s" % name)
        finally:
            if lock:
                lock.close()
            logger.debug('    processed %s in %.2fs', name, time.time() - t)