--- 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>test</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>test</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>test</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>test</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