Fixed a bug in changeset id parsing
authorJan Vrany <jan.vrany@fit.cvut.cz>
Wed, 13 Jul 2016 18:29:10 +0100
changeset 688 c3cb04bed338
parent 687 744539f5b8c7
child 713 f0ba1bb1106d
Fixed a bug in changeset id parsing The changeset id parsing logic can parse both, revision numbers and changeset id (hashes). It may happen, however, that a short id (12 chars) may consist of digits only (like "087537207973"). In that case it considered it being a revno which lead to an error. This is hard to disambiguate without querying the repo. However, it seems more appropriate to treat it as id when the maybe-revno is 12 digits and more in length. If it would be a revno, then the repo would contain at least 10^11 revisions.
mercurial/HGChangesetId.st
mercurial/HGCommitTask.st
mercurial/HGRepositoriesResource.st
mercurial/HGStXTests.st
mercurial/HGTests.st
--- a/mercurial/HGChangesetId.st	Mon Jun 27 12:00:16 2016 +0100
+++ b/mercurial/HGChangesetId.st	Wed Jul 13 18:29:10 2016 +0100
@@ -138,10 +138,11 @@
     "Parses node id from stream and returns it. Support both,
      short and full node ids"
 
-    | stream c c1 c2 sign revno hash hashPos short |
+    | stream c c1 c2 sign revno hash hashPos charPos short |
 
     hash := ByteArray new: 20.
     hashPos := 1.
+    charPos := 0.
     short := true.
     revno := 0.
 
@@ -168,9 +169,22 @@
             c1 := c2 := nil.
         ].
         stream next.
+        charPos := charPos + 1.
     ].
     revno := revno * sign.
-    (stream atEnd or:[stream peek isSeparator]) ifTrue:[
+    stream atEnd ifTrue:[
+        "/ We might have read revno or a short hash that by chance
+        "/ consist of only digits and not leading with 0. In this case
+        "/ we actually cannot distinguish. 
+        "/ In case we have read less than 12 characters (size of a short id), 
+        "/ treat it as revno. A conservative guess...
+        charPos < 12 ifTrue:[ 
+            ^(HGChangesetId new: 0)
+                revno: revno;
+                yourself
+        ]
+    ].
+    (stream atEnd not and:[stream peek isSeparator]) ifTrue:[
         ^(HGChangesetId new: 0)
             revno: revno;
             yourself
@@ -257,7 +271,7 @@
     "
 
     "Created: / 13-11-2012 / 16:49:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 22-01-2013 / 12:00:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-07-2016 / 18:15:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !HGChangesetId class methodsFor:'accessing'!
--- a/mercurial/HGCommitTask.st	Mon Jun 27 12:00:16 2016 +0100
+++ b/mercurial/HGCommitTask.st	Wed Jul 13 18:29:10 2016 +0100
@@ -185,8 +185,10 @@
             ].
             "/ If working copy us not shared or when using Mercurial < 3.3 (which does not support
             "/ sharing of bookmarks), also set the bookmark on package working copy.
-            (wc repository isShared not or:[ HGCommand hgVersionIsGreaterOrEqualThan_3_3 not]) ifTrue:[ 
-                repository bookmark: wc changesetId as: bookmark. 
+            bookmark notNil ifTrue:[
+                (wc repository isShared not or:[ HGCommand hgVersionIsGreaterOrEqualThan_3_3 not]) ifTrue:[ 
+                    repository bookmark: wc changesetId as: bookmark. 
+                ].
             ].
 
             remote notNil ifTrue:[
--- a/mercurial/HGRepositoriesResource.st	Mon Jun 27 12:00:16 2016 +0100
+++ b/mercurial/HGRepositoriesResource.st	Wed Jul 13 18:29:10 2016 +0100
@@ -259,12 +259,12 @@
 
 initialize
 
-    HGRepositoriesArchiveDir := (Smalltalk packageDirectoryForPackageId:self package)
+    HGRepositoriesArchiveDir := (Smalltalk getPackageDirectoryForPackage:self package)
                     / 'tests' / 'repositories'
 
     "Created: / 09-12-2010 / 23:07:08 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified (format): / 27-12-2011 / 18:07:34 / dundee"
-    "Modified: / 17-10-2012 / 13:02:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-07-2016 / 17:54:01 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !HGRepositoriesResource methodsFor:'accessing'!
--- a/mercurial/HGStXTests.st	Mon Jun 27 12:00:16 2016 +0100
+++ b/mercurial/HGStXTests.st	Wed Jul 13 18:29:10 2016 +0100
@@ -2388,13 +2388,13 @@
     "/ build.xml
     "/ build.auto.xml
     "/ .hgignore
-    self assert: (changeset changes select:[:change | change isAdded ]) size == 4.
+    self assert: (changeset changes select:[:change | change isAdded ]) size == 5.
 
 
     self assert: (changeset / 'java' / 'src' / 'mocks' / 'hg' / 'p5' / 'Foo.java' ) notNil.
 
     "Created: / 04-08-2014 / 01:42:13 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (format): / 20-01-2015 / 11:36:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-07-2016 / 20:39:40 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 test_commit_java_01b
@@ -2446,12 +2446,12 @@
     "/ build.xml
     "/ build.auto.xml
     "/ .hgignore      
-    self assert: (changeset changes select:[:change | change isAdded ]) size == 4.
+    self assert: (changeset changes select:[:change | change isAdded ]) size == 5.
 
     self assert: (changeset / 'java' / 'src' / 'mocks' / 'hg' / 'p5' / 'Foo.java' ) notNil.
 
     "Created: / 04-08-2014 / 01:43:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 20-01-2015 / 11:36:30 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-07-2016 / 20:39:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 test_commit_java_01c
--- a/mercurial/HGTests.st	Mon Jun 27 12:00:16 2016 +0100
+++ b/mercurial/HGTests.st	Wed Jul 13 18:29:10 2016 +0100
@@ -1532,16 +1532,21 @@
 
     "/Only hash
     id := HGChangesetId fromString:'6f88e1f44d9eb86e0b56ca15e30e5d786acd83c7'.
-    self assert: id revno = nil. "/meaning - unknown.
+    self assert: id revno isNil. "/meaning - unknown.
     self assert: id asByteArray = #[111 136 225 244 77 158 184 110 11 86 202 21 227 14 93 120 106 205 131 199].
 
     "/Only short hash
     id := HGChangesetId fromString:'6f88e1f44d9e'.
-    self assert: id revno = nil. "/meaning - unknown.
-    self assert: id asByteArray = #[111 136 225 244 77 158]
+    self assert: id revno isNil. "/meaning - unknown.
+    self assert: id asByteArray = #[111 136 225 244 77 158].
+
+    "/Short hash that looks like a revno only
+    id := HGChangesetId fromString:'087537207973'.
+    self assert: id revno isNil. "/meaning - unknown.
+    self assert: id asByteArray = #[16r08 16r75 16r37 16r20 16r79 16r73].
 
     "Created: / 16-11-2012 / 21:27:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 22-01-2013 / 12:31:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 13-07-2016 / 17:54:52 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 test_nodeid_02