changeset 13287:d0e0d3d43e14 stable

subrepo: compare svn subrepo state to last committed revision A subversion project revisions are a subset of the repository revisions, you can ask subversion to update a working directory from one revision to another without changing anything. Unfortunately, Mercurial will think the subrepository has changed and will commit it again. To avoid useless commits, we compare the subrepository state to its actual "parent" revision. To ensure ascending compatibility with existing subrepositories which might reference fake revisions, we also keep comparing with the subrepo working directory revision. NOTE: not sure if this should go in stable or not.
author Patrick Mezard <pmezard@gmail.com>
date Sat, 22 Jan 2011 16:15:40 +0100
parents 2ef915184ff2
children 9c3bfba3f48d 035684c6b69a
files mercurial/subrepo.py tests/test-subrepo-svn.t
diffstat 2 files changed, 36 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/subrepo.py	Fri Jan 21 14:42:15 2011 -0600
+++ b/mercurial/subrepo.py	Sat Jan 22 16:15:40 2011 +0100
@@ -499,13 +499,23 @@
             raise util.Abort(stderr)
         return stdout
 
-    def _wcrev(self):
+    def _wcrevs(self):
+        # Get the working directory revision as well as the last
+        # commit revision so we can compare the subrepo state with
+        # both. We used to store the working directory one.
         output = self._svncommand(['info', '--xml'])
         doc = xml.dom.minidom.parseString(output)
         entries = doc.getElementsByTagName('entry')
-        if not entries:
-            return '0'
-        return str(entries[0].getAttribute('revision')) or '0'
+        lastrev, rev = '0', '0'
+        if entries:
+            rev = str(entries[0].getAttribute('revision')) or '0'
+            commits = entries[0].getElementsByTagName('commit')
+            if commits:
+                lastrev = str(commits[0].getAttribute('revision')) or '0'
+        return (lastrev, rev)
+
+    def _wcrev(self):
+        return self._wcrevs()[0]
 
     def _wcchanged(self):
         """Return (changes, extchanges) where changes is True
@@ -534,7 +544,7 @@
         return bool(changes), False
 
     def dirty(self):
-        if self._wcrev() == self._state[1] and not self._wcchanged()[0]:
+        if self._state[1] in self._wcrevs() and not self._wcchanged()[0]:
             return False
         return True
 
--- a/tests/test-subrepo-svn.t	Fri Jan 21 14:42:15 2011 -0600
+++ b/tests/test-subrepo-svn.t	Sat Jan 22 16:15:40 2011 +0100
@@ -123,6 +123,25 @@
    source   file://*/svn-repo/src (glob)
    revision 2
 
+add an unrelated revision in svn and update the subrepo to without
+bringing any changes.
+
+  $ svn mkdir --parents "$SVNREPO/unrelated" -m 'create unrelated'
+  
+  Committed revision 4.
+  $ svn up s
+  
+  Fetching external item into 's/externals'
+  External at revision 1.
+  
+  At revision 4.
+  $ hg sum
+  parent: 2:* tip (glob)
+   Message!
+  branch: default
+  commit: (clean)
+  update: (current)
+
   $ echo a > s/a
 
 should be empty despite change to s/a
@@ -139,14 +158,14 @@
   A    externals/other
   Updated external to revision 1.
   
-  Updated to revision 3.
+  Updated to revision 4.
   $ echo xyz >> alpha
   $ svn propset svn:mime-type 'text/xml' alpha
   property 'svn:mime-type' set on 'alpha'
   $ svn ci -m 'amend a from svn'
   Sending        src/alpha
   Transmitting file data .
-  Committed revision 4.
+  Committed revision 5.
   $ cd ../../sub/t
 
 this commit from hg will fail