--- a/hgext/mq.py Sat May 01 15:14:22 2010 -0500
+++ b/hgext/mq.py Sat May 01 15:15:35 2010 -0500
@@ -2357,11 +2357,28 @@
return 0
def strip(ui, repo, rev, **opts):
- """strip a revision and all its descendants from the repository
+ """strip a changeset and all its descendants from the repository
+
+ The strip command removes all changesets whose local revision
+ number is greater than or equal to REV, and then restores any
+ changesets that are not descendants of REV. If the working
+ directory has uncommitted changes, the operation is aborted unless
+ the --force flag is supplied.
- If one of the working directory's parent revisions is stripped, the
- working directory will be updated to the parent of the stripped
- revision.
+ If a parent of the working directory is stripped, then the working
+ directory will automatically be updated to the most recent
+ available ancestor of the stripped parent after the operation
+ completes.
+
+ Any stripped changesets are stored in ``.hg/strip-backup`` as a
+ bundle (see ``hg help bundle`` and ``hg help unbundle``). They can
+ be restored by running ``hg unbundle .hg/strip-backup/BUNDLE``,
+ where BUNDLE is the bundle file created by the strip. Note that
+ the local revision numbers will in general be different after the
+ restore.
+
+ Use the --nobackup option to discard the backup bundle once the
+ operation completes.
"""
backup = 'all'
if opts['backup']:
@@ -2788,14 +2805,17 @@
(series,
[('m', 'missing', None, _('print patches not in series')),
] + seriesopts,
- _('hg qseries [-ms]')),
- "strip":
- (strip,
- [('f', 'force', None, _('force removal with local changes')),
- ('b', 'backup', None, _('bundle unrelated changesets')),
- ('n', 'nobackup', None, _('no backups'))],
- _('hg strip [-f] [-b] [-n] REV')),
- "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
+ _('hg qseries [-ms]')),
+ "strip":
+ (strip,
+ [('f', 'force', None, _('force removal of changesets even if the '
+ 'working directory has uncommitted changes')),
+ ('b', 'backup', None, _('bundle only changesets with local revision'
+ ' number greater than REV which are not'
+ ' descendants of REV (DEPRECATED)')),
+ ('n', 'nobackup', None, _('no backups'))],
+ _('hg strip [-f] [-b] [-n] REV')),
+ "qtop": (top, [] + seriesopts, _('hg qtop [-s]')),
"qunapplied":
(unapplied,
[('1', 'first', None, _('show only the first patch'))] + seriesopts,
--- a/mercurial/commands.py Sat May 01 15:14:22 2010 -0500
+++ b/mercurial/commands.py Sat May 01 15:15:35 2010 -0500
@@ -2474,7 +2474,8 @@
c = repo['']
subs = c.substate # only repos that are committed
for s in sorted(subs):
- c.sub(s).push(opts.get('force'))
+ if not c.sub(s).push(opts.get('force')):
+ return False
r = repo.push(other, opts.get('force'), revs=revs)
return r == 0
--- a/mercurial/statichttprepo.py Sat May 01 15:14:22 2010 -0500
+++ b/mercurial/statichttprepo.py Sat May 01 15:15:35 2010 -0500
@@ -18,6 +18,7 @@
self.url = url
self.pos = 0
self.opener = opener
+ self.name = url
def seek(self, pos):
self.pos = pos
def read(self, bytes=None):
@@ -56,6 +57,10 @@
data = data[:bytes]
self.pos += len(data)
return data
+ def __iter__(self):
+ return iter(self.read().splitlines(1))
+ def close(self):
+ pass
def build_opener(ui, authinfo):
# urllib cannot handle URLs with embedded user or passwd
@@ -65,7 +70,9 @@
def opener(base):
"""return a function that opens files over http"""
p = base
- def o(path, mode="r"):
+ def o(path, mode="r", atomictemp=None):
+ if 'a' in mode or 'w' in mode:
+ raise IOError('Permission denied')
f = "/".join((p, urllib.quote(path)))
return httprangereader(f, urlopener)
return o
@@ -77,6 +84,7 @@
self._url = path
self.ui = ui
+ self.root = path
self.path, authinfo = url.getauthinfo(path.rstrip('/') + "/.hg")
opener = build_opener(ui, authinfo)
@@ -116,6 +124,8 @@
self.changelog = changelog.changelog(self.sopener)
self._tags = None
self.nodetagscache = None
+ self._branchcache = None
+ self._branchcachetip = None
self.encodepats = None
self.decodepats = None
--- a/mercurial/subrepo.py Sat May 01 15:14:22 2010 -0500
+++ b/mercurial/subrepo.py Sat May 01 15:15:35 2010 -0500
@@ -259,12 +259,13 @@
c = self._repo['']
subs = c.substate # only repos that are committed
for s in sorted(subs):
- c.sub(s).push(force)
+ if not c.sub(s).push(force):
+ return False
self._repo.ui.status(_('pushing subrepo %s\n') % self._path)
dsturl = _abssource(self._repo, True)
other = hg.repository(self._repo.ui, dsturl)
- self._repo.push(other, force)
+ return self._repo.push(other, force)
class svnsubrepo(object):
def __init__(self, ctx, path, state):
--- a/mercurial/tags.py Sat May 01 15:14:22 2010 -0500
+++ b/mercurial/tags.py Sat May 01 15:15:35 2010 -0500
@@ -197,6 +197,8 @@
try:
cachefile = repo.opener('tags.cache', 'r')
+ # force reading the file for static-http
+ cachelines = iter(cachefile)
_debug(ui, 'reading tag cache from %s\n' % cachefile.name)
except IOError:
cachefile = None
@@ -217,7 +219,7 @@
cacheheads = [] # list of headnode
cachefnode = {} # map headnode to filenode
if cachefile:
- for line in cachefile:
+ for line in cachelines:
if line == "\n":
break
line = line.rstrip().split()
@@ -237,7 +239,7 @@
# have been destroyed by strip or rollback.)
if cacheheads and cacheheads[0] == tipnode and cacherevs[0] == tiprev:
_debug(ui, "tag cache: tip unchanged\n")
- tags = _readtags(ui, repo, cachefile, cachefile.name)
+ tags = _readtags(ui, repo, cachelines, cachefile.name)
cachefile.close()
return (None, None, tags, False)
if cachefile:
--- a/tests/test-extension Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-extension Sat May 01 15:15:35 2010 -0500
@@ -156,6 +156,7 @@
echo '% disabled extension commands'
HGRCPATH=
+export HGRCPATH
hg help email
hg qdel
hg churn
--- a/tests/test-issue2137 Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-issue2137 Sat May 01 15:15:35 2010 -0500
@@ -28,7 +28,7 @@
cat >> $HGRCPATH <<EOF
[extensions]
-commitwrapper = $PWD/commitwrapper.py
+commitwrapper = `pwd`/commitwrapper.py
EOF
hg init repo1
--- a/tests/test-mq-merge Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-mq-merge Sat May 01 15:15:35 2010 -0500
@@ -28,7 +28,7 @@
hg qrefresh -m "rm a"
# Save the patch queue so we can merge it later
-hg qsave -c -e 2>&1 | grep -v ^copy
+hg qsave -c -e 2>&1 | grep -v '^copy'
checkundo qsave
# Update b and commit in an "update" changeset
@@ -40,7 +40,7 @@
# Here, qpush used to abort with :
# The system cannot find the file specified => a
hg manifest
-hg qpush -a -m 2>&1 | grep -v ^merging
+hg qpush -a -m 2>&1 | grep -v '^merging'
checkundo 'qpush -m'
hg manifest
--- a/tests/test-mq.out Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-mq.out Sat May 01 15:15:35 2010 -0500
@@ -55,7 +55,7 @@
qseries print the entire series file
qtop print the name of the current patch
qunapplied print the patches not yet applied
- strip strip a revision and all its descendants from the repository
+ strip strip a changeset and all its descendants from the repository
use "hg -v help mq" to show aliases and global options
adding a
--- a/tests/test-static-http Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-static-http Sat May 01 15:15:35 2010 -0500
@@ -43,6 +43,8 @@
cd ../remote
echo baz > quux
hg commit -A -mtest2 -d '100000000 0'
+# check for HTTP opener failures when cachefile does not exist
+rm .hg/*.cache
cd ../local
echo '[hooks]' >> .hg/hgrc
@@ -55,8 +57,12 @@
hg commit -m"test" -d "100000000 0"
hg push | sed -e "s,:$HGPORT/,:\$HGPORT/,"
+echo '% trying clone -r'
+cd ..
+hg clone -r donotexist static-http://localhost:$HGPORT/remote local0 | sed -e "s,:$HGPORT/,:\$HGPORT/,"
+hg clone -r 0 static-http://localhost:$HGPORT/remote local0 | sed -e "s,:$HGPORT/,:\$HGPORT/,"
+
echo '% test with "/" URI (issue 747)'
-cd ..
hg init
echo a > a
hg add a
--- a/tests/test-static-http.out Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-static-http.out Sat May 01 15:15:35 2010 -0500
@@ -33,6 +33,15 @@
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
abort: cannot lock static-http repository
pushing to static-http://localhost:$HGPORT/remote
+% trying clone -r
+abort: unknown revision 'donotexist'!
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
% test with "/" URI (issue 747)
requesting all changes
adding changesets
--- a/tests/test-subrepo Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-subrepo Sat May 01 15:15:35 2010 -0500
@@ -208,4 +208,24 @@
| "$TESTDIR/filtertmp.py"
rm -rf mercurial mercurial2
+echo % issue 1977
+hg init repo
+hg init repo/s
+echo a > repo/s/a
+hg -R repo/s ci -Am0
+echo s = s > repo/.hgsub
+hg -R repo ci -Am1
+hg clone repo repo2
+hg -q -R repo2 pull -u
+echo 1 > repo2/s/a
+hg -R repo2/s ci -m2
+hg -q -R repo2/s push
+hg -R repo2/s up -C 0
+echo 2 > repo2/s/a
+hg -R repo2/s ci -m3
+hg -R repo2 ci -m3
+hg -q -R repo2 push
+hg -R repo update
+rm -rf repo2 repo
+
exit 0
--- a/tests/test-subrepo.out Sat May 01 15:14:22 2010 -0500
+++ b/tests/test-subrepo.out Sat May 01 15:15:35 2010 -0500
@@ -163,14 +163,6 @@
pushing ...subrepo s
searching for changes
(did you forget to merge? use push -f to force)
-pushing ...subrepo t
-searching for changes
-no changes found
-searching for changes
-adding changesets
-adding manifests
-adding file changes
-added 1 changesets with 1 changes to 1 files
pushing ...sub/t
pushing ...subrepo ss
searching for changes
@@ -185,7 +177,10 @@
searching for changes
no changes found
searching for changes
-no changes found
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
% update
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
committing subrepository t
@@ -266,3 +261,20 @@
default = $HGTMP/test-subrepo/sub/mercurial/nested_absolute
[paths]
default = $HGTMP/test-subrepo/sub/mercurial/main/../nested_relative
+% issue 1977
+adding a
+adding .hgsub
+committing subrepository s
+updating to branch default
+pulling subrepo s
+requesting all changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+committing subrepository s
+abort: push creates new remote heads on branch 'default'!
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved