Martin Geisler avatar Martin Geisler committed 5579cb5

Support checking only heads.

Comments (0)

Files changed (3)

     return chash(manifest, files, desc, p1, p2, user, date, extra)
 
 
-def verifysigs(ui, repo, *revrange):
+def verifysigs(ui, repo, *revrange, **opts):
     """verify manifest signatures
 
-    Verify the revision range specified or all changesets. The return
-    code is one of:
+    Verify repository heads, the revision range specified or all
+    changesets. The return code is one of:
 
     - 0 if all changesets had valid signatures
     - 1 if there were a changeset without a signature
 
     The final return code is the highest of the above.
     """
-    if not revrange:
+    if opts.get('only_heads'):
+        revs = repo.heads()
+    elif not revrange:
         revs = xrange(len(repo))
     else:
         revs = cmdutil.revrange(repo, revrange)
     return retcode
 
 
-def hook(ui, repo, node, **kwargs):
+def verifyallhook(ui, repo, node, **kwargs):
     """verify changeset signatures
 
     This hook is suitable for use as a ``pretxnchangegroup`` hook. It
     if verifysigs(ui, repo, "%s:" % node) > 0:
         raise error.Abort(_("could not verify all new changesets"))
 
+def verifyheadshook(ui, repo, node, **kwargs):
+    """verify signatures in repository heads
+
+    This hook is suitable for use as a ``pretxnchangegroup`` hook. It
+    will verify that all heads carry a good signature after push. If
+    one or more changesets lack a good signature, the push is aborted.
+    """
+    ctx = repo[node]
+    if verifysigs(ui, repo, True, "%s:" % node, only_heads=True) > 0:
+        raise error.Abort(_("could not verify all new changesets"))
+
 sigschemes = {'gnupg': (gnupgsign, gnupgverify),
               'openssl': (opensslsign, opensslverify)}
 
     extensions.wrapfunction(changelog.changelog, 'add', add)
 
 cmdtable = {
-    "verifysigs": (verifysigs, [], "[REV...]")
+    "verifysigs": (verifysigs,
+                   [('', 'only-heads', None, _('only verify heads'))], 
+                   "[REV...]")
 }

tests/test-commitsigs

     echo "% hg verifysigs (exit code: $?)"
     sed 's|:[0-9a-f]\+:|:XXXXXXXXXXXX:|' < output
     rm output
+
+    hg verifysigs --only-heads > output
+    echo "% hg verifysigs --only-heads (exit code: $?)"
+    sed 's|:[0-9a-f]\+:|:XXXXXXXXXXXX:|' < output
+    rm output
 }
 
 hg init repo
 
 cat >> .hg/hgrc <<EOF
 [hooks]
-pretxncommit = python:$TESTDIR/../commitsigs.py:hook
-pretxnchangegroup = python:$TESTDIR/../commitsigs.py:hook
+pretxncommit = python:$TESTDIR/../commitsigs.py:verifyheadshook
+pretxnchangegroup = python:$TESTDIR/../commitsigs.py:verifyallhook
 EOF
 
 echo "% commit with pretxncommit hook"

tests/test-commitsigs.out

 % Commit with no signature
 % hg verifysigs (exit code: 1)
 0:XXXXXXXXXXXX: ** no signature
+% hg verifysigs --only-heads (exit code: 1)
+0:XXXXXXXXXXXX: ** no signature
 % Commit with GnuPG signature
 % hg verifysigs (exit code: 1)
 0:XXXXXXXXXXXX: ** no signature
 1:XXXXXXXXXXXX: good gnupg signature
+% hg verifysigs --only-heads (exit code: 0)
+1:XXXXXXXXXXXX: good gnupg signature
 % Commit with OpenSSL signature
 % hg verifysigs (exit code: 1)
 0:XXXXXXXXXXXX: ** no signature
 1:XXXXXXXXXXXX: good gnupg signature
 2:XXXXXXXXXXXX: good openssl signature
+% hg verifysigs --only-heads (exit code: 0)
+2:XXXXXXXXXXXX: good openssl signature
 % commit with pretxncommit hook
 3:XXXXXXXXXXXX: ** no signature
 error: pretxncommit hook failed: could not verify all new changesets
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.