diff --git a/.coveragerc b/.coveragerc
index a9417ac42accecb3b351172f82616455c5226605..a4faf805dbac31700cc1061cc5d52c14457ab653 100644
--- a/.coveragerc
+++ b/.coveragerc
@@ -1,14 +1,39 @@
 [report]
+# When running a summary report, show missing lines.
+# (boolean)
 show_missing = True
 
+# Any line of source code that matches one of these regexes is excluded
+# from being reported as missing.
+# (multi-string)
 exclude_lines =
     # Have to re-enable the standard pragma
     pragma: no cover
 
     # Don't complain if tests don't hit defensive assertion code:
+    raise AssertionError
     raise NotImplementedError
 
+# List of file name patterns, the files to include in reporting.
+# (multi-string)
+include =
+    */api_doc/*
+    */api_roundup/*
+    */aslint/*
+    */hgaster/hooks/*.py
+    #*/api_bitbucket/*
+
+# List of file name patterns, the files to leave out of reporting.
+# (multi-string)
+omit =
+    */api_roundup/stats.py
+    */hgaster/hooks/codeaster.py
+    */share/test/*
+
+
 [run]
+# List of file name patterns, the files to include in measurement.
+# (multi-string)
 include =
     */api_doc/*
     */api_roundup/*
@@ -16,6 +41,8 @@ include =
     */hgaster/hooks/*.py
     #*/api_bitbucket/*
 
+# List of file name patterns, the files to leave out of measurement.
+# (multi-string)
 omit =
     */api_roundup/stats.py
     */hgaster/hooks/codeaster.py
diff --git a/bin/maint/mergexx b/bin/maint/mergexx
index 6ce1e66ea792e624188104a0d39faa377d0cc3d9..6029c03fadec85ce434c0977df7cd708a71b7359 100755
--- a/bin/maint/mergexx
+++ b/bin/maint/mergexx
@@ -48,7 +48,7 @@ run_main()
     [ $# -ne 1 ] && _error "exactly one argument is expected."
     tag="$1"
 
-    if [ $(hg status | wc -l) -ne 0 ]; then
+    if [ $(hg status -ardm | wc -l) -ne 0 ]; then
         _error "uncommitted changes! Please discard or commit first."
     fi
 
@@ -65,7 +65,7 @@ run_main()
     printf "\ncommitting with message '${msg}'...\n"
     hg ci -m "${msg}" || _error "failed"
 
-    printf "\nDo forget to submit the new revision!\n"
+    printf "\nDo not forget to submit the new revision!\n"
     return ${?}
 }
 
diff --git a/lib/aslint/check_global.py b/lib/aslint/check_global.py
index 23293015679eb7627b5da703f594c5b5f3eefd1d..ff633476d3af7227da0eac6176b939fff98221f4 100644
--- a/lib/aslint/check_global.py
+++ b/lib/aslint/check_global.py
@@ -31,24 +31,8 @@ class ErrorMessages(DirnameCat, GenericMsg):
         # only in 'src'
         if not osp.isdir(osp.join(srcdir, 'bibpyt', 'Messages')):
             return result
-        found = False
-        subdirs = ['build', 'build/std', 'build/mpi']
-        if ASCFG.get('waf.builddir') not in subdirs:
-            subdirs.insert(0, ASCFG.get('waf.builddir'))
-        for bld in ('release', 'debug'):
-            for sub in subdirs:
-                instdir = osp.join(srcdir, sub, bld)
-                fconf = osp.join(instdir, 'data', 'config.txt')
-                if osp.isfile(osp.join(instdir, 'config.txt')) or \
-                    osp.isfile(fconf):
-                    found = True
-                    break
-        if not found:
-            return [": can not check messages, 'config.txt' not found in "
-                    "debug/release of this directories {0}"
-                    .format(tuple(subdirs))]
         try:
-            unused, not_found = check_messages(instdir, srcdir)
+            unused, not_found = check_messages(srcdir)
             result.extend([': %s (unused)' % msg for msg in unused])
             result.extend([': %s (missing)' % msg for msg in not_found])
         except ValueError, exc:
@@ -87,14 +71,15 @@ class Supv002aRequirement(DirnameCat, GenericMsg):
 CHECK_LIST = checkers_from_context(globals(), TextMsg)
 
 
-def check_messages(instdir, srcdir):
+def check_messages(srcdir):
     """Check the errors messages"""
     from aslint.messages import MessagesManager, CataMessageError
     tmpcache = tempfile.NamedTemporaryFile(prefix='cachedict.').name
     catapy = osp.abspath(osp.join(srcdir, 'code_aster'))
     if not osp.exists(catapy):
         catapy = osp.abspath(osp.join(srcdir, 'catapy'))
-    msgman = MessagesManager(repref=instdir,
+    # repref is not necessary because fort, pyt and capy are absolute paths
+    msgman = MessagesManager(repref="__unused__",
                              fort=osp.abspath(osp.join(srcdir, 'bibfor')),
                              pyt=osp.abspath(osp.join(srcdir, 'bibpyt')),
                              capy=catapy,
diff --git a/lib/aslint/fortran/check_source.py b/lib/aslint/fortran/check_source.py
index 1b377d6a1b338929ddbbef9578402ddf62afa1c6..a05873f6a8fbdada6e1318de2e97023db2129d47 100644
--- a/lib/aslint/fortran/check_source.py
+++ b/lib/aslint/fortran/check_source.py
@@ -15,15 +15,27 @@ from aslint.config import ASCFG
 from aslint.decorators import interrupt_decorator
 from aslint.utils import apply_in_sandbox
 from aslint.base_checkers import (
-    Report, MsgList, CheckList, CompilMsg,
+    Report, MsgList, CheckList, CompilMsg, GenericMsg,
     call_checkers,
     check_file_content, check_filename, check_disabled, check_fortran_code,
 )
+from aslint.fortran.free.fortran_code import FortranParserError
 import aslint.fortran.gfortran_checkers as GFORT
 import aslint.fortran.static_fortran_checkers as STAT
 import aslint.common_checkers as COMM
 
 
+class ParserMsg(GenericMsg):
+    """Fortran parser error
+    There is probably an error reported by the compiler. Otherwise, please
+    report this error."""
+    id = 'C1011'
+
+    def search(self, txt):
+        """Returns the error message"""
+        return [": " + txt]
+
+
 @interrupt_decorator
 def check_fortran_source(fname, flags, incdir, checklist, tmpdir=None):
     """Check a fortran source file."""
@@ -42,9 +54,12 @@ def check_fortran_source(fname, flags, incdir, checklist, tmpdir=None):
         lmsg.extend(check_file_content(fname, checklist.on_content()))
         lmsg.extend(check_fortran_code(fname, checklist.on_fortran_code()))
         lmsg.extend(check_filename(fname, checklist.on_filename()))
-    except:
+    except FortranParserError as exc:
+        checker = ParserMsg(None)
+        checker.check(lmsg, exc.msg)
+    except Exception as exc:
         logger.error(_("cannot check %r"), fname)
-        raise
+        raise RuntimeError(exc)
     check_disabled(fname, checklist, lmsg)
     report = Report()
     report.set(fname, lmsg)
diff --git a/lib/hgaster/ascommands.py b/lib/hgaster/ascommands.py
index f4da15b0426df692de7f137af2de273c8300c03e..3c1628c9b0a941b08ee4ec0b5f99f287d16bc355 100644
--- a/lib/hgaster/ascommands.py
+++ b/lib/hgaster/ascommands.py
@@ -34,6 +34,7 @@ from .ext_utils import (check_for_updates, get_changed_files, get_description,
                         parent_is_last, sendmail, shortrev, shortrev_s,
                         valid_branch)
 from .request_queue import QueueError, Request, RequestQueue, requestkey
+from .hooks.generic import OK
 
 cmdtable = {}
 command = cmdutil.command(cmdtable)
@@ -110,7 +111,7 @@ def submit(ui, repo, *args, **opts):
     if reponame == "devtools":
         class_ = SubmitDevtools
     elif reponame in ("data", "src", "validation"):
-        class_ = SubmitAster
+        class_ = SubmitAsterLegacy
     elif reponame in ("data-xx", "src-xx", "validation-xx"):
         class_ = SubmitAsterXX
     elif reponame == "salome-codeaster-study":
@@ -329,7 +330,7 @@ class CandidateRevisionCheck(object):
             if not self._local:
                 self.refrev = self.get_reference_revision()
         if not self._local:
-            if not self.valid_branch(self.repo, self.wrkbranch):
+            if not self.valid_branch():
                 self._error(_("integration is not allowed in the branch '{0}'")
                             .format(self.wrkbranch))
         if not self.refrev:
@@ -580,10 +581,20 @@ class CandidateRevisionCheck(object):
             self._error(_("can not find the last integrated revision"))
         return refrev
 
-    @staticmethod
-    def valid_branch(repo, branch):
+    def check_single_head(self):
+        """Check for single heads in branch."""
+        from hooks.generic import single_head_per_branch_hook
+        checker = single_head_per_branch_hook()
+        return checker(self.ui, self.repo, self.wrkrev) == OK
+
+    def check_branch(self, repo, branch): # pragma pylint: disable=unused-argument
         """Check branch validity."""
-        return valid_branch(repo, branch)
+        raise NotImplementedError("must be subclassed")
+
+    def valid_branch(self):
+        """Check branch validity."""
+        return (self.check_branch(self.repo, self.wrkbranch) and
+                self.check_single_head())
 
 
 class CandidateRevisionCheckAster(CandidateRevisionCheck):
@@ -656,9 +667,8 @@ class CandidateRevisionCheckAster(CandidateRevisionCheck):
             for fname in lfiles:
                 adiff = get_diff(self.ui, self.repo, revs, [fname])
                 diffs[typ][fname] = adiff
-        errcode = check_diff(self._report, diffs)
+        check_diff(self._report, diffs)
         os.chdir(prev)
-        return errcode
 
     @stop_on_failure
     def check_waf_build(self):
@@ -944,7 +954,7 @@ class AbstractSubmit(CandidateRevisionCheck):
         return 0
 
 
-class SubmitAster(CandidateRevisionCheckAster, AbstractSubmit):
+class AbstractSubmitAster(CandidateRevisionCheckAster, AbstractSubmit):
 
     """Check code_aster source files at the parent revision
     and, in case of success, submit changesets for continuous integration.
@@ -952,7 +962,7 @@ class SubmitAster(CandidateRevisionCheckAster, AbstractSubmit):
 
     def __init__(self, ui, repo, *args, **opts):
         """Initialization"""
-        super(SubmitAster, self).__init__(ui, repo, *args, **opts)
+        super(AbstractSubmitAster, self).__init__(ui, repo, *args, **opts)
         self._resutest = opts.get("resutest")
 
     @stop_on_failure
@@ -992,7 +1002,7 @@ class SubmitAster(CandidateRevisionCheckAster, AbstractSubmit):
 
     def run(self):
         """Execute the elementary tasks"""
-        super(SubmitAster, self).check_init()
+        super(AbstractSubmitAster, self).check_init()
         self.set_working_revision()
         self.set_parameters()
         logger.title(_("asking integration in branch '{0}' of the repository"
@@ -1025,7 +1035,24 @@ class SubmitAster(CandidateRevisionCheckAster, AbstractSubmit):
         return 0
 
 
-class SubmitAsterXX(SubmitAster):
+class SubmitAsterLegacy(AbstractSubmitAster):
+
+    """Check code_aster source files at the parent revision
+    and, in case of success, submit changesets for continuous integration.
+    """
+
+    @staticmethod
+    def check_single_head():
+        """Check single heads in branch."""
+        # multiple heads allowed in code_aster legacy repositories
+        return True
+
+    def check_branch(self, repo, branch):
+        """Check branch validity."""
+        return valid_branch(repo, branch)
+
+
+class SubmitAsterXX(AbstractSubmitAster):
 
     """Check code_aster++ source files at the parent revision
     and, in case of success, submit changesets for continuous integration.
@@ -1055,10 +1082,9 @@ class SubmitAsterXX(SubmitAster):
         XXCFG.waf_builddir = "build/std"
         return XXCFG.get(key, default)
 
-    @staticmethod
-    def valid_branch(dummy, branch):
+    def check_branch(self, dummy, branch):
         """Check branch validity."""
-        from hooks.generic import OK, branch_checker
+        from hooks.generic import branch_checker
         return branch_checker('^asterxx/')(branch) == OK
 
     def accept_special_issue(self, issue_id):
@@ -1109,22 +1135,20 @@ class SubmitDevtools(AbstractSubmit):
         par = super(SubmitDevtools, self)
         return par.check_issues_status(expected, logfunc=logger.warn)
 
-    @staticmethod
-    def valid_branch(dummy, branch):
+    def check_branch(self, dummy, branch):
         """Check branch validity."""
-        from hooks.generic import OK
         from hooks.devtools import repo_branch_checker
         return repo_branch_checker(branch) == OK
 
 
-class SubmitSMecaMinimal(AbstractSubmit):
+class AbstractSubmitSmeca(AbstractSubmit):
 
     """Minimal 'submit' command for some salome_meca tools (only push changes).
     """
 
     def __init__(self, ui, repo, *args, **opts):
         """Initialization"""
-        super(SubmitSMecaMinimal, self).__init__(ui, repo, *args, **opts)
+        super(AbstractSubmitSmeca, self).__init__(ui, repo, *args, **opts)
         self.refbranch = "edf/default"
 
     @classmethod
@@ -1133,7 +1157,7 @@ class SubmitSMecaMinimal(AbstractSubmit):
         return SMCFG.get(key, default)
 
 
-class SubmitAsterStudy(SubmitSMecaMinimal):
+class SubmitAsterStudy(AbstractSubmitSmeca):
 
     """Check AsterStudy source files at the parent revision
     and, in case of success, submit changesets for continuous integration.
@@ -1142,28 +1166,22 @@ class SubmitAsterStudy(SubmitSMecaMinimal):
     command_lint = ["./check_lint.sh", "-p"]
     command_tests = [["./check_salome.sh", "-c"],
                      ["./check_docs.sh"],
-                     ["./check_comm2study.sh", "clean", "--jobs=4"],
-                     ["./check_comm2code.sh", "clean", "--jobs=4"],
-                     ["./check_persistence.sh", "clean", "--jobs=4"],
-                     ["./check_performance.sh", "clean", "--jobs=4"],
                     ]
 
     @staticmethod
-    def valid_branch(dummy, branch):
+    def check_branch(dummy, branch):
         """Check branch validity."""
-        from hooks.generic import OK
         from hooks.asterstudy import repo_branch_checker
         return repo_branch_checker(branch) == OK
 
 
-class SubmitRTool(SubmitSMecaMinimal):
+class SubmitRTool(AbstractSubmitSmeca):
 
     """Submit command for some salome_meca RTOOL plugin."""
 
     @staticmethod
-    def valid_branch(dummy, branch):
+    def check_branch(dummy, branch):
         """Check branch validity."""
-        from hooks.generic import OK
         from hooks.rtool import repo_branch_checker
         return repo_branch_checker(branch) == OK
 
diff --git a/lib/hgaster/ext_utils.py b/lib/hgaster/ext_utils.py
index d61731d893af082a4c854582e90ace66d59b87c0..9a25641e49f0bda6557752070971c1ef01d7839e 100644
--- a/lib/hgaster/ext_utils.py
+++ b/lib/hgaster/ext_utils.py
@@ -205,7 +205,7 @@ def get_hgpath(ui, repo, dest):
 
 
 def valid_branch(repo, branch):
-    """Return True if 'branch' is one of the open branches
+    """Return True if 'branch' is one of the opened branches
     (default or the last vNN)"""
     if branch == 'default':
         return True
diff --git a/lib/hgaster/hooks/generic.py b/lib/hgaster/hooks/generic.py
index 5a0ce33134cc40881b8a635599adbbe558c4bd0b..f15ce050885b9d839312ab59ef1be81c69c308c0 100644
--- a/lib/hgaster/hooks/generic.py
+++ b/lib/hgaster/hooks/generic.py
@@ -180,6 +180,8 @@ def single_head_per_branch_hook(in_branch=None):
         for branch, heads in repo.branchmap().items():
             if in_branch and not re.search(in_branch, branch):
                 continue
+            if node.branch() != branch:
+                continue
             unclosed = [head for head in heads
                         if not repo[head].extra().get("close")]
             if len(unclosed) > 1:
diff --git a/share/test/aslint/test_check_files.py b/share/test/aslint/test_check_files.py
index 5d4df03015a660c12493749d3c15436dd16ba924..17359c70f0a91fca4154f7d6639e76580a7be41e 100644
--- a/share/test/aslint/test_check_files.py
+++ b/share/test/aslint/test_check_files.py
@@ -6,12 +6,26 @@ Tests for the Docaster API.
 
 import os
 import os.path as osp
+import tempfile
 import unittest
 
 from hamcrest import *
 from testutils import CODEASTER_SRC
 
 
+# the parser fails in eval_parameters if 'if' statement is incomplete
+SNIPPET_PARSER_ERROR = """
+subroutine rc32t
+    implicit none
+    character(len=8) :: option, poum
+    if (option .eq. 'RIGI_MECA_TANG')
+        poum = '-'
+    else
+        poum = '+'
+    endif
+end subroutine
+"""
+
 def test_get_file_type():
     """test manifest"""
     from aslint.filetype import get_file_type
@@ -55,19 +69,24 @@ def test_filter_names():
     assert len(filter_names(flist)) == 3
 
 def test_check_files():
-    """check a source file"""
+    """check source files"""
     from aslint.base_checkers import Report
     from aslint.check_files import check_files, read_waf_parameters
     from aslint.filetype import filter_arguments
+    from aslint.fortran.check_source import ParserMsg
     from aslint.logger import logger
 
-    args = ['bibc/supervis/aster_module.c', 'bibfor/utilifor/ibmain.F90']
+    fname = tempfile.NamedTemporaryFile(suffix='.F90').name
+    with open(fname, 'w') as fort:
+        fort.write(SNIPPET_PARSER_ERROR)
+
+    args = ['bibc/supervis/indik8.c', 'bibfor/utilifor/ibmain.F90', fname]
     args = [osp.join(CODEASTER_SRC, i) for i in args]
     filtered_args = filter_arguments(args, status='M')
     assert_that(filtered_args, has_key('c'))
     assert_that(filtered_args['c'], has_length(1))
     assert_that(filtered_args, has_key('for'))
-    assert_that(filtered_args['for'], has_length(1))
+    assert_that(filtered_args['for'], has_length(2))
 
     wafc4che = osp.join(CODEASTER_SRC, 'build', 'std',
                         'c4che', 'release_cache.py')
@@ -84,6 +103,16 @@ def test_check_files():
         os.chdir(prev)
     logger.info(report.to_text())
 
+    assert_that(report, has_key(fname))
+    parser_error = [i for i in report[fname] if isinstance(i, ParserMsg)]
+    assert_that(parser_error, has_length(1))
+
+
+def test_check_messages():
+    # useful to increase coverage without an installation directory
+    from aslint.check_global import check_messages
+    check_messages(CODEASTER_SRC)
+
 
 if __name__ == "__main__":
     import sys
diff --git a/share/test/aslint/test_fortran_code.py b/share/test/aslint/test_fortran_code.py
index 56d312aee6253e438c29478c758bc1a7d1015720..d0a318980dd6f3911520ac8436b66bd3ff054ba7 100644
--- a/share/test/aslint/test_fortran_code.py
+++ b/share/test/aslint/test_fortran_code.py
@@ -647,6 +647,15 @@ def test_long_assign():
     lines = src.code_text().splitlines()
     assert len(lines) == 5, lines
 
+def test_parser_error():
+    """parser error"""
+    src = FC_source80(os.linesep.join([
+        "if (cond.eq.1)",
+        "   continue",
+        "endif"
+    ]), init_level=3)
+    assert_that(calling(src.code_text), raises(FC.FortranParserError))
+
 
 if __name__ == "__main__":
     import sys
diff --git a/share/test/hgaster/test_hooks.py b/share/test/hgaster/test_hooks.py
index a2833cc1752e6f07d83318568b0db1c3c2114600..53d6c6ee8d637a2d21ecc985b6c7bae90695c04f 100644
--- a/share/test/hgaster/test_hooks.py
+++ b/share/test/hgaster/test_hooks.py
@@ -209,7 +209,7 @@ def test_single_head():
         FakeCset(0, branch='default'),
         FakeCset(1, branch='edf/user', head=True),
     ])
-    assert_that(single_head_per_branch(ui, repo, 1,
+    assert_that(single_head_per_branch(ui, repo, repo[1],
                                        hooktype='pretxnchangegroup'),
                 equal_to(OK))
 
@@ -218,7 +218,7 @@ def test_single_head():
         FakeCset(1, branch='edf/user', head=True),
         FakeCset(2, branch='edf/user', head=True),
     ])
-    assert_that(single_head_per_branch(ui, repo, 1,
+    assert_that(single_head_per_branch(ui, repo, repo[1],
                                        hooktype='pretxnchangegroup'),
                 equal_to(NOOK))