static-http: mimic more closely localrepo (
issue2164: allow clone -r )
* httprangereader: name, __iter__ and close are needed to mimic file object
* static-http opener:
- disallow write/append modes
- add (unused) atomictemp parameter
* static-http repo:
- root attribute is needed for localrepo.dirstate()
- _branch* attributes are required for commitctx and branchmap calls
* tags: force repo.opener.__iter__ call earlier to force httprangereader
to try to read the cache early, to avoid raising IOError later.
--- a/mercurial/statichttprepo.py Fri Apr 30 18:11:56 2010 +0200
+++ b/mercurial/statichttprepo.py Mon Apr 26 20:13:14 2010 +0900
@@ -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/tags.py Fri Apr 30 18:11:56 2010 +0200
+++ b/mercurial/tags.py Mon Apr 26 20:13:14 2010 +0900
@@ -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-static-http Fri Apr 30 18:11:56 2010 +0200
+++ b/tests/test-static-http Mon Apr 26 20:13:14 2010 +0900
@@ -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 Fri Apr 30 18:11:56 2010 +0200
+++ b/tests/test-static-http.out Mon Apr 26 20:13:14 2010 +0900
@@ -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