changeset 330:27d08c0c2a7e

Merge with TAH -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Merge with TAH fixup history messages to not interfere with GPG signing manifest hash: aea3a92e4699dfe0cbd98e6e2c8c6971218a59b8 -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCrkK4ywK+sNU5EO8RAqxHAKCNyjTE5F/7EvM+ipjhgzIUk1aWZACgm7zz eBcKlHcOA8ceUcn4IEBLQpM= =YfHT -----END PGP SIGNATURE-----
author mpm@selenic.com
date Mon, 13 Jun 2005 18:36:40 -0800
parents dac675ef6189 (diff) 67c19ad374a9 (current diff)
children 55f63f3b6a54 a0b2758edee7
files README doc/hg.1.txt mercurial/commands.py mercurial/hg.py mercurial/hgweb.py mercurial/mdiff.py mercurial/revlog.py
diffstat 7 files changed, 169 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/README	Mon Jun 13 08:49:21 2005 +0100
+++ b/README	Mon Jun 13 18:36:40 2005 -0800
@@ -59,7 +59,7 @@
  $ cd ..
  $ mkdir linux-work
  $ cd linux-work
- $ hg branch ../linux        # create a new branch
+ $ hg init ../linux          # create a new branch
  $ hg update                 # populate the working directory
  $ <make changes>
  $ hg commit
@@ -100,6 +100,9 @@
  # export your current repo via HTTP with browsable interface
  foo$ hg serve -n "My repo" -p 80
  
+ # pushing changes to a remote repo with SSH
+ foo$ hg push ssh://user@example.com/~/hg/
+
  # merge changes from a remote machine
  bar$ hg pull http://foo/
  bar$ hg co        # merge changes into your working directory
@@ -110,10 +113,10 @@
 
 Symbolic repository names:
 
- Mercurial uses an optional file called ~/.hgpaths to track repo
- locations symbolically. Simply add a line with the name, a space, and
- a URL:
+ Mercurial uses an options file called ~/.hgrc. To track locations
+ symbolically, add a section to it like this:
 
- foo$ echo "main http://selenic.com/hg/" >> ~/.hgpaths
- foo$ hg merge main
- foo$ hg co
+ [paths]
+ main = http://selenic.com/hg
+ hgweb = http://edge2.net/hg/hgweb/
+ hgdoc = http://edge2.net/hg/man/
--- a/doc/hg.1.txt	Mon Jun 13 08:49:21 2005 +0100
+++ b/doc/hg.1.txt	Mon Jun 13 18:36:40 2005 -0800
@@ -188,6 +188,22 @@
     (which could be a local path or a remote URI), the format is 
     <symbolic name> <repository path> with each mapping on a seperate line
 
+NON_TRANSPARENT PROXY SUPPORT
+-----
+
+    To access a mercurial repository through a proxy,
+    create a file $HOME/.hgrc in the following format:
+
+[http_proxy]
+host=myproxy:8080
+user=<username>
+passwd=<password>
+no=<localhost1>,<localhost2>,<localhost3>,...
+
+    "user","passwd" fields are used for authenticating proxies,
+    "no" is a comma-separated list of local host names
+    for which proxy must be bypassed.
+
 BUGS
 ----
 Probably lots, please post them to the mailing list (See Resources below)
--- a/mercurial/commands.py	Mon Jun 13 08:49:21 2005 +0100
+++ b/mercurial/commands.py	Mon Jun 13 18:36:40 2005 -0800
@@ -118,8 +118,12 @@
         time.localtime(float(changes[2].split(' ')[0]))))
     ui.note("files:       %s\n" % " ".join(changes[3]))
     if description:
-        ui.status("description: %s\n" % description[0])
-        ui.note(''.join(["| %s\n" % line.rstrip() for line in description[1:]]))
+        if ui.verbose:
+            ui.status("description:\n")
+            ui.status(changes[4].strip())
+            ui.status("\n")
+        else:
+            ui.status("summary:     %s\n" % description[0])
     ui.status("\n")
 
 def help(ui, cmd=None):
--- a/mercurial/hg.py	Mon Jun 13 08:49:21 2005 +0100
+++ b/mercurial/hg.py	Mon Jun 13 18:36:40 2005 -0800
@@ -723,38 +723,50 @@
         if not unknown:
             self.ui.status("nothing to do!\n")
             return None
-            
+
+        rep = {}
+        reqcnt = 0
+        
         unknown = remote.branches(unknown)
         while unknown:
-            n = unknown.pop(0)
-            seen[n[0]] = 1
-            
-            self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1])))
-            if n == nullid: break
-            if n in seenbranch:
-                self.ui.debug("branch already found\n")
-                continue
-            if n[1] and n[1] in m: # do we know the base?
-                self.ui.debug("found incomplete branch %s:%s\n"
-                              % (short(n[0]), short(n[1])))
-                search.append(n) # schedule branch range for scanning
-                seenbranch[n] = 1
-            else:
-                if n[2] in m and n[3] in m:
-                    if n[1] not in fetch:
-                        self.ui.debug("found new changeset %s\n" %
-                                      short(n[1]))
-                        fetch.append(n[1]) # earliest unknown
-                        continue
+            r = []
+            while unknown:
+                n = unknown.pop(0)
+                if n[0] in seen:
+                    continue
 
-                r = []
-                for a in n[2:4]:
-                    if a not in seen: r.append(a)
-                    
-                if r:
-                    self.ui.debug("requesting %s\n" %
-                                " ".join(map(short, r)))
-                    for b in remote.branches(r):
+                self.ui.debug("examining %s:%s\n" % (short(n[0]), short(n[1])))
+                if n[0] == nullid:
+                    break
+                if n in seenbranch:
+                    self.ui.debug("branch already found\n")
+                    continue
+                if n[1] and n[1] in m: # do we know the base?
+                    self.ui.debug("found incomplete branch %s:%s\n"
+                                  % (short(n[0]), short(n[1])))
+                    search.append(n) # schedule branch range for scanning
+                    seenbranch[n] = 1
+                else:
+                    if n[1] not in seen and n[1] not in fetch:
+                        if n[2] in m and n[3] in m:
+                            self.ui.debug("found new changeset %s\n" %
+                                          short(n[1]))
+                            fetch.append(n[1]) # earliest unknown
+                            continue
+
+                    for a in n[2:4]:
+                        if a not in rep:
+                            r.append(a)
+                            rep[a] = 1
+
+                seen[n[0]] = 1
+
+            if r:
+                reqcnt += 1
+                self.ui.debug("request %d: %s\n" %
+                            (reqcnt, " ".join(map(short, r))))
+                for p in range(0, len(r), 10):
+                    for b in remote.branches(r[p:p+10]):
                         self.ui.debug("received %s:%s\n" %
                                       (short(b[0]), short(b[1])))
                         if b[0] not in m and b[0] not in seen:
@@ -762,10 +774,13 @@
   
         while search:
             n = search.pop(0)
+            reqcnt += 1
             l = remote.between([(n[0], n[1])])[0]
+            l.append(n[1])
             p = n[0]
             f = 1
-            for i in l + [n[1]]:
+            for i in l:
+                self.ui.debug("narrowing %d:%d %s\n" % (f, len(l), short(i)))
                 if i in m:
                     if f <= 2:
                         self.ui.debug("found new branch changeset %s\n" %
@@ -785,6 +800,8 @@
         self.ui.note("adding new changesets starting at " +
                      " ".join([short(f) for f in fetch]) + "\n")
 
+        self.ui.debug("%d total queries\n" % reqcnt)
+
         return remote.changegroup(fetch)
     
     def changegroup(self, basenodes):
@@ -1228,6 +1245,36 @@
     def __init__(self, ui, path):
         self.url = path
         self.ui = ui
+        no_list = [ "localhost", "127.0.0.1" ]
+        host = ui.config("http_proxy", "host")
+        user = ui.config("http_proxy", "user")
+        passwd = ui.config("http_proxy", "passwd")
+        no = ui.config("http_proxy", "no")
+        if no:
+            no_list = no_list + no.split(",")
+            
+        no_proxy = 0
+        for h in no_list:
+            if (path.startswith("http://" + h + "/") or
+                path.startswith("http://" + h + ":") or
+                path == "http://" + h):
+                no_proxy = 1
+
+        # Note: urllib2 takes proxy values from the environment and those will
+        # take precedence
+
+        proxy_handler = urllib2.BaseHandler()
+        if host and not no_proxy:
+            proxy_handler = urllib2.ProxyHandler({"http" : "http://" + host})
+
+        authinfo = None
+        if user and passwd:
+            passmgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
+            passmgr.add_password(None, host, user, passwd)
+            authinfo = urllib2.ProxyBasicAuthHandler(passmgr)
+
+        opener = urllib2.build_opener(proxy_handler, authinfo)
+        urllib2.install_opener(opener)
 
     def do_cmd(self, cmd, **args):
         self.ui.debug("sending %s command\n" % cmd)
@@ -1235,7 +1282,7 @@
         q.update(args)
         qs = urllib.urlencode(q)
         cu = "%s?%s" % (self.url, qs)
-        return urllib.urlopen(cu)
+        return urllib2.urlopen(cu)
 
     def heads(self):
         d = self.do_cmd("heads").read()
--- a/mercurial/hgweb.py	Mon Jun 13 08:49:21 2005 +0100
+++ b/mercurial/hgweb.py	Mon Jun 13 18:36:40 2005 -0800
@@ -135,6 +135,7 @@
     def refresh(self):
         s = os.stat(os.path.join(self.path, ".hg", "00changelog.i"))
         if s.st_mtime != self.mtime:
+            self.mtime = s.st_mtime
             self.repo = repository(ui(), self.path)
 
     def date(self, cs):
--- a/mercurial/mdiff.py	Mon Jun 13 08:49:21 2005 +0100
+++ b/mercurial/mdiff.py	Mon Jun 13 18:36:40 2005 -0800
@@ -43,28 +43,41 @@
 
 def sortdiff(a, b):
     la = lb = 0
-
+    lena = len(a)
+    lenb = len(b)
+    
     while 1:
-        if la >= len(a) or lb >= len(b): break
-        if b[lb] < a[la]:
-            si = lb
-            while lb < len(b) and b[lb] < a[la] : lb += 1
-            yield "insert", la, la, si, lb
-        elif a[la] < b[lb]:
-            si = la
-            while la < len(a) and a[la] < b[lb]: la += 1
-            yield "delete", si, la, lb, lb
-        else:
+        am, bm, = la, lb
+
+        # walk over matching lines
+        while lb < lenb and la < lena and a[la] == b[lb] :
             la += 1
             lb += 1
 
-    if lb < len(b):
-        yield "insert", la, la, lb, len(b)
+        if la > am:
+            yield (am, bm, la - am) # return a match
+
+        # skip mismatched lines from b
+        while lb < lenb and b[lb] < a[la]:
+            lb += 1
 
-    if la < len(a):
-        yield "delete", la, len(a), lb, lb
+        if lb >= lenb:
+            break
+        
+        # skip mismatched lines from a
+        while la < lena and b[lb] > a[la]:
+            la += 1
+
+        if la >= lena:
+            break
+        
+    yield (lena, lenb, 0)
 
 def diff(a, b, sorted=0):
+    if not a:
+        s = "".join(b)
+        return s and (struct.pack(">lll", 0, 0, len(s)) + s)
+
     bin = []
     p = [0]
     for i in a: p.append(p[-1] + len(i))
@@ -76,13 +89,16 @@
             print a, b
             raise
     else:
-        d = difflib.SequenceMatcher(None, a, b).get_opcodes()
-
-    for o, m, n, s, t in d:
-        if o == 'equal': continue
-        s = "".join(b[s:t])
-        bin.append(struct.pack(">lll", p[m], p[n], len(s)) + s)
-
+        d = difflib.SequenceMatcher(None, a, b).get_matching_blocks()
+    la = 0
+    lb = 0
+    for am, bm, size in d:
+        s = "".join(b[lb:bm])
+        if am > la or s:
+            bin.append(struct.pack(">lll", p[la], p[am], len(s)) + s)
+        la = am + size
+        lb = bm + size
+    
     return "".join(bin)
 
 def patchtext(bin):
--- a/mercurial/revlog.py	Mon Jun 13 08:49:21 2005 +0100
+++ b/mercurial/revlog.py	Mon Jun 13 18:36:40 2005 -0800
@@ -43,17 +43,28 @@
 indexformat = ">4l20s20s20s"
 
 class lazyparser:
-    def __init__(self, data):
+    def __init__(self, data, revlog):
         self.data = data
         self.s = struct.calcsize(indexformat)
         self.l = len(data)/self.s
         self.index = [None] * self.l
         self.map = {nullid: -1}
+        self.all = 0
+        self.revlog = revlog
 
-    def load(self, pos):
-        block = pos / 1000
-        i = block * 1000
-        end = min(self.l, i + 1000)
+    def load(self, pos=None):
+        if self.all: return
+        if pos is not None:
+            block = pos / 1000
+            i = block * 1000
+            end = min(self.l, i + 1000)
+        else:
+            self.all = 1
+            i = 0
+            end = self.l
+            self.revlog.index = self.index
+            self.revlog.nodemap = self.map
+            
         while i < end:
             d = self.data[i * self.s: (i + 1) * self.s]
             e = struct.unpack(indexformat, d)
@@ -78,16 +89,14 @@
     def __init__(self, parser):
         self.p = parser
     def load(self, key):
+        if self.p.all: return
         n = self.p.data.find(key)
         if n < 0: raise KeyError("node " + hex(key))
         pos = n / self.p.s
         self.p.load(pos)
     def __contains__(self, key):
-        try:
-            self[key]
-            return True
-        except KeyError:
-            return False
+        self.p.load()
+        return key in self.p.map
     def __iter__(self):
         for i in xrange(self.p.l):
             try:
@@ -121,7 +130,7 @@
 
         if len(i) > 10000:
             # big index, let's parse it on demand
-            parser = lazyparser(i)
+            parser = lazyparser(i, self)
             self.index = lazyindex(parser)
             self.nodemap = lazymap(parser)
         else: