merge with i18n stable
authorMatt Mackall <mpm@selenic.com>
Mon, 07 Mar 2011 15:46:28 -0600
branchstable
changeset 13557 7509e36eed3b
parent 13553 dea6efdd7ec4 (diff)
parent 13556 2cefee00a5b9 (current diff)
child 13558 f854b775c386
child 13559 42a34c0aeddc
merge with i18n
--- a/hgext/hgcia.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/hgext/hgcia.py	Mon Mar 07 15:46:28 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/hgext/mq.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/hgext/mq.py	Mon Mar 07 15:46:28 2011 -0600
@@ -2921,8 +2921,9 @@
 
         def abort_if_wdir_patched(self, errmsg, force=False):
             if self.mq.applied and not force:
-                parent = self.dirstate.parents()[0]
-                if parent in [s.node for s in self.mq.applied]:
+                parents = self.dirstate.parents()
+                patches = [s.node for s in self.mq.applied]
+                if parents[0] in patches or parents[1] in patches:
                     raise util.Abort(errmsg)
 
         def commit(self, text="", user=None, date=None, match=None,
--- a/mercurial/cmdutil.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/cmdutil.py	Mon Mar 07 15:46:28 2011 -0600
@@ -261,6 +261,8 @@
     return ret
 
 def match(repo, pats=[], opts={}, globbed=False, default='relpath'):
+    if pats == ("",):
+        pats = []
     if not globbed and default == 'relpath':
         pats = expandpats(pats or [])
     m = matchmod.match(repo.root, repo.getcwd(), pats,
--- a/mercurial/context.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/context.py	Mon Mar 07 15:46:28 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/localrepo.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/localrepo.py	Mon Mar 07 15:46:28 2011 -0600
@@ -763,7 +763,7 @@
         self._branchcachetip = None
 
     def invalidate(self):
-        for a in ("changelog", "manifest", "_bookmarks", "_bookmarkscurrent"):
+        for a in ("changelog", "manifest", "_bookmarks", "_bookmarkcurrent"):
             if a in self.__dict__:
                 delattr(self, a)
         self.invalidatecaches()
@@ -976,7 +976,7 @@
             for f in changes[0]:
                 if f in ms and ms[f] == 'u':
                     raise util.Abort(_("unresolved merge conflicts "
-                                                    "(see hg resolve)"))
+                                       "(see hg help resolve)"))
 
             cctx = context.workingctx(self, text, user, date, extra, changes)
             if editor:
--- a/mercurial/merge.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/merge.py	Mon Mar 07 15:46:28 2011 -0600
@@ -74,7 +74,10 @@
         fco = octx[ofile]
         fca = self._repo.filectx(afile, fileid=anode)
         r = filemerge.filemerge(self._repo, self._local, lfile, fcd, fco, fca)
-        if not r:
+        if r is None:
+            # no real conflict
+            del self._state[dfile]
+        elif not r:
             self.mark(dfile, 'r')
         return r
 
@@ -537,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)
@@ -546,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	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/subrepo.py	Mon Mar 07 15:46:28 2011 -0600
@@ -625,7 +625,8 @@
     def get(self, state, overwrite=False):
         if overwrite:
             self._svncommand(['revert', '--recursive'])
-        status = self._svncommand(['checkout', state[0], '--revision', state[1]])
+        status = self._svncommand(['checkout', '--force', state[0],
+                                   '--revision', state[1]])
         if not re.search('Checked out revision [0-9]+.', status):
             raise util.Abort(status.splitlines()[-1])
         self._ui.status(status)
@@ -702,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'])
 
@@ -758,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():
             self._ui.status(_('cloning subrepo %s\n') % self._relpath)
             self._gitnodir(['clone', self._abssource(source), self._abspath])
         if self._githavelocally(revision):
@@ -771,6 +775,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
@@ -859,6 +865,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:
@@ -895,6 +903,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:
@@ -928,6 +938,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)
@@ -971,6 +983,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/mercurial/templates/gitweb/filelog.tmpl	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/templates/gitweb/filelog.tmpl	Mon Mar 07 15:46:28 2011 -0600
@@ -22,7 +22,7 @@
 revisions |
 <a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a> |
 <a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a> |
-<a href="{url}rss-log/{node|short}/{file|urlescape}">rss</a> |
+<a href="{url}rss-log/tip/{file|urlescape}">rss</a> |
 <a href="{url}help{sessionvars%urlparameter}">help</a>
 <br/>
 {nav%filenav}
--- a/mercurial/templates/monoblue/filelog.tmpl	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/templates/monoblue/filelog.tmpl	Mon Mar 07 15:46:28 2011 -0600
@@ -34,7 +34,7 @@
         <li class="current">revisions</li>
         <li><a href="{url}annotate/{node|short}/{file|urlescape}{sessionvars%urlparameter}">annotate</a></li>
         <li><a href="{url}diff/{node|short}/{file|urlescape}{sessionvars%urlparameter}">diff</a></li>
-        <li><a href="{url}rss-log/{node|short}/{file|urlescape}">rss</a></li>
+        <li><a href="{url}rss-log/tip/{file|urlescape}">rss</a></li>
     </ul>
 
     <h2 class="no-link no-border">{file|urlescape}</h2>
--- a/mercurial/templates/rss/filelogentry.tmpl	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/templates/rss/filelogentry.tmpl	Mon Mar 07 15:46:28 2011 -0600
@@ -1,6 +1,6 @@
 <item>
     <title>{desc|strip|firstline|strip|escape}</title>
-    <link>{urlbase}{url}log{{node|short}}/{file|urlescape}</link>
+    <link>{urlbase}{url}log{node|short}/{file|urlescape}</link>
     <description><![CDATA[{desc|strip|escape|addbreaks|nonempty}]]></description>
     <author>{author|obfuscate}</author>
     <pubDate>{date|rfc822date}</pubDate>
--- a/mercurial/url.py	Sun Mar 06 15:32:37 2011 +0100
+++ b/mercurial/url.py	Mon Mar 07 15:46:28 2011 -0600
@@ -560,9 +560,13 @@
             hostfingerprint = self.ui.config('hostfingerprints', host)
 
             if cacerts and not hostfingerprint:
+                cacerts = util.expandpath(cacerts)
+                if not os.path.exists(cacerts):
+                    raise util.Abort(_('could not find '
+                                       'web.cacerts: %s') % cacerts)
                 self.sock = _ssl_wrap_socket(self.sock, self.key_file,
                     self.cert_file, cert_reqs=CERT_REQUIRED,
-                    ca_certs=util.expandpath(cacerts))
+                    ca_certs=cacerts)
                 msg = _verifycert(self.sock.getpeercert(), host)
                 if msg:
                     raise util.Abort(_('%s certificate error: %s '
--- a/tests/hghave	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/hghave	Mon Mar 07 15:46:28 2011 -0600
@@ -202,7 +202,7 @@
     "outer-repo": (has_outer_repo, "outer repo"),
     "p4": (has_p4, "Perforce server and client"),
     "pygments": (has_pygments, "Pygments source highlighting library"),
-    "ssl": (has_ssl, "python >= 2.6 ssl module"),
+    "ssl": (has_ssl, "python >= 2.6 ssl module and python OpenSSL"),
     "svn": (has_svn, "subversion client and admin tools"),
     "svn-bindings": (has_svn_bindings, "subversion python bindings"),
     "symlink": (has_symlink, "symbolic links"),
--- a/tests/test-commit-unresolved.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-commit-unresolved.t	Mon Mar 07 15:46:28 2011 -0600
@@ -38,7 +38,7 @@
 
   $ echo "ABCD" > A
   $ hg commit -m "Merged"
-  abort: unresolved merge conflicts (see hg resolve)
+  abort: unresolved merge conflicts (see hg help resolve)
   [255]
 
 Mark the conflict as resolved and commit
--- a/tests/test-hgweb-filelog.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-hgweb-filelog.t	Mon Mar 07 15:46:28 2011 -0600
@@ -656,6 +656,84 @@
   </html>
   
 
+rss log
+
+  $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/rss-log/tip/a')
+  200 Script output follows
+  
+  <?xml version="1.0" encoding="ascii"?>
+  <rss version="2.0">
+    <channel>
+      <link>http://*:$HGPORT/</link> (glob)
+      <language>en-us</language>
+  
+      <title>test: a history</title>
+      <description>a revision history</description>
+      <item>
+      <title>second a</title>
+      <link>http://*:$HGPORT/log01de2d66a28d/a</link> (glob)
+      <description><![CDATA[second a]]></description>
+      <author>&#116;&#101;&#115;&#116;</author>
+      <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
+  </item>
+  <item>
+      <title>first a</title>
+      <link>http://*:$HGPORT/log5ed941583260/a</link> (glob)
+      <description><![CDATA[first a]]></description>
+      <author>&#116;&#101;&#115;&#116;</author>
+      <pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
+  </item>
+  
+    </channel>
+  </rss>
+
+atom log
+
+  $ ("$TESTDIR/get-with-headers.py" localhost:$HGPORT '/atom-log/tip/a')
+  200 Script output follows
+  
+  <?xml version="1.0" encoding="ascii"?>
+  <feed xmlns="http://www.w3.org/2005/Atom">
+   <id>http://*:$HGPORT/atom-log/tip/a</id> (glob)
+   <link rel="self" href="http://*:$HGPORT/atom-log/tip/a"/> (glob)
+   <title>test: a history</title>
+   <updated>1970-01-01T00:00:00+00:00</updated>
+  
+   <entry>
+    <title>second a</title>
+    <id>http://*:$HGPORT/#changeset-01de2d66a28df5549090991dccda788726948517</id> (glob)
+    <link href="http://*:$HGPORT/rev/01de2d66a28d"/> (glob)
+    <author>
+     <name>test</name>
+     <email>&#116;&#101;&#115;&#116;</email>
+    </author>
+    <updated>1970-01-01T00:00:00+00:00</updated>
+    <published>1970-01-01T00:00:00+00:00</published>
+    <content type="xhtml">
+     <div xmlns="http://www.w3.org/1999/xhtml">
+      <pre xml:space="preserve">second a</pre>
+     </div>
+    </content>
+   </entry>
+   <entry>
+    <title>first a</title>
+    <id>http://*:$HGPORT/#changeset-5ed941583260248620985524192fdc382ef57c36</id> (glob)
+    <link href="http://*:$HGPORT/rev/5ed941583260"/> (glob)
+    <author>
+     <name>test</name>
+     <email>&#116;&#101;&#115;&#116;</email>
+    </author>
+    <updated>1970-01-01T00:00:00+00:00</updated>
+    <published>1970-01-01T00:00:00+00:00</published>
+    <content type="xhtml">
+     <div xmlns="http://www.w3.org/1999/xhtml">
+      <pre xml:space="preserve">first a</pre>
+     </div>
+    </content>
+   </entry>
+  
+  </feed>
+
 errors
 
   $ cat errors.log
--- a/tests/test-https.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-https.t	Mon Mar 07 15:46:28 2011 -0600
@@ -96,6 +96,12 @@
   $ hg serve -p $HGPORT -d --pid-file=../hg0.pid --certificate=$PRIV
   $ cat ../hg0.pid >> $DAEMON_PIDS
 
+cacert not found
+
+  $ hg in --config web.cacerts=no-such.pem https://localhost:$HGPORT/
+  abort: could not find web.cacerts: no-such.pem
+  [255]
+
 Test server address cannot be reused
 
   $ hg serve -p $HGPORT --certificate=$PRIV 2>&1
--- a/tests/test-issue619.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-issue619.t	Mon Mar 07 15:46:28 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-mq-merge.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-mq-merge.t	Mon Mar 07 15:46:28 2011 -0600
@@ -1,3 +1,32 @@
+Setup extension:
+
+  $ echo "[extensions]" >> $HGRCPATH
+  $ echo "mq =" >> $HGRCPATH
+  $ echo "[mq]" >> $HGRCPATH
+  $ echo "git = keep" >> $HGRCPATH
+
+Test merge with mq changeset as the second parent:
+
+  $ hg init m
+  $ cd m
+  $ touch a b c
+  $ hg add a
+  $ hg commit -m a
+  $ hg add b
+  $ hg qnew -d "0 0" b
+  $ hg update 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ hg add c
+  $ hg commit -m c
+  created new head
+  $ hg merge
+  1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  (branch merge, don't forget to commit)
+  $ hg commit -m merge
+  abort: cannot commit over an applied mq patch
+  [255]
+  $ cd ..
+
 Issue529: mq aborts when merging patch deleting files
 
   $ checkundo()
@@ -7,11 +36,6 @@
   >     fi
   > }
 
-  $ echo "[extensions]" >> $HGRCPATH
-  $ echo "mq =" >> $HGRCPATH
-  $ echo "[mq]" >> $HGRCPATH
-  $ echo "git = keep" >> $HGRCPATH
-
 Commit two dummy files in "init" changeset:
 
   $ hg init t
--- a/tests/test-newbranch.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-newbranch.t	Mon Mar 07 15:46:28 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	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-push-warn.t	Mon Mar 07 15:46:28 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-rebase-conflicts.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-rebase-conflicts.t	Mon Mar 07 15:46:28 2011 -0600
@@ -65,7 +65,7 @@
 Try to continue without solving the conflict:
 
   $ hg rebase --continue 
-  abort: unresolved merge conflicts (see hg resolve)
+  abort: unresolved merge conflicts (see hg help resolve)
   [255]
 
 Conclude rebase:
--- a/tests/test-subrepo-git.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-subrepo-git.t	Mon Mar 07 15:46:28 2011 -0600
@@ -314,6 +314,26 @@
   cloning subrepo s
   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
--- a/tests/test-subrepo-svn.t	Sun Mar 06 15:32:37 2011 +0100
+++ b/tests/test-subrepo-svn.t	Mon Mar 07 15:46:28 2011 -0600
@@ -438,3 +438,60 @@
   $ svnversion
   2
   $ cd ..
+
+Test case where subversion would fail to update the subrepo because there
+are unknown directories being replaced by tracked ones (happens with rebase).
+
+  $ cd $WCROOT/src
+  $ mkdir dir
+  $ echo epsilon.py > dir/epsilon.py
+  $ svn add dir
+  A         dir
+  A         dir/epsilon.py
+  $ svn ci -m 'Add dir/epsilon.py'
+  Adding         src/dir
+  Adding         src/dir/epsilon.py
+  Transmitting file data .
+  Committed revision 6.
+  $ cd ../..
+  $ hg init rebaserepo
+  $ cd rebaserepo
+  $ svn co -r5 --quiet "$SVNREPO"/src s
+  $ echo "s =        [svn]       $SVNREPO/src" >> .hgsub
+  $ hg add .hgsub
+  $ hg ci -m addsub
+  committing subrepository s
+  $ echo a > a
+  $ hg ci -Am adda
+  adding a
+  $ hg up 0
+  0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+  $ svn up -r6 s
+  A    s/dir
+  A    s/dir/epsilon.py
+  
+  Fetching external item into 's/externals'
+  Updated external to revision 1.
+  
+  Updated to revision 6.
+  $ hg ci -m updatesub
+  committing subrepository s
+  created new head
+  $ echo pyc > s/dir/epsilon.pyc
+  $ hg up 1
+  D    $TESTTMP/rebaserepo/s/dir
+  
+  Fetching external item into '$TESTTMP/rebaserepo/s/externals'
+  Checked out external at revision 1.
+  
+  Checked out revision 5.
+  2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+  $ hg up 2
+  E    $TESTTMP/rebaserepo/s/dir
+  A    $TESTTMP/rebaserepo/s/dir/epsilon.py
+  
+  Fetching external item into '$TESTTMP/rebaserepo/s/externals'
+  Checked out external at revision 1.
+  
+  Checked out revision 6.
+  1 files updated, 0 files merged, 1 files removed, 0 files unresolved