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.
This commit is contained in:
Nicolas Dumazet 2010-04-26 20:13:14 +09:00
parent 16da932a11
commit 09283d5a0c
4 changed files with 31 additions and 4 deletions

View File

@ -18,6 +18,7 @@ class httprangereader(object):
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 @@ class httprangereader(object):
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 build_opener(ui, authinfo):
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 @@ class statichttprepository(localrepo.localrepository):
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 @@ class statichttprepository(localrepo.localrepository):
self.changelog = changelog.changelog(self.sopener)
self._tags = None
self.nodetagscache = None
self._branchcache = None
self._branchcachetip = None
self.encodepats = None
self.decodepats = None

View File

@ -197,6 +197,8 @@ def _readtagcache(ui, repo):
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 @@ def _readtagcache(ui, repo):
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 @@ def _readtagcache(ui, repo):
# 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:

View File

@ -43,6 +43,8 @@ cat bar
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 @@ echo more foo >> bar
hg commit -m"test" -d "100000000 0"
hg push | sed -e "s,:$HGPORT/,:\$HGPORT/,"
echo '% test with "/" URI (issue 747)'
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)'
hg init
echo a > a
hg add a

View File

@ -33,6 +33,15 @@ added 1 changesets with 1 changes to 1 files
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