Bug 1274693 - Upgrade robustcheckout extension to require --revision be a revision; r?jlund draft
authorGregory Szorc <gps@mozilla.com>
Fri, 20 May 2016 14:58:56 -0700
changeset 369238 21cd8e1a034e223c962167fd3f1e5434691cbbda
parent 369237 30b83fcb0009b524cf3982a8aeb2bc0fc6d2d5b7
child 521523 8b4bda598462a947280bfa30164fa8475fdb0819
push id18806
push userbmo:gps@mozilla.com
push dateFri, 20 May 2016 21:59:07 +0000
reviewersjlund
bugs1274693, 1274095
milestone49.0a1
Bug 1274693 - Upgrade robustcheckout extension to require --revision be a revision; r?jlund This is a straight import of version-control-tools:hgext/robustcheckout/__init__.py at d115bc9578dac4ae2694ea93bb9662de9e6b0b67. Code was reviewed in bug 1274095. Should be a rubber stamp review. MozReview-Commit-ID: CEXR9uCHBfI
testing/mozharness/external_tools/robustcheckout.py
--- a/testing/mozharness/external_tools/robustcheckout.py
+++ b/testing/mozharness/external_tools/robustcheckout.py
@@ -122,16 +122,22 @@ def robustcheckout(ui, url, dest, upstre
                    purge=False, sharebase=None):
     """Ensure a working copy has the specified revision checked out."""
     if not revision and not branch:
         raise error.Abort('must specify one of --revision or --branch')
 
     if revision and branch:
         raise error.Abort('cannot specify both --revision and --branch')
 
+    # Require revision to look like a SHA-1.
+    if revision:
+        if len(revision) < 12 or len(revision) > 40 or not re.match('^[a-f0-9]+$', revision):
+            raise error.Abort('--revision must be a SHA-1 fragment 12-40 '
+                              'characters long')
+
     sharebase = sharebase or ui.config('share', 'pool')
     if not sharebase:
         raise error.Abort('share base directory not defined; refusing to operate',
                           hint='define share.pool config option or pass --sharebase')
 
     # worker.backgroundclose only makes things faster if running anti-virus,
     # which our automation doesn't. Disable it.
     ui.setconfig('worker', 'backgroundclose', False)
@@ -236,23 +242,29 @@ def _docheckout(ui, url, dest, upstream,
             raise error.Abort('clone did not create a shared repo')
 
         created = True
 
     # The destination .hg directory should exist. Now make sure we have the
     # wanted revision.
 
     repo = hg.repository(ui, dest)
+
+    # We only pull if we are using symbolic names or the requested revision
+    # doesn't exist.
     havewantedrev = False
-    if revision:
-        havewantedrev = revision in repo
-    else:
-        assert branch
-        # Branch names are not constant over time, so always pull to
-        # ensure we have the latest revision.
+    if revision and revision in repo:
+        ctx = repo[revision]
+
+        if not ctx.hex().startswith(revision):
+            raise error.Abort('--revision argument is ambiguous',
+                              hint='must be the first 12+ characters of a '
+                                   'SHA-1 fragment')
+
+        havewantedrev = True
 
     if not havewantedrev:
         ui.write('(pulling to obtain %s)\n' % (revision or branch,))
 
         try:
             remote = hg.peer(repo, {}, url)
             pullrevs = [remote.lookup(revision or branch)]
             pullop = exchange.pull(repo, remote, heads=pullrevs)