diff --git a/swh/web/api/utils.py b/swh/web/api/utils.py
index 722be7bd1..d3f7f610d 100644
--- a/swh/web/api/utils.py
+++ b/swh/web/api/utils.py
@@ -1,299 +1,213 @@
 # Copyright (C) 2015-2018  The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU Affero General Public License version 3, or any later version
 # See top-level LICENSE file for more information
 
 
 from swh.web.common.utils import reverse
 from swh.web.common.query import parse_hash
 
 
 def filter_field_keys(data, field_keys):
     """Given an object instance (directory or list), and a csv field keys
     to filter on.
 
     Return the object instance with filtered keys.
 
     Note: Returns obj as is if it's an instance of types not in (dictionary,
     list)
 
     Args:
         - data: one object (dictionary, list...) to filter.
         - field_keys: csv or set of keys to filter the object on
 
     Returns:
         obj filtered on field_keys
 
     """
     if isinstance(data, map):
         return map(lambda x: filter_field_keys(x, field_keys), data)
     if isinstance(data, list):
         return [filter_field_keys(x, field_keys) for x in data]
     if isinstance(data, dict):
         return {k: v for (k, v) in data.items() if k in field_keys}
     return data
 
 
 def person_to_string(person):
     """Map a person (person, committer, tagger, etc...) to a string.
 
     """
     return ''.join([person['name'], ' <', person['email'], '>'])
 
 
 def enrich_object(object):
     """Enrich an object (revision, release) with link to the 'target' of
     type 'target_type'.
 
     Args:
         object: An object with target and target_type keys
         (e.g. release, revision)
 
     Returns:
         Object enriched with target_url pointing to the right
         swh.web.ui.api urls for the pointing object (revision,
         release, content, directory)
 
     """
     obj = object.copy()
     if 'target' in obj and 'target_type' in obj:
         if obj['target_type'] == 'revision':
             obj['target_url'] = reverse('api-revision',
                                         url_args={'sha1_git': obj['target']})
         elif obj['target_type'] == 'release':
             obj['target_url'] = reverse('api-release',
                                         url_args={'sha1_git': obj['target']})
         elif obj['target_type'] == 'content':
             obj['target_url'] = \
                 reverse('api-content',
                         url_args={'q': 'sha1_git:' + obj['target']})
 
         elif obj['target_type'] == 'directory':
             obj['target_url'] = reverse('api-directory',
                                         url_args={'sha1_git': obj['target']})
 
     if 'author' in obj:
         author = obj['author']
         obj['author_url'] = reverse('api-person',
                                     url_args={'person_id': author['id']})
 
     return obj
 
 
 enrich_release = enrich_object
 
 
 def enrich_directory(directory, context_url=None):
     """Enrich directory with url to content or directory.
 
     """
     if 'type' in directory:
         target_type = directory['type']
         target = directory['target']
         if target_type == 'file':
             directory['target_url'] = \
                 reverse('api-content', url_args={'q': 'sha1_git:%s' % target})
             if context_url:
                 directory['file_url'] = context_url + directory['name'] + '/'
         elif target_type == 'dir':
             directory['target_url'] = reverse('api-directory',
                                               url_args={'sha1_git': target})
             if context_url:
                 directory['dir_url'] = context_url + directory['name'] + '/'
         else:
             directory['target_url'] = reverse('api-revision',
                                               url_args={'sha1_git': target})
             if context_url:
                 directory['rev_url'] = context_url + directory['name'] + '/'
 
     return directory
 
 
 def enrich_metadata_endpoint(content):
     """Enrich metadata endpoint with link to the upper metadata endpoint.
 
     """
     c = content.copy()
     c['content_url'] = reverse('api-content',
                                url_args={'q': 'sha1:%s' % c['id']})
     return c
 
 
 def enrich_content(content, top_url=False, query_string=None):
     """Enrich content with links to:
         - data_url: its raw data
         - filetype_url: its filetype information
         - language_url: its programming language information
         - license_url: its licensing information
 
     Args:
         content: dict of data associated to a swh content object
         top_url: whether or not to include the content url in
             the enriched data
         query_string: optional query string of type '<algo>:<hash>'
             used when requesting the content, it acts as a hint
             for picking the same hash method when computing
             the url listed above
 
     Returns:
         An enriched content dict filled with additional urls
 
     """
     checksums = content
     if 'checksums' in content:
         checksums = content['checksums']
     hash_algo = 'sha1'
     if query_string:
         hash_algo = parse_hash(query_string)[0]
     if hash_algo in checksums:
         q = '%s:%s' % (hash_algo, checksums[hash_algo])
         if top_url:
             content['content_url'] = reverse('api-content', url_args={'q': q})
         content['data_url'] = reverse('api-content-raw', url_args={'q': q})
         content['filetype_url'] = reverse('api-content-filetype',
                                           url_args={'q': q})
         content['language_url'] = reverse('api-content-language',
                                           url_args={'q': q})
         content['license_url'] = reverse('api-content-license',
                                          url_args={'q': q})
 
     return content
 
 
-def _get_path_list(path_string):
-    """Helper for enrich_revision: get a list of the sha1 id of the navigation
-    breadcrumbs, ordered from the oldest to the most recent.
-
-    Args:
-        path_string: the path as a '/'-separated string
-
-    Returns:
-        The navigation context as a list of sha1 revision ids
-    """
-    return path_string.split('/')
-
-
-def _get_revision_contexts(rev_id, context):
-    """Helper for enrich_revision: retrieve for the revision id and potentially
-    the navigation breadcrumbs the context to pass to parents and children of
-    of the revision.
-
-    Args:
-        rev_id: the revision's sha1 id
-        context: the current navigation context
-
-    Returns:
-        The context for parents, children and the url of the direct child as a
-        tuple in that order.
-    """
-    context_for_parents = None
-    context_for_children = None
-    url_direct_child = None
-
-    if not context:
-        return (rev_id, None, None)
-
-    path_list = _get_path_list(context)
-    context_for_parents = '%s/%s' % (context, rev_id)
-    prev_for_children = path_list[:-1]
-    if len(prev_for_children) > 0:
-        context_for_children = '/'.join(prev_for_children)
-    child_id = path_list[-1]
-    # This commit is not the first commit in the path
-    if context_for_children:
-        url_direct_child = reverse('api-revision-context',
-                                   url_args={'sha1_git': child_id,
-                                             'context': context_for_children})
-    # This commit is the first commit in the path
-    else:
-        url_direct_child = reverse('api-revision',
-                                   url_args={'sha1_git': child_id})
-
-    return (context_for_parents, context_for_children, url_direct_child)
-
-
-def _make_child_url(rev_children, context):
-    """Helper for enrich_revision: retrieve the list of urls corresponding
-    to the children of the current revision according to the navigation
-    breadcrumbs.
-
-    Args:
-        rev_children: a list of revision id
-        context: the '/'-separated navigation breadcrumbs
-
-    Returns:
-        the list of the children urls according to the context
-    """
-    children = []
-    for child in rev_children:
-        if context and child != _get_path_list(context)[-1]:
-            children.append(reverse('api-revision',
-                                    url_args={'sha1_git': child}))
-        elif not context:
-            children.append(reverse('api-revision',
-                                    url_args={'sha1_git': child}))
-    return children
-
-
-def enrich_revision(revision, context=None):
+def enrich_revision(revision):
     """Enrich revision with links where it makes sense (directory, parents).
     Keep track of the navigation breadcrumbs if they are specified.
 
     Args:
         revision: the revision as a dict
-        context: the navigation breadcrumbs as a /-separated string of revision
-        sha1_git
     """
 
-    ctx_parents, ctx_children, url_direct_child = _get_revision_contexts(
-        revision['id'], context)
-
     revision['url'] = reverse('api-revision',
                               url_args={'sha1_git': revision['id']})
     revision['history_url'] = reverse('api-revision-log',
                                       url_args={'sha1_git': revision['id']})
-    if context:
-        revision['history_context_url'] = reverse(
-            'api-revision-log', url_args={'sha1_git': revision['id'],
-                                          'prev_sha1s': context})
 
     if 'author' in revision:
         author = revision['author']
         revision['author_url'] = reverse('api-person',
                                          url_args={'person_id': author['id']})
 
     if 'committer' in revision:
         committer = revision['committer']
         revision['committer_url'] = \
             reverse('api-person', url_args={'person_id': committer['id']})
 
     if 'directory' in revision:
         revision['directory_url'] = \
             reverse('api-directory',
                     url_args={'sha1_git': revision['directory']})
 
     if 'parents' in revision:
         parents = []
         for parent in revision['parents']:
             parents.append({
                 'id': parent,
                 'url': reverse('api-revision', url_args={'sha1_git': parent})
             })
 
         revision['parents'] = parents
 
     if 'children' in revision:
-        children = _make_child_url(revision['children'], context)
-        if url_direct_child:
-            children.append(url_direct_child)
+        children = []
+        for child in revision['children']:
+            children.append(reverse('api-revision',
+                                    url_args={'sha1_git': child}))
         revision['children_urls'] = children
-    else:
-        if url_direct_child:
-            revision['children_urls'] = [url_direct_child]
 
     if 'message_decoding_failed' in revision:
         revision['message_url'] = \
             reverse('api-revision-raw-message',
                     url_args={'sha1_git': revision['id']})
 
     return revision
diff --git a/swh/web/api/views/revision.py b/swh/web/api/views/revision.py
index c64a80bd6..1083ce56c 100644
--- a/swh/web/api/views/revision.py
+++ b/swh/web/api/views/revision.py
@@ -1,501 +1,485 @@
 # Copyright (C) 2015-2018  The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU Affero General Public License version 3, or any later version
 # See top-level LICENSE file for more information
 
 from django.http import HttpResponse
 
 from swh.web.common import service
 from swh.web.common.utils import reverse
 from swh.web.common.utils import parse_timestamp
 from swh.web.api import utils
 from swh.web.api.apidoc import api_doc
 from swh.web.api.apiurls import api_route
 from swh.web.api.views.utils import api_lookup
 
 
 def _revision_directory_by(revision, path, request_path,
                            limit=100, with_data=False):
     """
     Compute the revision matching criterion's directory or content data.
 
     Args:
         revision: dictionary of criterions representing a revision to lookup
         path: directory's path to lookup
         request_path: request path which holds the original context to
         limit: optional query parameter to limit the revisions log
         (default to 100). For now, note that this limit could impede the
         transitivity conclusion about sha1_git not being an ancestor of
         with_data: indicate to retrieve the content's raw data if path resolves
         to a content.
 
     """
     def enrich_directory_local(dir, context_url=request_path):
         return utils.enrich_directory(dir, context_url)
 
     rev_id, result = service.lookup_directory_through_revision(
         revision, path, limit=limit, with_data=with_data)
 
     content = result['content']
     if result['type'] == 'dir':  # dir_entries
         result['content'] = list(map(enrich_directory_local, content))
     else:  # content
         result['content'] = utils.enrich_content(content)
 
     return result
 
 
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/log/',
            'api-revision-origin-log')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)/log/',
            'api-revision-origin-log')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/ts/(?P<ts>.+)/log/',
            'api-revision-origin-log')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)'
            r'/ts/(?P<ts>.+)/log/',
            'api-revision-origin-log')
 @api_doc('/revision/origin/log/')
 def api_revision_log_by(request, origin_id,
                         branch_name='HEAD',
                         ts=None):
     """
     .. http:get:: /api/1/revision/origin/(origin_id)[/branch/(branch_name)][/ts/(timestamp)]/log
 
         Show the commit log for a revision, searching for it based on software origin,
         branch name, and/or visit timestamp.
 
         This endpoint behaves like :http:get:`/api/1/revision/(sha1_git)[/prev/(prev_sha1s)]/log/`,
         but operates on the revision that has been found at a given software origin,
         close to a given point in time, pointed by a given branch.
 
         :param int origin_id: a software origin identifier
         :param string branch_name: optional parameter specifying a fully-qualified branch name
             associated to the software origin, e.g., "refs/heads/master". Defaults to the HEAD branch.
         :param string timestamp: optional parameter specifying a timestamp close to which the revision
             pointed by the given branch should be looked up. The timestamp can be expressed either
             as an ISO date or as a Unix one (in UTC). Defaults to now.
 
         :reqheader Accept: the requested response content type,
             either ``application/json`` (default) or ``application/yaml``
         :resheader Content-Type: this depends on :http:header:`Accept` header of request
 
         :>jsonarr object author: information about the author of the revision
         :>jsonarr string author_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the author of the revision
         :>jsonarr object committer: information about the committer of the revision
         :>jsonarr string committer_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the committer of the revision
         :>jsonarr string committer_date: ISO representation of the commit date (in UTC)
         :>jsonarr string date: ISO representation of the revision date (in UTC)
         :>jsonarr string directory: the unique identifier that revision points to
         :>jsonarr string directory_url: link to :http:get:`/api/1/directory/(sha1_git)/[(path)/]`
             to get information about the directory associated to the revision
         :>jsonarr string id: the revision unique identifier
         :>jsonarr boolean merge: whether or not the revision corresponds to a merge commit
         :>jsonarr string message: the message associated to the revision
         :>jsonarr array parents: the parents of the revision, i.e. the previous revisions
             that head directly to it, each entry of that array contains an unique parent
             revision identifier but also a link to :http:get:`/api/1/revision/(sha1_git)/`
             to get more information about it
         :>jsonarr string type: the type of the revision
 
         **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options`
 
         :statuscode 200: no error
         :statuscode 404: no revision matching the given criteria could be found in the archive
 
         **Example:**
 
         .. parsed-literal::
 
             :swh_web_api:`revision/origin/723566/ts/2016-01-17T00:00:00+00:00/log/`
     """ # noqa
     result = {}
     per_page = int(request.query_params.get('per_page', '10'))
 
     def lookup_revision_log_by_with_limit(o_id, br, ts, limit=per_page+1):
         return service.lookup_revision_log_by(o_id, br, ts, limit)
 
     error_msg = 'No revision matching origin %s ' % origin_id
     error_msg += ', branch name %s' % branch_name
     error_msg += (' and time stamp %s.' % ts) if ts else '.'
 
     rev_get = api_lookup(
         lookup_revision_log_by_with_limit, origin_id, branch_name, ts,
         notfound_msg=error_msg,
         enrich_fn=utils.enrich_revision)
 
     nb_rev = len(rev_get)
     if nb_rev == per_page+1:
         revisions = rev_get[:-1]
         last_sha1_git = rev_get[-1]['id']
 
         params = {k: v for k, v in {'origin_id': origin_id,
                                     'branch_name': branch_name,
                                     'ts': ts,
                                     }.items() if v is not None}
 
         query_params = {}
         query_params['sha1_git'] = last_sha1_git
 
         if request.query_params.get('per_page'):
             query_params['per_page'] = per_page
 
         result['headers'] = {
             'link-next': reverse('api-revision-origin-log', url_args=params,
                                  query_params=query_params)
         }
 
     else:
         revisions = rev_get
 
     result.update({'results': revisions})
 
     return result
 
 
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)/directory/',
            'api-revision-origin-directory')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)/directory/(?P<path>.+)/',
            'api-revision-origin-directory')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/directory/',
            'api-revision-origin-directory')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/ts/(?P<ts>.+)/directory/',
            'api-revision-origin-directory')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/directory/(?P<path>.+)/',
            'api-revision-origin-directory')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/ts/(?P<ts>.+)'
            r'/directory/(?P<path>.+)/',
            'api-revision-origin-directory')
 @api_doc('/revision/origin/directory/', tags=['hidden'])
 def api_directory_through_revision_origin(request, origin_id,
                                           branch_name="refs/heads/master",
                                           ts=None,
                                           path=None,
                                           with_data=False):
     """
     Display directory or content information through a revision identified
     by origin/branch/timestamp.
     """
     if ts:
         ts = parse_timestamp(ts)
 
     return _revision_directory_by({'origin_id': origin_id,
                                    'branch_name': branch_name,
                                    'ts': ts
                                    },
                                   path, request.path,
                                   with_data=with_data)
 
 
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)/',
            'api-revision-origin')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/',
            'api-revision-origin')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)'
            r'/branch/(?P<branch_name>.+)/ts/(?P<ts>.+)/',
            'api-revision-origin')
 @api_route(r'/revision/origin/(?P<origin_id>[0-9]+)/ts/(?P<ts>.+)/',
            'api-revision-origin')
 @api_doc('/revision/origin/')
 def api_revision_with_origin(request, origin_id,
                              branch_name='HEAD',
                              ts=None):
     """
     .. http:get:: /api/1/revision/origin/(origin_id)/[branch/(branch_name)/][ts/(timestamp)/]
 
         Get information about a revision, searching for it based on software origin,
         branch name, and/or visit timestamp.
 
         This endpoint behaves like :http:get:`/api/1/revision/(sha1_git)/`,
         but operates on the revision that has been found at a given software origin,
         close to a given point in time, pointed by a given branch.
 
         :param int origin_id: a software origin identifier
         :param string branch_name: optional parameter specifying a fully-qualified branch name
             associated to the software origin, e.g., "refs/heads/master". Defaults to the HEAD branch.
         :param string timestamp: optional parameter specifying a timestamp close to which the revision
             pointed by the given branch should be looked up. The timestamp can be expressed either
             as an ISO date or as a Unix one (in UTC). Defaults to now.
 
         :reqheader Accept: the requested response content type,
             either ``application/json`` (default) or ``application/yaml``
         :resheader Content-Type: this depends on :http:header:`Accept` header of request
 
         :>json object author: information about the author of the revision
         :>json string author_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the author of the revision
         :>json object committer: information about the committer of the revision
         :>json string committer_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the committer of the revision
         :>json string committer_date: ISO representation of the commit date (in UTC)
         :>json string date: ISO representation of the revision date (in UTC)
         :>json string directory: the unique identifier that revision points to
         :>json string directory_url: link to :http:get:`/api/1/directory/(sha1_git)/[(path)/]`
             to get information about the directory associated to the revision
         :>json string id: the revision unique identifier
         :>json boolean merge: whether or not the revision corresponds to a merge commit
         :>json string message: the message associated to the revision
         :>json array parents: the parents of the revision, i.e. the previous revisions
             that head directly to it, each entry of that array contains an unique parent
             revision identifier but also a link to :http:get:`/api/1/revision/(sha1_git)/`
             to get more information about it
         :>json string type: the type of the revision
 
         **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options`
 
         :statuscode 200: no error
         :statuscode 404: no revision matching the given criteria could be found in the archive
 
         **Example:**
 
         .. parsed-literal::
 
             :swh_web_api:`revision/origin/13706355/branch/refs/heads/2.7/`
     """ # noqa
     return api_lookup(
         service.lookup_revision_by, origin_id, branch_name, ts,
         notfound_msg=('Revision with (origin_id: {}, branch_name: {}'
                       ', ts: {}) not found.'.format(origin_id,
                                                     branch_name, ts)),
         enrich_fn=utils.enrich_revision)
 
 
-@api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)/prev/(?P<context>[0-9a-f/]+)/',
-           'api-revision-context')
-@api_doc('/revision/prev/', tags=['hidden'])
-def api_revision_with_context(request, sha1_git, context):
-    """
-    Return information about revision with id sha1_git.
-    """
-    def _enrich_revision(revision, context=context):
-        return utils.enrich_revision(revision, context)
-
-    return api_lookup(
-        service.lookup_revision, sha1_git,
-        notfound_msg='Revision with sha1_git %s not found.' % sha1_git,
-        enrich_fn=_enrich_revision)
-
-
 @api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)/', 'api-revision')
 @api_doc('/revision/')
 def api_revision(request, sha1_git):
     """
     .. http:get:: /api/1/revision/(sha1_git)/
 
         Get information about a revision in the archive.
         Revisions are identified by **sha1** checksums, compatible with Git commit identifiers.
         See :func:`swh.model.identifiers.revision_identifier` in our data model module for details
         about how they are computed.
 
         :param string sha1_git: hexadecimal representation of the revision **sha1_git** identifier
 
         :reqheader Accept: the requested response content type,
             either ``application/json`` (default) or ``application/yaml``
         :resheader Content-Type: this depends on :http:header:`Accept` header of request
 
         :>json object author: information about the author of the revision
         :>json string author_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the author of the revision
         :>json object committer: information about the committer of the revision
         :>json string committer_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the committer of the revision
         :>json string committer_date: ISO representation of the commit date (in UTC)
         :>json string date: ISO representation of the revision date (in UTC)
         :>json string directory: the unique identifier that revision points to
         :>json string directory_url: link to :http:get:`/api/1/directory/(sha1_git)/[(path)/]`
             to get information about the directory associated to the revision
         :>json string id: the revision unique identifier
         :>json boolean merge: whether or not the revision corresponds to a merge commit
         :>json string message: the message associated to the revision
         :>json array parents: the parents of the revision, i.e. the previous revisions
             that head directly to it, each entry of that array contains an unique parent
             revision identifier but also a link to :http:get:`/api/1/revision/(sha1_git)/`
             to get more information about it
         :>json string type: the type of the revision
 
         **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options`
 
         :statuscode 200: no error
         :statuscode 400: an invalid **sha1_git** value has been provided
         :statuscode 404: requested revision can not be found in the archive
 
         **Example:**
 
         .. parsed-literal::
 
             :swh_web_api:`revision/aafb16d69fd30ff58afdd69036a26047f3aebdc6/`
     """ # noqa
     return api_lookup(
         service.lookup_revision, sha1_git,
         notfound_msg='Revision with sha1_git {} not found.'.format(sha1_git),
         enrich_fn=utils.enrich_revision)
 
 
 @api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)/raw/',
            'api-revision-raw-message')
 @api_doc('/revision/raw/', tags=['hidden'], handle_response=True)
 def api_revision_raw_message(request, sha1_git):
     """Return the raw data of the message of revision identified by sha1_git
     """
     raw = service.lookup_revision_message(sha1_git)
     response = HttpResponse(raw['message'],
                             content_type='application/octet-stream')
     response['Content-disposition'] = \
         'attachment;filename=rev_%s_raw' % sha1_git
     return response
 
 
 @api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)/directory/',
            'api-revision-directory')
 @api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)/directory/(?P<dir_path>.+)/',
            'api-revision-directory')
 @api_doc('/revision/directory/')
 def api_revision_directory(request, sha1_git,
                            dir_path=None,
                            with_data=False):
     """
     .. http:get:: /api/1/revision/(sha1_git)/directory/[(path)/]
 
         Get information about directory (entry) objects associated to revisions.
         Each revision is associated to a single "root" directory.
         This endpoint behaves like :http:get:`/api/1/directory/(sha1_git)/[(path)/]`,
         but operates on the root directory associated to a given revision.
 
         :param string sha1_git: hexadecimal representation of the revision **sha1_git** identifier
         :param string path: optional parameter to get information about the directory entry
             pointed by that relative path
 
         :reqheader Accept: the requested response content type,
             either ``application/json`` (default) or ``application/yaml``
         :resheader Content-Type: this depends on :http:header:`Accept` header of request
 
         :>json array content: directory entries as returned by :http:get:`/api/1/directory/(sha1_git)/[(path)/]`
         :>json string path: path of directory from the revision root one
         :>json string revision: the unique revision identifier
         :>json string type: the type of the directory
 
         **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options`
 
         :statuscode 200: no error
         :statuscode 400: an invalid **sha1_git** value has been provided
         :statuscode 404: requested revision can not be found in the archive
 
         **Example:**
 
         .. parsed-literal::
 
             :swh_web_api:`revision/f1b94134a4b879bc55c3dacdb496690c8ebdc03f/directory/`
     """ # noqa
     return _revision_directory_by({'sha1_git': sha1_git},
                                   dir_path, request.path,
                                   with_data=with_data)
 
 
 @api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)/log/', 'api-revision-log')
 @api_route(r'/revision/(?P<sha1_git>[0-9a-f]+)'
            r'/prev/(?P<prev_sha1s>[0-9a-f/]+)/log/',
            'api-revision-log')
 @api_doc('/revision/log/')
 def api_revision_log(request, sha1_git, prev_sha1s=None):
     """
     .. http:get:: /api/1/revision/(sha1_git)[/prev/(prev_sha1s)]/log/
 
         Get a list of all revisions heading to a given one, in other words show the commit log.
 
         :param string sha1_git: hexadecimal representation of the revision **sha1_git** identifier
         :param string prev_sha1s: optional parameter representing the navigation breadcrumbs
             (descendant revisions previously visited). If multiple values, use / as delimiter.
             If provided, revisions information will be added at the beginning of the returned list.
         :query int per_page: number of elements in the returned list, for pagination purpose
 
         :reqheader Accept: the requested response content type,
             either ``application/json`` (default) or ``application/yaml``
         :resheader Content-Type: this depends on :http:header:`Accept` header of request
         :resheader Link: indicates that a subsequent result page is available and contains
             the url pointing to it
 
         :>jsonarr object author: information about the author of the revision
         :>jsonarr string author_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the author of the revision
         :>jsonarr object committer: information about the committer of the revision
         :>jsonarr string committer_url: link to :http:get:`/api/1/person/(person_id)/` to get
             information about the committer of the revision
         :>jsonarr string committer_date: ISO representation of the commit date (in UTC)
         :>jsonarr string date: ISO representation of the revision date (in UTC)
         :>jsonarr string directory: the unique identifier that revision points to
         :>jsonarr string directory_url: link to :http:get:`/api/1/directory/(sha1_git)/[(path)/]`
             to get information about the directory associated to the revision
         :>jsonarr string id: the revision unique identifier
         :>jsonarr boolean merge: whether or not the revision corresponds to a merge commit
         :>jsonarr string message: the message associated to the revision
         :>jsonarr array parents: the parents of the revision, i.e. the previous revisions
             that head directly to it, each entry of that array contains an unique parent
             revision identifier but also a link to :http:get:`/api/1/revision/(sha1_git)/`
             to get more information about it
         :>jsonarr string type: the type of the revision
 
         **Allowed HTTP Methods:** :http:method:`get`, :http:method:`head`, :http:method:`options`
 
         :statuscode 200: no error
         :statuscode 400: an invalid **sha1_git** value has been provided
         :statuscode 404: requested revision can not be found in the archive
 
         **Example:**
 
         .. parsed-literal::
 
             :swh_web_api:`revision/e1a315fa3fa734e2a6154ed7b5b9ae0eb8987aad/log/`
     """ # noqa
     result = {}
     per_page = int(request.query_params.get('per_page', '10'))
 
     def lookup_revision_log_with_limit(s, limit=per_page+1):
         return service.lookup_revision_log(s, limit)
 
     error_msg = 'Revision with sha1_git %s not found.' % sha1_git
     rev_get = api_lookup(lookup_revision_log_with_limit, sha1_git,
                          notfound_msg=error_msg,
                          enrich_fn=utils.enrich_revision)
 
     nb_rev = len(rev_get)
     if nb_rev == per_page+1:
         rev_backward = rev_get[:-1]
         new_last_sha1 = rev_get[-1]['id']
         query_params = {}
 
         if request.query_params.get('per_page'):
             query_params['per_page'] = per_page
 
         result['headers'] = {
             'link-next': reverse('api-revision-log',
                                  url_args={'sha1_git': new_last_sha1},
                                  query_params=query_params)
         }
 
     else:
         rev_backward = rev_get
 
     if not prev_sha1s:  # no nav breadcrumbs, so we're done
         revisions = rev_backward
 
     else:
         rev_forward_ids = prev_sha1s.split('/')
         rev_forward = api_lookup(
             service.lookup_revision_multiple, rev_forward_ids,
             notfound_msg=error_msg,
             enrich_fn=utils.enrich_revision)
         revisions = rev_forward + rev_backward
 
     result.update({
         'results': revisions
     })
     return result
diff --git a/swh/web/tests/api/test_utils.py b/swh/web/tests/api/test_utils.py
index 5e5725702..de0855e82 100644
--- a/swh/web/tests/api/test_utils.py
+++ b/swh/web/tests/api/test_utils.py
@@ -1,688 +1,599 @@
 # Copyright (C) 2015-2018  The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU Affero General Public License version 3, or any later version
 # See top-level LICENSE file for more information
 
 from unittest.mock import patch, call
 
 from swh.web.api import utils
 from swh.web.tests.testcase import WebTestCase
 
 
 class UtilsTestCase(WebTestCase):
     def setUp(self):
         self.maxDiff = None
         self.url_map = [dict(rule='/other/<slug>',
                              methods=set(['GET', 'POST', 'HEAD']),
                              endpoint='foo'),
                         dict(rule='/some/old/url/<slug>',
                              methods=set(['GET', 'POST']),
                              endpoint='blablafn'),
                         dict(rule='/other/old/url/<int:id>',
                              methods=set(['GET', 'HEAD']),
                              endpoint='bar'),
                         dict(rule='/other',
                              methods=set([]),
                              endpoint=None),
                         dict(rule='/other2',
                              methods=set([]),
                              endpoint=None)]
         self.sample_content_hashes = {
             'blake2s256': ('791e07fcea240ade6dccd0a9309141673'
                            'c31242cae9c237cf3855e151abc78e9'),
             'sha1': 'dc2830a9e72f23c1dfebef4413003221baa5fb62',
             'sha1_git': 'fe95a46679d128ff167b7c55df5d02356c5a1ae1',
             'sha256': ('b5c7fe0536f44ef60c8780b6065d30bca74a5cd06'
                        'd78a4a71ba1ad064770f0c9')
         }
 
     def test_filter_field_keys_dict_unknown_keys(self):
         # when
         actual_res = utils.filter_field_keys(
             {'directory': 1, 'file': 2, 'link': 3},
             {'directory1', 'file2'})
 
         # then
         self.assertEqual(actual_res, {})
 
     def test_filter_field_keys_dict(self):
         # when
         actual_res = utils.filter_field_keys(
             {'directory': 1, 'file': 2, 'link': 3},
             {'directory', 'link'})
 
         # then
         self.assertEqual(actual_res, {'directory': 1, 'link': 3})
 
     def test_filter_field_keys_list_unknown_keys(self):
         # when
         actual_res = utils.filter_field_keys(
             [{'directory': 1, 'file': 2, 'link': 3},
              {'1': 1, '2': 2, 'link': 3}],
             {'d'})
 
         # then
         self.assertEqual(actual_res, [{}, {}])
 
     def test_filter_field_keys_map(self):
         # when
         actual_res = utils.filter_field_keys(
             map(lambda x: {'i': x['i']+1, 'j': x['j']},
                 [{'i': 1, 'j': None},
                  {'i': 2, 'j': None},
                  {'i': 3, 'j': None}]),
             {'i'})
 
         # then
         self.assertEqual(list(actual_res), [{'i': 2}, {'i': 3}, {'i': 4}])
 
     def test_filter_field_keys_list(self):
         # when
         actual_res = utils.filter_field_keys(
             [{'directory': 1, 'file': 2, 'link': 3},
              {'dir': 1, 'fil': 2, 'lin': 3}],
             {'directory', 'dir'})
 
         # then
         self.assertEqual(actual_res, [{'directory': 1}, {'dir': 1}])
 
     def test_filter_field_keys_other(self):
         # given
         input_set = {1, 2}
 
         # when
         actual_res = utils.filter_field_keys(input_set, {'a', '1'})
 
         # then
         self.assertEqual(actual_res, input_set)
 
     def test_person_to_string(self):
         self.assertEqual(utils.person_to_string(dict(name='raboof',
                                                      email='foo@bar')),
                          'raboof <foo@bar>')
 
     def test_enrich_release_0(self):
         # when
         actual_release = utils.enrich_release({})
 
         # then
         self.assertEqual(actual_release, {})
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_release_1(self, mock_django_reverse):
         # given
 
         def reverse_test_context(view_name, url_args):
             if view_name == 'api-content':
                 id = url_args['q']
                 return '/api/1/content/%s/' % id
             elif view_name == 'api-person':
                 id = url_args['person_id']
                 return '/api/1/person/%s/' % id
             else:
                 raise ValueError(
                     'This should not happened so fail if it does.')
 
         mock_django_reverse.side_effect = reverse_test_context
 
         # when
         actual_release = utils.enrich_release({
             'target': '123',
             'target_type': 'content',
             'author': {
                 'id': 100,
                 'name': 'author release name',
                 'email': 'author@email',
             },
         })
 
         # then
         self.assertEqual(actual_release, {
             'target': '123',
             'target_type': 'content',
             'target_url': '/api/1/content/sha1_git:123/',
             'author_url': '/api/1/person/100/',
             'author': {
                 'id': 100,
                 'name': 'author release name',
                 'email': 'author@email',
             },
         })
 
         mock_django_reverse.assert_has_calls([
                 call('api-content', url_args={'q': 'sha1_git:123'}),
                 call('api-person', url_args={'person_id': 100})
         ])
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_release_2(self, mock_django_reverse):
         # given
         mock_django_reverse.return_value = '/api/1/dir/23/'
 
         # when
         actual_release = utils.enrich_release({'target': '23',
                                                'target_type': 'directory'})
 
         # then
         self.assertEqual(actual_release, {
             'target': '23',
             'target_type': 'directory',
             'target_url': '/api/1/dir/23/'
         })
 
         mock_django_reverse.assert_called_once_with('api-directory',
                                                     url_args={'sha1_git': '23'}) # noqa
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_release_3(self, mock_django_reverse):
         # given
         mock_django_reverse.return_value = '/api/1/rev/3/'
 
         # when
         actual_release = utils.enrich_release({'target': '3',
                                                'target_type': 'revision'})
 
         # then
         self.assertEqual(actual_release, {
             'target': '3',
             'target_type': 'revision',
             'target_url': '/api/1/rev/3/'
         })
 
         mock_django_reverse.assert_called_once_with('api-revision',
                                                     url_args={'sha1_git': '3'})
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_release_4(self, mock_django_reverse):
         # given
         mock_django_reverse.return_value = '/api/1/rev/4/'
 
         # when
         actual_release = utils.enrich_release({'target': '4',
                                                'target_type': 'release'})
 
         # then
         self.assertEqual(actual_release, {
             'target': '4',
             'target_type': 'release',
             'target_url': '/api/1/rev/4/'
         })
 
         mock_django_reverse.assert_called_once_with('api-release',
                                                     url_args={'sha1_git': '4'})
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_directory_no_type(self, mock_django_reverse):
         # when/then
         self.assertEqual(utils.enrich_directory({'id': 'dir-id'}),
                          {'id': 'dir-id'})
 
         # given
         mock_django_reverse.return_value = '/api/content/sha1_git:123/'
 
         # when
         actual_directory = utils.enrich_directory({
             'id': 'dir-id',
             'type': 'file',
             'target': '123',
         })
 
         # then
         self.assertEqual(actual_directory, {
             'id': 'dir-id',
             'type': 'file',
             'target': '123',
             'target_url': '/api/content/sha1_git:123/',
         })
 
         mock_django_reverse.assert_called_once_with(
             'api-content', url_args={'q': 'sha1_git:123'})
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_directory_with_context_and_type_file(
         self, mock_django_reverse,
     ):
         # given
         mock_django_reverse.return_value = '/api/content/sha1_git:123/'
 
         # when
         actual_directory = utils.enrich_directory({
             'id': 'dir-id',
             'type': 'file',
             'name': 'hy',
             'target': '789',
         }, context_url='/api/revision/revsha1/directory/prefix/path/')
 
         # then
         self.assertEqual(actual_directory, {
             'id': 'dir-id',
             'type': 'file',
             'name': 'hy',
             'target': '789',
             'target_url': '/api/content/sha1_git:123/',
             'file_url': '/api/revision/revsha1/directory'
                         '/prefix/path/hy/'
         })
 
         mock_django_reverse.assert_called_once_with(
             'api-content', url_args={'q': 'sha1_git:789'})
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_directory_with_context_and_type_dir(
         self, mock_django_reverse,
     ):
         # given
         mock_django_reverse.return_value = '/api/directory/456/'
 
         # when
         actual_directory = utils.enrich_directory({
             'id': 'dir-id',
             'type': 'dir',
             'name': 'emacs-42',
             'target_type': 'file',
             'target': '456',
         }, context_url='/api/revision/origin/2/directory/some/prefix/path/')
 
         # then
         self.assertEqual(actual_directory, {
             'id': 'dir-id',
             'type': 'dir',
             'target_type': 'file',
             'name': 'emacs-42',
             'target': '456',
             'target_url': '/api/directory/456/',
             'dir_url': '/api/revision/origin/2/directory'
             '/some/prefix/path/emacs-42/'
         })
 
         mock_django_reverse.assert_called_once_with('api-directory',
                                                     url_args={'sha1_git': '456'}) # noqa
 
     def test_enrich_content_without_hashes(self):
         # when/then
         self.assertEqual(utils.enrich_content({'id': '123'}),
                          {'id': '123'})
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_content_with_hashes(self, mock_django_reverse):
 
         for algo, hash in self.sample_content_hashes.items():
 
             query_string = '%s:%s' % (algo, hash)
 
             # given
             mock_django_reverse.side_effect = [
                 '/api/content/%s/raw/' % query_string,
                 '/api/filetype/%s/' % query_string,
                 '/api/language/%s/' % query_string,
                 '/api/license/%s/' % query_string
                 ]
 
             # when
             enriched_content = utils.enrich_content(
                 {
                     algo: hash,
                 },
                 query_string=query_string
             )
 
             # then
             self.assertEqual(
                 enriched_content,
                 {
                     algo: hash,
                     'data_url': '/api/content/%s/raw/' % query_string,
                     'filetype_url': '/api/filetype/%s/' % query_string,
                     'language_url': '/api/language/%s/' % query_string,
                     'license_url': '/api/license/%s/' % query_string,
                 }
             )
 
             mock_django_reverse.assert_has_calls([
                 call('api-content-raw', url_args={'q': query_string}),
                 call('api-content-filetype', url_args={'q': query_string}),
                 call('api-content-language', url_args={'q': query_string}),
                 call('api-content-license', url_args={'q': query_string}),
             ])
 
             mock_django_reverse.reset()
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_content_with_hashes_and_top_level_url(self,
                                                           mock_django_reverse):
 
         for algo, hash in self.sample_content_hashes.items():
 
             query_string = '%s:%s' % (algo, hash)
 
             # given
             mock_django_reverse.side_effect = [
                 '/api/content/%s/' % query_string,
                 '/api/content/%s/raw/' % query_string,
                 '/api/filetype/%s/' % query_string,
                 '/api/language/%s/' % query_string,
                 '/api/license/%s/' % query_string,
                 ]
 
             # when
             enriched_content = utils.enrich_content(
                 {
                     algo: hash
                 },
                 top_url=True,
                 query_string=query_string
             )
 
             # then
             self.assertEqual(
                 enriched_content,
                 {
                     algo: hash,
                     'content_url': '/api/content/%s/' % query_string,
                     'data_url': '/api/content/%s/raw/' % query_string,
                     'filetype_url': '/api/filetype/%s/' % query_string,
                     'language_url': '/api/language/%s/' % query_string,
                     'license_url': '/api/license/%s/' % query_string,
                 }
             )
 
             mock_django_reverse.assert_has_calls([
                 call('api-content', url_args={'q': query_string}),
                 call('api-content-raw', url_args={'q': query_string}),
                 call('api-content-filetype', url_args={'q': query_string}),
                 call('api-content-language', url_args={'q': query_string}),
                 call('api-content-license', url_args={'q': query_string}),
             ])
 
             mock_django_reverse.reset()
 
     def _reverse_context_test(self, view_name, url_args):
         if view_name == 'api-revision':
             return '/api/revision/%s/' % url_args['sha1_git']
         elif view_name == 'api-revision-context':
             return '/api/revision/%s/prev/%s/' % (url_args['sha1_git'], url_args['context'])  # noqa
         elif view_name == 'api-revision-log':
             if 'prev_sha1s' in url_args:
                 return '/api/revision/%s/prev/%s/log/' % (url_args['sha1_git'], url_args['prev_sha1s'])  # noqa
             else:
                 return '/api/revision/%s/log/' % url_args['sha1_git']
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_revision_without_children_or_parent(
         self, mock_django_reverse,
     ):
         # given
         def reverse_test(view_name, url_args):
             if view_name == 'api-revision':
                 return '/api/revision/' + url_args['sha1_git'] + '/'
             elif view_name == 'api-revision-log':
                 return '/api/revision/' + url_args['sha1_git'] + '/log/'
             elif view_name == 'api-directory':
                 return '/api/directory/' + url_args['sha1_git'] + '/'
             elif view_name == 'api-person':
                 return '/api/person/' + url_args['person_id'] + '/'
 
         mock_django_reverse.side_effect = reverse_test
 
         # when
         actual_revision = utils.enrich_revision({
             'id': 'rev-id',
             'directory': '123',
             'author': {'id': '1'},
             'committer': {'id': '2'},
         })
 
         expected_revision = {
             'id': 'rev-id',
             'directory': '123',
             'url': '/api/revision/rev-id/',
             'history_url': '/api/revision/rev-id/log/',
             'directory_url': '/api/directory/123/',
             'author': {'id': '1'},
             'author_url': '/api/person/1/',
             'committer': {'id': '2'},
             'committer_url': '/api/person/2/'
         }
 
         # then
         self.assertEqual(actual_revision, expected_revision)
 
         mock_django_reverse.assert_has_calls(
             [call('api-revision', url_args={'sha1_git': 'rev-id'}),
              call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
              call('api-person', url_args={'person_id': '1'}),
              call('api-person', url_args={'person_id': '2'}),
              call('api-directory', url_args={'sha1_git': '123'})])
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_revision_with_children_and_parent_no_dir(
         self, mock_django_reverse,
     ):
         # given
         mock_django_reverse.side_effect = self._reverse_context_test
 
         # when
         actual_revision = utils.enrich_revision({
             'id': 'rev-id',
             'parents': ['123'],
             'children': ['456'],
-        }, context='prev-rev')
+        })
 
         expected_revision = {
             'id': 'rev-id',
             'url': '/api/revision/rev-id/',
             'history_url': '/api/revision/rev-id/log/',
-            'history_context_url': '/api/revision/rev-id/prev/prev-rev/log/',
             'parents': [{'id': '123', 'url': '/api/revision/123/'}],
             'children': ['456'],
-            'children_urls': ['/api/revision/456/',
-                              '/api/revision/prev-rev/'],
+            'children_urls': ['/api/revision/456/'],
         }
 
         # then
         self.assertEqual(actual_revision, expected_revision)
 
         mock_django_reverse.assert_has_calls(
-            [call('api-revision', url_args={'sha1_git': 'prev-rev'}),
-             call('api-revision', url_args={'sha1_git': 'rev-id'}),
+            [call('api-revision', url_args={'sha1_git': 'rev-id'}),
              call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'sha1_git': 'rev-id',
-                                                'prev_sha1s': 'prev-rev'}),
              call('api-revision', url_args={'sha1_git': '123'}),
              call('api-revision', url_args={'sha1_git': '456'})])
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_revision_no_context(self, mock_django_reverse):
         # given
         mock_django_reverse.side_effect = self._reverse_context_test
 
         # when
         actual_revision = utils.enrich_revision({
             'id': 'rev-id',
             'parents': ['123'],
             'children': ['456'],
         })
 
         expected_revision = {
             'id': 'rev-id',
             'url': '/api/revision/rev-id/',
             'history_url': '/api/revision/rev-id/log/',
             'parents': [{'id': '123', 'url': '/api/revision/123/'}],
             'children': ['456'],
             'children_urls': ['/api/revision/456/']
         }
 
         # then
         self.assertEqual(actual_revision, expected_revision)
 
         mock_django_reverse.assert_has_calls(
             [call('api-revision', url_args={'sha1_git': 'rev-id'}),
              call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
              call('api-revision', url_args={'sha1_git': '123'}),
              call('api-revision', url_args={'sha1_git': '456'})])
 
-    @patch('swh.web.api.utils.reverse')
-    def test_enrich_revision_context_empty_prev_list(
-        self, mock_django_reverse,
-    ):
-        # given
-        mock_django_reverse.side_effect = self._reverse_context_test
-
-        # when
-        expected_revision = {
-            'id': 'rev-id',
-            'url': '/api/revision/rev-id/',
-            'history_url': '/api/revision/rev-id/log/',
-            'history_context_url': ('/api/revision/rev-id/'
-                                    'prev/prev-rev/log/'),
-            'parents': [{'id': '123', 'url': '/api/revision/123/'}],
-            'children': ['456'],
-            'children_urls': ['/api/revision/456/',
-                              '/api/revision/prev-rev/'],
-        }
-
-        actual_revision = utils.enrich_revision({
-            'id': 'rev-id',
-            'url': '/api/revision/rev-id/',
-            'parents': ['123'],
-            'children': ['456']}, context='prev-rev')
-
-        # then
-        self.assertEqual(actual_revision, expected_revision)
-        mock_django_reverse.assert_has_calls(
-            [call('api-revision', url_args={'sha1_git': 'prev-rev'}),
-             call('api-revision', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'sha1_git': 'rev-id',
-                                                'prev_sha1s': 'prev-rev'}),
-             call('api-revision', url_args={'sha1_git': '123'}),
-             call('api-revision', url_args={'sha1_git': '456'})])
-
-    @patch('swh.web.api.utils.reverse')
-    def test_enrich_revision_context_some_prev_list(self, mock_django_reverse):
-        # given
-        mock_django_reverse.side_effect = self._reverse_context_test
-
-        # when
-        expected_revision = {
-            'id': 'rev-id',
-            'url': '/api/revision/rev-id/',
-            'history_url': '/api/revision/rev-id/log/',
-            'history_context_url': ('/api/revision/rev-id/'
-                                    'prev/prev1-rev/prev0-rev/log/'),
-            'parents': [{'id': '123', 'url': '/api/revision/123/'}],
-            'children': ['456'],
-            'children_urls': ['/api/revision/456/',
-                              '/api/revision/prev0-rev/prev/prev1-rev/'],
-        }
-
-        actual_revision = utils.enrich_revision({
-            'id': 'rev-id',
-            'parents': ['123'],
-            'children': ['456']}, context='prev1-rev/prev0-rev')
-
-        # then
-        self.assertEqual(actual_revision, expected_revision)
-        mock_django_reverse.assert_has_calls(
-            [call('api-revision-context', url_args={'context': 'prev1-rev',
-                                                  'sha1_git': 'prev0-rev'}),
-             call('api-revision', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'prev_sha1s': 'prev1-rev/prev0-rev', # noqa
-                                              'sha1_git': 'rev-id'}),
-             call('api-revision', url_args={'sha1_git': '123'}),
-             call('api-revision', url_args={'sha1_git': '456'})])
-
     def _reverse_rev_message_test(self, view_name, url_args):
         if view_name == 'api-revision':
             return '/api/revision/%s/' % url_args['sha1_git']
         elif view_name == 'api-revision-log':
             if 'prev_sha1s' in url_args and url_args['prev_sha1s'] is not None:
                 return '/api/revision/%s/prev/%s/log/' % (url_args['sha1_git'], url_args['prev_sha1s'])  # noqa
             else:
                 return '/api/revision/%s/log/' % url_args['sha1_git']
         elif view_name == 'api-revision-raw-message':
             return '/api/revision/' + url_args['sha1_git'] + '/raw/'
         else:
             return '/api/revision/%s/prev/%s/' % (url_args['sha1_git'], url_args['context'])  # noqa
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_revision_with_no_message(self, mock_django_reverse):
         # given
         mock_django_reverse.side_effect = self._reverse_rev_message_test
 
         # when
         expected_revision = {
             'id': 'rev-id',
             'url': '/api/revision/rev-id/',
             'history_url': '/api/revision/rev-id/log/',
-            'history_context_url': ('/api/revision/rev-id/'
-                                    'prev/prev-rev/log/'),
             'message': None,
             'parents': [{'id': '123', 'url': '/api/revision/123/'}],
             'children': ['456'],
-            'children_urls': ['/api/revision/456/',
-                              '/api/revision/prev-rev/'],
+            'children_urls': ['/api/revision/456/'],
         }
 
         actual_revision = utils.enrich_revision({
             'id': 'rev-id',
             'message': None,
             'parents': ['123'],
             'children': ['456'],
-        }, context='prev-rev')
+        })
 
         # then
         self.assertEqual(actual_revision, expected_revision)
 
         mock_django_reverse.assert_has_calls(
-            [call('api-revision', url_args={'sha1_git': 'prev-rev'}),
-             call('api-revision', url_args={'sha1_git': 'rev-id'}),
+            [call('api-revision', url_args={'sha1_git': 'rev-id'}),
              call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'sha1_git': 'rev-id',
-                                                'prev_sha1s': 'prev-rev'}),
              call('api-revision', url_args={'sha1_git': '123'}),
              call('api-revision', url_args={'sha1_git': '456'})]
         )
 
     @patch('swh.web.api.utils.reverse')
     def test_enrich_revision_with_invalid_message(self, mock_django_reverse):
         # given
         mock_django_reverse.side_effect = self._reverse_rev_message_test
 
         # when
         actual_revision = utils.enrich_revision({
             'id': 'rev-id',
             'message': None,
             'message_decoding_failed': True,
             'parents': ['123'],
             'children': ['456'],
-        }, context='prev-rev')
+        })
 
         expected_revision = {
             'id': 'rev-id',
             'url': '/api/revision/rev-id/',
             'history_url': '/api/revision/rev-id/log/',
-            'history_context_url': ('/api/revision/rev-id/'
-                                    'prev/prev-rev/log/'),
             'message': None,
             'message_decoding_failed': True,
             'message_url': '/api/revision/rev-id/raw/',
             'parents': [{'id': '123', 'url': '/api/revision/123/'}],
             'children': ['456'],
-            'children_urls': ['/api/revision/456/',
-                              '/api/revision/prev-rev/'],
+            'children_urls': ['/api/revision/456/'],
         }
 
         # then
         self.assertEqual(actual_revision, expected_revision)
 
         mock_django_reverse.assert_has_calls(
-            [call('api-revision', url_args={'sha1_git': 'prev-rev'}),
-             call('api-revision', url_args={'sha1_git': 'rev-id'}),
+            [call('api-revision', url_args={'sha1_git': 'rev-id'}),
              call('api-revision-log', url_args={'sha1_git': 'rev-id'}),
-             call('api-revision-log', url_args={'sha1_git': 'rev-id',
-                                                'prev_sha1s': 'prev-rev'}),
              call('api-revision', url_args={'sha1_git': '123'}),
              call('api-revision', url_args={'sha1_git': '456'}),
              call('api-revision-raw-message', url_args={'sha1_git': 'rev-id'})]) # noqa
diff --git a/swh/web/tests/api/views/test_revision.py b/swh/web/tests/api/views/test_revision.py
index ed583251c..e4a7fa847 100644
--- a/swh/web/tests/api/views/test_revision.py
+++ b/swh/web/tests/api/views/test_revision.py
@@ -1,883 +1,847 @@
 # Copyright (C) 2015-2018  The Software Heritage developers
 # See the AUTHORS file at the top-level directory of this distribution
 # License: GNU Affero General Public License version 3, or any later version
 # See top-level LICENSE file for more information
 
 from rest_framework.test import APITestCase
 from unittest.mock import patch
 
 from swh.web.common.exc import NotFoundExc
 from swh.web.api.views.revision import (
     _revision_directory_by
 )
 
 from swh.web.tests.testcase import WebTestCase
 
 
 class RevisionApiTestCase(WebTestCase, APITestCase):
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision(self, mock_service):
         # given
         stub_revision = {
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': ['8734ef7e7c357ce2af928115c6c6a42b7e2a44e7'],
             'type': 'tar',
             'synthetic': True,
             'metadata': {
                 'original_artifact': [{
                     'archive_type': 'tar',
                     'name': 'webbase-5.7.0.tar.gz',
                     'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd',
                     'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1',
                     'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f'
                     '309d36484e7edf7bb912'
                 }]
             },
         }
         mock_service.lookup_revision.return_value = stub_revision
 
         expected_revision = {
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/',
             'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233e'
                            'ff7371d5/log/',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6'
                              'a42b7e2a44e6/',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': [{
                 'id': '8734ef7e7c357ce2af928115c6c6a42b7e2a44e7',
                  'url': '/api/1/revision/8734ef7e7c357ce2af928115c6c6a42b7e2a44e7/'  # noqa
             }],
             'type': 'tar',
             'synthetic': True,
             'metadata': {
                 'original_artifact': [{
                     'archive_type': 'tar',
                     'name': 'webbase-5.7.0.tar.gz',
                     'sha1': '147f73f369733d088b7a6fa9c4e0273dcd3c7ccd',
                     'sha1_git': '6a15ea8b881069adedf11feceec35588f2cfe8f1',
                     'sha256': '401d0df797110bea805d358b85bcc1ced29549d3d73f'
                     '309d36484e7edf7bb912'
                 }]
             },
         }
 
         # when
         rv = self.client.get('/api/1/revision/'
                              '18d8be353ed3480476f032475e7c233eff7371d5/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(expected_revision, rv.data)
 
         mock_service.lookup_revision.assert_called_once_with(
             '18d8be353ed3480476f032475e7c233eff7371d5')
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_not_found(self, mock_service):
         # given
         mock_service.lookup_revision.return_value = None
 
         # when
         rv = self.client.get('/api/1/revision/12345/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, {
             'exception': 'NotFoundExc',
             'reason': 'Revision with sha1_git 12345 not found.'})
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_raw_ok(self, mock_service):
         # given
         stub_revision = {'message': 'synthetic revision message'}
 
         mock_service.lookup_revision_message.return_value = stub_revision
 
         # when
         rv = self.client.get('/api/1/revision/18d8be353ed3480476f032475e7c2'
                              '33eff7371d5/raw/')
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/octet-stream')
         self.assertEqual(rv.content, b'synthetic revision message')
 
         mock_service.lookup_revision_message.assert_called_once_with(
             '18d8be353ed3480476f032475e7c233eff7371d5')
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_raw_ok_no_msg(self, mock_service):
         # given
         mock_service.lookup_revision_message.side_effect = NotFoundExc(
             'No message for revision')
 
         # when
         rv = self.client.get('/api/1/revision/'
                              '18d8be353ed3480476f032475e7c233eff7371d5/raw/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, {
             'exception': 'NotFoundExc',
             'reason': 'No message for revision'})
 
         self.assertEqual
         mock_service.lookup_revision_message.assert_called_once_with(
             '18d8be353ed3480476f032475e7c233eff7371d5')
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_raw_ko_no_rev(self, mock_service):
         # given
         mock_service.lookup_revision_message.side_effect = NotFoundExc(
             'No revision found')
 
         # when
         rv = self.client.get('/api/1/revision/'
                              '18d8be353ed3480476f032475e7c233eff7371d5/raw/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, {
             'exception': 'NotFoundExc',
             'reason': 'No revision found'})
 
         mock_service.lookup_revision_message.assert_called_once_with(
             '18d8be353ed3480476f032475e7c233eff7371d5')
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_with_origin_not_found(self, mock_service):
         mock_service.lookup_revision_by.return_value = None
 
         rv = self.client.get('/api/1/revision/origin/123/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertIn('Revision with (origin_id: 123', rv.data['reason'])
         self.assertIn('not found', rv.data['reason'])
         self.assertEqual('NotFoundExc', rv.data['exception'])
 
         mock_service.lookup_revision_by.assert_called_once_with(
             '123',
             'HEAD',
             None)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_with_origin(self, mock_service):
         mock_revision = {
             'id': '32',
             'directory': '21',
             'message': 'message 1',
             'type': 'deb',
         }
         expected_revision = {
             'id': '32',
             'url': '/api/1/revision/32/',
             'history_url': '/api/1/revision/32/log/',
             'directory': '21',
             'directory_url': '/api/1/directory/21/',
             'message': 'message 1',
             'type': 'deb',
         }
         mock_service.lookup_revision_by.return_value = mock_revision
 
         rv = self.client.get('/api/1/revision/origin/1/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_revision)
 
         mock_service.lookup_revision_by.assert_called_once_with(
             '1',
             'HEAD',
             None)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_with_origin_and_branch_name(self, mock_service):
         mock_revision = {
             'id': '12',
             'directory': '23',
             'message': 'message 2',
             'type': 'tar',
         }
         mock_service.lookup_revision_by.return_value = mock_revision
 
         expected_revision = {
             'id': '12',
             'url': '/api/1/revision/12/',
             'history_url': '/api/1/revision/12/log/',
             'directory': '23',
             'directory_url': '/api/1/directory/23/',
             'message': 'message 2',
             'type': 'tar',
         }
 
         rv = self.client.get('/api/1/revision/origin/1'
                              '/branch/refs/origin/dev/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_revision)
 
         mock_service.lookup_revision_by.assert_called_once_with(
             '1',
             'refs/origin/dev',
             None)
 
     @patch('swh.web.api.views.revision.service')
     @patch('swh.web.api.views.revision.utils')
     def test_api_revision_with_origin_and_branch_name_and_timestamp(self,
                                                                mock_utils,
                                                                mock_service): # noqa
         mock_revision = {
             'id': '123',
             'directory': '456',
             'message': 'message 3',
             'type': 'tar',
         }
         mock_service.lookup_revision_by.return_value = mock_revision
 
         expected_revision = {
             'id': '123',
             'url': '/api/1/revision/123/',
             'history_url': '/api/1/revision/123/log/',
             'directory': '456',
             'directory_url': '/api/1/directory/456/',
             'message': 'message 3',
             'type': 'tar',
         }
 
         mock_utils.enrich_revision.return_value = expected_revision
 
         rv = self.client.get('/api/1/revision'
                              '/origin/1'
                              '/branch/refs/origin/dev'
                              '/ts/1452591542/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_revision)
 
         mock_service.lookup_revision_by.assert_called_once_with(
             '1',
             'refs/origin/dev',
             '1452591542')
         mock_utils.enrich_revision.assert_called_once_with(
             mock_revision)
 
     @patch('swh.web.api.views.revision.service')
     @patch('swh.web.api.views.revision.utils')
     def test_api_revision_with_origin_and_branch_name_and_timestamp_escapes(
             self,
             mock_utils,
             mock_service):
         mock_revision = {
             'id': '999',
         }
         mock_service.lookup_revision_by.return_value = mock_revision
 
         expected_revision = {
             'id': '999',
             'url': '/api/1/revision/999/',
             'history_url': '/api/1/revision/999/log/',
         }
 
         mock_utils.enrich_revision.return_value = expected_revision
 
         rv = self.client.get('/api/1/revision'
                              '/origin/1'
                              '/branch/refs%2Forigin%2Fdev'
                              '/ts/Today%20is%20'
                              'January%201,%202047%20at%208:21:00AM/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_revision)
 
         mock_service.lookup_revision_by.assert_called_once_with(
             '1',
             'refs/origin/dev',
             'Today is January 1, 2047 at 8:21:00AM')
         mock_utils.enrich_revision.assert_called_once_with(
             mock_revision)
 
     @patch('swh.web.api.views.revision.service')
     def test_revision_directory_by_ko_raise(self, mock_service):
         # given
         mock_service.lookup_directory_through_revision.side_effect = NotFoundExc('not')  # noqa
 
         # when
         with self.assertRaises(NotFoundExc):
             _revision_directory_by(
                 {'sha1_git': 'id'},
                 None,
                 '/api/1/revision/sha1/directory/')
 
         # then
         mock_service.lookup_directory_through_revision.assert_called_once_with(
             {'sha1_git': 'id'},
             None, limit=100, with_data=False)
 
     @patch('swh.web.api.views.revision.service')
     def test_revision_directory_by_type_dir(self, mock_service):
         # given
         mock_service.lookup_directory_through_revision.return_value = (
             'rev-id',
             {
                 'type': 'dir',
                 'revision': 'rev-id',
                 'path': 'some/path',
                 'content': []
             })
         # when
         actual_dir_content = _revision_directory_by(
             {'sha1_git': 'blah-id'},
             'some/path', '/api/1/revision/sha1/directory/')
 
         # then
         self.assertEqual(actual_dir_content, {
             'type': 'dir',
             'revision': 'rev-id',
             'path': 'some/path',
             'content': []
         })
 
         mock_service.lookup_directory_through_revision.assert_called_once_with(
             {'sha1_git': 'blah-id'},
             'some/path', limit=100, with_data=False)
 
     @patch('swh.web.api.views.revision.service')
     def test_revision_directory_by_type_file(self, mock_service):
         # given
         mock_service.lookup_directory_through_revision.return_value = (
             'rev-id',
             {
                 'type': 'file',
                 'revision': 'rev-id',
                 'path': 'some/path',
                 'content': {'blah': 'blah'}
             })
         # when
         actual_dir_content = _revision_directory_by(
             {'sha1_git': 'sha1'},
             'some/path',
             '/api/1/revision/origin/2/directory/',
             limit=1000, with_data=True)
 
         # then
         self.assertEqual(actual_dir_content, {
                 'type': 'file',
                 'revision': 'rev-id',
                 'path': 'some/path',
                 'content': {'blah': 'blah'}
             })
 
         mock_service.lookup_directory_through_revision.assert_called_once_with(
             {'sha1_git': 'sha1'},
             'some/path', limit=1000, with_data=True)
 
     @patch('swh.web.api.views.revision.parse_timestamp')
     @patch('swh.web.api.views.revision._revision_directory_by')
     @patch('swh.web.api.views.revision.utils')
     def test_api_directory_through_revision_origin_ko_not_found(self,
                                                            mock_utils,
                                                            mock_rev_dir,
                                                            mock_parse_timestamp): # noqa
         mock_rev_dir.side_effect = NotFoundExc('not found')
         mock_parse_timestamp.return_value = '2012-10-20 00:00:00'
 
         rv = self.client.get('/api/1/revision'
                              '/origin/10'
                              '/branch/refs/remote/origin/dev'
                              '/ts/2012-10-20'
                              '/directory/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, {
             'exception': 'NotFoundExc',
             'reason': 'not found'})
 
         mock_rev_dir.assert_called_once_with(
             {'origin_id': '10',
              'branch_name': 'refs/remote/origin/dev',
              'ts': '2012-10-20 00:00:00'}, None,
             '/api/1/revision'
             '/origin/10'
             '/branch/refs/remote/origin/dev'
             '/ts/2012-10-20'
             '/directory/',
             with_data=False)
 
     @patch('swh.web.api.views.revision._revision_directory_by')
     def test_api_directory_through_revision_origin(self,
                                                    mock_revision_dir):
         expected_res = [{
             'id': '123'
         }]
         mock_revision_dir.return_value = expected_res
 
         rv = self.client.get('/api/1/revision/origin/3/directory/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_res)
 
         mock_revision_dir.assert_called_once_with({
             'origin_id': '3',
             'branch_name': 'refs/heads/master',
             'ts': None}, None, '/api/1/revision/origin/3/directory/',
                                                   with_data=False)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log(self, mock_service):
         # given
         stub_revisions = [{
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'],
             'type': 'tar',
             'synthetic': True,
         }]
         mock_service.lookup_revision_log.return_value = stub_revisions
 
         expected_revisions = [{
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/',
             'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233ef'
             'f7371d5/log/',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6a'
             '42b7e2a44e6/',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': [{
                 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345',
                 'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/',  # noqa
             }],
             'type': 'tar',
             'synthetic': True,
         }]
 
         # when
         rv = self.client.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42'
                              'b7e2a44e6/log/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
 
         self.assertEqual(rv.data, expected_revisions)
         self.assertFalse(rv.has_header('Link'))
 
         mock_service.lookup_revision_log.assert_called_once_with(
             '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 11)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log_with_next(self, mock_service):
         # given
         stub_revisions = []
         for i in range(27):
             stub_revisions.append({'id': str(i)})
 
         mock_service.lookup_revision_log.return_value = stub_revisions[:26]
 
         expected_revisions = [x for x in stub_revisions if int(x['id']) < 25]
         for e in expected_revisions:
             e['url'] = '/api/1/revision/%s/' % e['id']
             e['history_url'] = '/api/1/revision/%s/log/' % e['id']
 
         # when
         rv = self.client.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6a42'
                              'b7e2a44e6/log/?per_page=25')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_revisions)
         self.assertEqual(rv['Link'],
                          '</api/1/revision/25/log/?per_page=25>; rel="next"')
 
         mock_service.lookup_revision_log.assert_called_once_with(
             '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 26)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log_not_found(self, mock_service):
         # given
         mock_service.lookup_revision_log.return_value = None
 
         # when
         rv = self.client.get('/api/1/revision/8834ef7e7c357ce2af928115c6c6'
                              'a42b7e2a44e6/log/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, {
             'exception': 'NotFoundExc',
             'reason': 'Revision with sha1_git'
             ' 8834ef7e7c357ce2af928115c6c6a42b7e2a44e6 not found.'})
         self.assertFalse(rv.has_header('Link'))
 
         mock_service.lookup_revision_log.assert_called_once_with(
             '8834ef7e7c357ce2af928115c6c6a42b7e2a44e6', 11)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log_context(self, mock_service):
         # given
         stub_revisions = [{
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'],
             'type': 'tar',
             'synthetic': True,
         }]
 
         mock_service.lookup_revision_log.return_value = stub_revisions
         mock_service.lookup_revision_multiple.return_value = [{
             'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'directory': '18d8be353ed3480476f032475e7c233eff7371d5',
             'author_name': 'Name Surname',
             'author_email': 'name@surname.com',
             'committer_name': 'Name Surname',
             'committer_email': 'name@surname.com',
             'message': 'amazing revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': ['adc83b19e793491b1c6ea0fd8b46cd9f32e592fc'],
             'type': 'tar',
             'synthetic': True,
         }]
 
         expected_revisions = [
             {
                 'url': '/api/1/revision/'
                 '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/',
                 'history_url': '/api/1/revision/'
                 '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/log/',
                 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
                 'directory': '18d8be353ed3480476f032475e7c233eff7371d5',
                 'directory_url': '/api/1/directory/'
                 '18d8be353ed3480476f032475e7c233eff7371d5/',
                 'author_name': 'Name Surname',
                 'author_email': 'name@surname.com',
                 'committer_name': 'Name Surname',
                 'committer_email': 'name@surname.com',
                 'message': 'amazing revision message',
                 'date_offset': 0,
                 'committer_date_offset': 0,
                 'parents': [{
                     'id': 'adc83b19e793491b1c6ea0fd8b46cd9f32e592fc',
                     'url': '/api/1/revision/adc83b19e793491b1c6ea0fd8b46cd9f32e592fc/',  # noqa
                 }],
                 'type': 'tar',
                 'synthetic': True,
             },
             {
                 'url': '/api/1/revision/'
                 '18d8be353ed3480476f032475e7c233eff7371d5/',
                 'history_url': '/api/1/revision/'
                 '18d8be353ed3480476f032475e7c233eff7371d5/log/',
                 'id': '18d8be353ed3480476f032475e7c233eff7371d5',
                 'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
                 'directory_url': '/api/1/directory/'
                 '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6/',
                 'author_name': 'Software Heritage',
                 'author_email': 'robot@softwareheritage.org',
                 'committer_name': 'Software Heritage',
                 'committer_email': 'robot@softwareheritage.org',
                 'message': 'synthetic revision message',
                 'date_offset': 0,
                 'committer_date_offset': 0,
                 'parents': [{
                     'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345',
                     'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/',  # noqa
                 }],
                 'type': 'tar',
                 'synthetic': True,
             }]
 
         # when
         rv = self.client.get('/api/1/revision/18d8be353ed3480476f0'
                              '32475e7c233eff7371d5/prev/21145781e2'
                              '6ad1f978e/log/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(expected_revisions, rv.data)
         self.assertFalse(rv.has_header('Link'))
 
         mock_service.lookup_revision_log.assert_called_once_with(
             '18d8be353ed3480476f032475e7c233eff7371d5', 11)
         mock_service.lookup_revision_multiple.assert_called_once_with(
             ['21145781e26ad1f978e'])
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log_by(self, mock_service):
         # given
         stub_revisions = [{
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': ['7834ef7e7c357ce2af928115c6c6a42b7e2a4345'],
             'type': 'tar',
             'synthetic': True,
         }]
         mock_service.lookup_revision_log_by.return_value = stub_revisions
 
         expected_revisions = [{
             'id': '18d8be353ed3480476f032475e7c233eff7371d5',
             'url': '/api/1/revision/18d8be353ed3480476f032475e7c233eff7371d5/',
             'history_url': '/api/1/revision/18d8be353ed3480476f032475e7c233ef'
                            'f7371d5/log/',
             'directory': '7834ef7e7c357ce2af928115c6c6a42b7e2a44e6',
             'directory_url': '/api/1/directory/7834ef7e7c357ce2af928115c6c6a'
                              '42b7e2a44e6/',
             'author_name': 'Software Heritage',
             'author_email': 'robot@softwareheritage.org',
             'committer_name': 'Software Heritage',
             'committer_email': 'robot@softwareheritage.org',
             'message': 'synthetic revision message',
             'date_offset': 0,
             'committer_date_offset': 0,
             'parents': [{
                 'id': '7834ef7e7c357ce2af928115c6c6a42b7e2a4345',
                  'url': '/api/1/revision/7834ef7e7c357ce2af928115c6c6a42b7e2a4345/'  # noqa
             }],
             'type': 'tar',
             'synthetic': True,
         }]
 
         # when
         rv = self.client.get('/api/1/revision/origin/1/log/')
 
         # then
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, expected_revisions)
         self.assertFalse(rv.has_header('Link'))
 
         mock_service.lookup_revision_log_by.assert_called_once_with(
             '1', 'HEAD', None, 11)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log_by_with_next(self, mock_service):
         # given
         stub_revisions = []
         for i in range(27):
             stub_revisions.append({'id': str(i)})
 
         mock_service.lookup_revision_log_by.return_value = stub_revisions[:26]
 
         expected_revisions = [x for x in stub_revisions if int(x['id']) < 25]
         for e in expected_revisions:
             e['url'] = '/api/1/revision/%s/' % e['id']
             e['history_url'] = '/api/1/revision/%s/log/' % e['id']
 
         # when
         rv = self.client.get('/api/1/revision/origin/1/log/?per_page=25')
 
         # then
         self.assertEqual(rv.status_code, 200)
 
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertIsNotNone(rv['Link'])
         self.assertEqual(rv.data, expected_revisions)
 
         mock_service.lookup_revision_log_by.assert_called_once_with(
             '1', 'HEAD', None, 26)
 
     @patch('swh.web.api.views.revision.service')
     def test_api_revision_log_by_norev(self, mock_service):
         # given
         mock_service.lookup_revision_log_by.side_effect = NotFoundExc(
             'No revision')
 
         # when
         rv = self.client.get('/api/1/revision/origin/1/log/')
 
         # then
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertFalse(rv.has_header('Link'))
         self.assertEqual(rv.data, {'exception': 'NotFoundExc',
                                    'reason': 'No revision'})
 
         mock_service.lookup_revision_log_by.assert_called_once_with(
             '1', 'HEAD', None, 11)
 
-    @patch('swh.web.api.views.revision.service')
-    def test_api_revision_history(self, mock_service):
-        # for readability purposes, we use:
-        # - sha1 as 3 letters (url are way too long otherwise to respect pep8)
-        # - only keys with modification steps (all other keys are kept as is)
-
-        # given
-        stub_revision = {
-            'id': '883',
-            'children': ['777', '999'],
-            'parents': [],
-            'directory': '272'
-        }
-
-        mock_service.lookup_revision.return_value = stub_revision
-
-        # then
-        rv = self.client.get('/api/1/revision/883/prev/999/')
-
-        self.assertEqual(rv.status_code, 200)
-        self.assertEqual(rv['Content-Type'], 'application/json')
-        self.assertEqual(rv.data, {
-            'id': '883',
-            'url': '/api/1/revision/883/',
-            'history_url': '/api/1/revision/883/log/',
-            'history_context_url': '/api/1/revision/883/prev/999/log/',
-            'children': ['777', '999'],
-            'children_urls': ['/api/1/revision/777/',
-                              '/api/1/revision/999/'],
-            'parents': [],
-            'directory': '272',
-            'directory_url': '/api/1/directory/272/'
-        })
-
-        mock_service.lookup_revision.assert_called_once_with('883')
-
     @patch('swh.web.api.views.revision._revision_directory_by')
     def test_api_revision_directory_ko_not_found(self, mock_rev_dir):
         # given
         mock_rev_dir.side_effect = NotFoundExc('Not found')
 
         # then
         rv = self.client.get('/api/1/revision/999/directory/some/path/to/dir/')
 
         self.assertEqual(rv.status_code, 404)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, {
             'exception': 'NotFoundExc',
             'reason': 'Not found'})
 
         mock_rev_dir.assert_called_once_with(
             {'sha1_git': '999'},
             'some/path/to/dir',
             '/api/1/revision/999/directory/some/path/to/dir/',
             with_data=False)
 
     @patch('swh.web.api.views.revision._revision_directory_by')
     def test_api_revision_directory_ok_returns_dir_entries(self, mock_rev_dir):
         stub_dir = {
             'type': 'dir',
             'revision': '999',
             'content': [
                 {
                     'sha1_git': '789',
                     'type': 'file',
                     'target': '101',
                     'target_url': '/api/1/content/sha1_git:101/',
                     'name': 'somefile',
                     'file_url': '/api/1/revision/999/directory/some/path/'
                     'somefile/'
                 },
                 {
                     'sha1_git': '123',
                     'type': 'dir',
                     'target': '456',
                     'target_url': '/api/1/directory/456/',
                     'name': 'to-subdir',
                     'dir_url': '/api/1/revision/999/directory/some/path/'
                     'to-subdir/',
                 }]
         }
 
         # given
         mock_rev_dir.return_value = stub_dir
 
         # then
         rv = self.client.get('/api/1/revision/999/directory/some/path/')
 
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, stub_dir)
 
         mock_rev_dir.assert_called_once_with(
             {'sha1_git': '999'},
             'some/path',
             '/api/1/revision/999/directory/some/path/',
             with_data=False)
 
     @patch('swh.web.api.views.revision._revision_directory_by')
     def test_api_revision_directory_ok_returns_content(self, mock_rev_dir):
         stub_content = {
             'type': 'file',
             'revision': '999',
             'content': {
                 'sha1_git': '789',
                 'sha1': '101',
                 'data_url': '/api/1/content/101/raw/',
             }
         }
 
         # given
         mock_rev_dir.return_value = stub_content
 
         # then
         url = '/api/1/revision/666/directory/some/other/path/'
         rv = self.client.get(url)
 
         self.assertEqual(rv.status_code, 200)
         self.assertEqual(rv['Content-Type'], 'application/json')
         self.assertEqual(rv.data, stub_content)
 
         mock_rev_dir.assert_called_once_with(
             {'sha1_git': '666'}, 'some/other/path', url, with_data=False)