merge with stable
authorMatt Mackall <mpm@selenic.com>
Mon, 07 Mar 2011 15:46:46 -0600
changeset 13558 f854b775c386
parent 13555 970150ddaaf8 (current diff)
parent 13557 7509e36eed3b (diff)
child 13560 a2734c8322ac
merge with stable
mercurial/subrepo.py
tests/test-subrepo-git.t
--- a/hgext/hgcia.py	Mon Mar 07 15:37:11 2011 +0800
+++ b/hgext/hgcia.py	Mon Mar 07 15:46:46 2011 -0600
@@ -198,7 +198,7 @@
     def sendrpc(self, msg):
         srv = xmlrpclib.Server(self.ciaurl)
         res = srv.hub.deliver(msg)
-        if res is not True:
+        if res is not True and res != 'queued.':
             raise util.Abort(_('%s returned an error: %s') %
                              (self.ciaurl, res))
 
--- a/i18n/de.po	Mon Mar 07 15:37:11 2011 +0800
+++ b/i18n/de.po	Mon Mar 07 15:46:46 2011 -0600
@@ -11774,7 +11774,7 @@
 msgstr ""
 
 msgid "show only branches that have unmerged heads"
-msgstr "Zeigt nur Branches mit mehreren Köpfen"
+msgstr "Zeigt nur Branches deren Köpfe nicht zusammengeführt wurden"
 
 msgid "show normal and closed branches"
 msgstr "Zeigt normale und geschlossene Branches"
--- a/mercurial/context.py	Mon Mar 07 15:37:11 2011 +0800
+++ b/mercurial/context.py	Mon Mar 07 15:46:46 2011 -0600
@@ -466,39 +466,40 @@
         else:
             base = self
 
-        # find all ancestors
+        # This algorithm would prefer to be recursive, but Python is a
+        # bit recursion-hostile. Instead we do an iterative
+        # depth-first search.
+
+        visit = [base]
+        hist = {}
+        pcache = {}
         needed = {base: 1}
-        visit = [base]
-        files = [base._path]
         while visit:
-            f = visit.pop(0)
-            for p in parents(f):
-                if p not in needed:
-                    needed[p] = 1
-                    visit.append(p)
-                    if p._path not in files:
-                        files.append(p._path)
-                else:
-                    # count how many times we'll use this
-                    needed[p] += 1
+            f = visit[-1]
+            if f not in pcache:
+                pcache[f] = parents(f)
 
-        # sort by revision (per file) which is a topological order
-        visit = []
-        for f in files:
-            visit.extend(n for n in needed if n._path == f)
+            ready = True
+            pl = pcache[f]
+            for p in pl:
+                if p not in hist:
+                    ready = False
+                    visit.append(p)
+                    needed[p] = needed.get(p, 0) + 1
+            if ready:
+                visit.pop()
+                curr = decorate(f.data(), f)
+                for p in pl:
+                    curr = pair(hist[p], curr)
+                    if needed[p] == 1:
+                        del hist[p]
+                    else:
+                        needed[p] -= 1
 
-        hist = {}
-        for f in sorted(visit, key=lambda x: x.rev()):
-            curr = decorate(f.data(), f)
-            for p in parents(f):
-                curr = pair(hist[p], curr)
-                # trim the history of unneeded revs
-                needed[p] -= 1
-                if not needed[p]:
-                    del hist[p]
-            hist[f] = curr
+                hist[f] = curr
+                pcache[f] = []
 
-        return zip(hist[f][0], hist[f][1].splitlines(True))
+        return zip(hist[base][0], hist[base][1].splitlines(True))
 
     def ancestor(self, fc2, actx=None):
         """
--- a/mercurial/merge.py	Mon Mar 07 15:37:11 2011 +0800
+++ b/mercurial/merge.py	Mon Mar 07 15:46:46 2011 -0600
@@ -540,7 +540,7 @@
         action += manifestmerge(repo, wc, p2, pa, overwrite, partial)
 
         ### apply phase
-        if not branchmerge or fastforward: # just jump to the new rev
+        if not branchmerge: # just jump to the new rev
             fp1, fp2, xp1, xp2 = fp2, nullid, xp2, ''
         if not partial:
             repo.hook('preupdate', throw=True, parent1=xp1, parent2=xp2)
@@ -549,7 +549,7 @@
 
         if not partial:
             repo.dirstate.setparents(fp1, fp2)
-            recordupdates(repo, action, branchmerge and not fastforward)
+            recordupdates(repo, action, branchmerge)
             if not branchmerge and not fastforward:
                 repo.dirstate.setbranch(p2.branch())
     finally:
--- a/mercurial/subrepo.py	Mon Mar 07 15:37:11 2011 +0800
+++ b/mercurial/subrepo.py	Mon Mar 07 15:46:46 2011 -0600
@@ -703,6 +703,9 @@
 
         return retdata, p.returncode
 
+    def _gitmissing(self):
+        return not os.path.exists(os.path.join(self._abspath, '.git'))
+
     def _gitstate(self):
         return self._gitcommand(['rev-parse', 'HEAD'])
 
@@ -759,7 +762,7 @@
         return _abssource(self)
 
     def _fetch(self, source, revision):
-        if not os.path.exists(os.path.join(self._abspath, '.git')):
+        if self._gitmissing():
             source = self._abssource(source)
             self._ui.status(_('cloning subrepo %s from %s\n') %
                             (self._relpath, source))
@@ -774,6 +777,8 @@
                                (revision, self._relpath))
 
     def dirty(self, ignoreupdate=False):
+        if self._gitmissing():
+            return True
         if not ignoreupdate and self._state[1] != self._gitstate():
             # different version checked out
             return True
@@ -862,6 +867,8 @@
             rawcheckout()
 
     def commit(self, text, user, date):
+        if self._gitmissing():
+            raise util.Abort(_("subrepo %s is missing") % self._relpath)
         cmd = ['commit', '-a', '-m', text]
         env = os.environ.copy()
         if user:
@@ -898,6 +905,8 @@
             mergefunc()
 
     def push(self, force):
+        if self._gitmissing():
+            raise util.Abort(_("subrepo %s is missing") % self._relpath)
         # if a branch in origin contains the revision, nothing to do
         branch2rev, rev2branch = self._gitbranchmap()
         if self._state[1] in rev2branch:
@@ -931,6 +940,8 @@
             return False
 
     def remove(self):
+        if self._gitmissing():
+            return
         if self.dirty():
             self._ui.warn(_('not removing repo %s because '
                             'it has changes.\n') % self._relpath)
@@ -974,6 +985,9 @@
 
 
     def status(self, rev2, **opts):
+        if self._gitmissing():
+            # if the repo is missing, return no results
+            return [], [], [], [], [], [], []
         rev1 = self._state[1]
         modified, added, removed = [], [], []
         if rev2:
--- a/tests/test-issue619.t	Mon Mar 07 15:37:11 2011 +0800
+++ b/tests/test-issue619.t	Mon Mar 07 15:46:46 2011 -0600
@@ -19,12 +19,7 @@
   $ hg merge b
   1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   (branch merge, don't forget to commit)
-  $ hg branch
-  default
-  $ hg parent --template '{rev}:{node|short} {branches}: {desc}\n'
-  1:06c2121185be b: b
   $ hg ci -Ammerge
-  created new head
 
 Bogus fast-forward should fail:
 
--- a/tests/test-newbranch.t	Mon Mar 07 15:37:11 2011 +0800
+++ b/tests/test-newbranch.t	Mon Mar 07 15:46:46 2011 -0600
@@ -209,11 +209,12 @@
   $ hg branch
   foo
   $ hg commit -m'Merge ff into foo'
-  created new head
   $ hg parents
-  changeset:   6:6af8030670c9
+  changeset:   6:917eb54e1b4b
   branch:      foo
   tag:         tip
+  parent:      4:98d14f698afe
+  parent:      5:6683a60370cb
   user:        test
   date:        Thu Jan 01 00:00:00 1970 +0000
   summary:     Merge ff into foo
--- a/tests/test-push-warn.t	Mon Mar 07 15:37:11 2011 +0800
+++ b/tests/test-push-warn.t	Mon Mar 07 15:46:46 2011 -0600
@@ -413,7 +413,6 @@
   (branch merge, don't forget to commit)
 
   $ hg -R k ci -m merge
-  created new head
 
   $ hg -R k push -r a j
   pushing to j
--- a/tests/test-subrepo-git.t	Mon Mar 07 15:37:11 2011 +0800
+++ b/tests/test-subrepo-git.t	Mon Mar 07 15:46:46 2011 -0600
@@ -314,6 +314,26 @@
   cloning subrepo s from $TESTTMP/gitroot
   3 files updated, 0 files merged, 0 files removed, 0 files unresolved
 
+Don't crash if the subrepo is missing
+
+  $ hg clone t missing -q
+  $ cd missing
+  $ rm -rf s
+  $ hg status -S
+  $ hg sum | grep commit
+  commit: 1 subrepos
+  $ hg push -q
+  abort: subrepo s is missing
+  [255]
+  $ hg commit -qm missing
+  abort: subrepo s is missing
+  [255]
+  $ hg update -C
+  cloning subrepo s
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg sum | grep commit
+  commit: (clean)
+
 Check hg update --clean
   $ cd $TESTTMP/ta
   $ echo  > s/g