def _fetch(self):
        '''
        Fetch the repo. If the local copy was updated, return True. If the
        local copy was already up-to-date, return False.
        '''
        origin = self.repo.remotes[0]
        refs_pre = self.repo.listall_references()
        fetch_kwargs = {}
        # pygit2 radically changed fetchiing in 0.23.2
        if self.remotecallbacks is not None:
            fetch_kwargs['callbacks'] = self.remotecallbacks
        else:
            if self.credentials is not None:
                origin.credentials = self.credentials
        try:
            fetch_kwargs['prune'] = pygit2.GIT_FETCH_PRUNE
        except AttributeError:
            # pruning only available in pygit2 >= 0.26.2
            pass
        try:
            fetch_results = origin.fetch(**fetch_kwargs)
        except GitError as exc:
            exc_str = get_error_message(exc).lower()
            if 'unsupported url protocol' in exc_str \
                    and isinstance(self.credentials, pygit2.Keypair):
                log.error(
                    'Unable to fetch SSH-based %s remote \'%s\'. '
                    'You may need to add ssh:// to the repo string or '
                    'libgit2 must be compiled with libssh2 to support '
                    'SSH authentication.', self.role, self.id,
                    exc_info=True
                )
            elif 'authentication required but no callback set' in exc_str:
                log.error(
                    '%s remote \'%s\' requires authentication, but no '
                    'authentication configured', self.role, self.id,
                    exc_info=True
                )
            else:
                log.error(
                    'Error occurred fetching %s remote \'%s\': %s',
                    self.role, self.id, exc,
                    exc_info=True
                )
            return False
        try:
            # pygit2.Remote.fetch() returns a dict in pygit2 < 0.21.0
            received_objects = fetch_results['received_objects']
        except (AttributeError, TypeError):
            # pygit2.Remote.fetch() returns a class instance in
            # pygit2 >= 0.21.0
            received_objects = fetch_results.received_objects
        if received_objects != 0:
            log.debug(
                '%s received %s objects for remote \'%s\'',
                self.role, received_objects, self.id
            )
        else:
            log.debug('%s remote \'%s\' is up-to-date', self.role, self.id)
        refs_post = self.repo.listall_references()
        cleaned = self.clean_stale_refs(local_refs=refs_post)
        return True \
            if (received_objects or refs_pre != refs_post or cleaned) \
            else None