# HG changeset patch # User Matt Mackall # Date 1342656491 18000 # Node ID 23b247234454c945ff0b907dd6195a385c134468 # Parent c315842cb25f4a0dec2625acc32db7bc651144ec# Parent 988974c2a4bf3aa18dcfb8a094b87d23aefb5542 merge with crew diff -r c315842cb25f -r 23b247234454 contrib/perf.py --- a/contrib/perf.py Thu Jul 19 00:54:33 2012 +0200 +++ b/contrib/perf.py Wed Jul 18 19:08:11 2012 -0500 @@ -177,7 +177,7 @@ ui.popbuffer() def perfcca(ui, repo): - timer(lambda: scmutil.casecollisionauditor(ui, False, repo[None])) + timer(lambda: scmutil.casecollisionauditor(ui, False, repo.dirstate)) def perffncacheload(ui, repo): from mercurial import scmutil, store diff -r c315842cb25f -r 23b247234454 mercurial/commands.py --- a/mercurial/commands.py Thu Jul 19 00:54:33 2012 +0200 +++ b/mercurial/commands.py Wed Jul 18 19:08:11 2012 -0500 @@ -5750,23 +5750,25 @@ none are found, the working directory is updated to the specified changeset. - The following rules apply when the working directory contains - uncommitted changes: - - 1. If neither -c/--check nor -C/--clean is specified, and if - the requested changeset is an ancestor or descendant of - the working directory's parent, the uncommitted changes - are merged into the requested changeset and the merged - result is left uncommitted. If the requested changeset is - not an ancestor or descendant (that is, it is on another - branch), the update is aborted and the uncommitted changes - are preserved. - - 2. With the -c/--check option, the update is aborted and the - uncommitted changes are preserved. - - 3. With the -C/--clean option, uncommitted changes are discarded and - the working directory is updated to the requested changeset. + .. container:: verbose + + The following rules apply when the working directory contains + uncommitted changes: + + 1. If neither -c/--check nor -C/--clean is specified, and if + the requested changeset is an ancestor or descendant of + the working directory's parent, the uncommitted changes + are merged into the requested changeset and the merged + result is left uncommitted. If the requested changeset is + not an ancestor or descendant (that is, it is on another + branch), the update is aborted and the uncommitted changes + are preserved. + + 2. With the -c/--check option, the update is aborted and the + uncommitted changes are preserved. + + 3. With the -C/--clean option, uncommitted changes are discarded and + the working directory is updated to the requested changeset. To cancel an uncommitted merge (and lose your changes), use :hg:`update --clean .`. diff -r c315842cb25f -r 23b247234454 mercurial/extensions.py --- a/mercurial/extensions.py Thu Jul 19 00:54:33 2012 +0200 +++ b/mercurial/extensions.py Wed Jul 18 19:08:11 2012 -0500 @@ -42,7 +42,12 @@ fd, fpath, desc = imp.find_module(f, [d]) return imp.load_module(module_name, fd, fpath, desc) else: - return imp.load_source(module_name, path) + try: + return imp.load_source(module_name, path) + except IOError, exc: + if not exc.filename: + exc.filename = path # python does not fill this + raise def load(ui, name, path): # unused ui argument kept for backwards compatibility diff -r c315842cb25f -r 23b247234454 mercurial/hook.py --- a/mercurial/hook.py Thu Jul 19 00:54:33 2012 +0200 +++ b/mercurial/hook.py Wed Jul 18 19:08:11 2012 -0500 @@ -169,7 +169,11 @@ path = util.expandpath(path) if repo: path = os.path.join(repo.root, path) - mod = extensions.loadpath(path, 'hghook.%s' % hname) + try: + mod = extensions.loadpath(path, 'hghook.%s' % hname) + except Exception: + ui.write(_("loading %s hook failed:\n") % hname) + raise hookfn = getattr(mod, cmd) else: hookfn = cmd[7:].strip() diff -r c315842cb25f -r 23b247234454 mercurial/httppeer.py --- a/mercurial/httppeer.py Thu Jul 19 00:54:33 2012 +0200 +++ b/mercurial/httppeer.py Wed Jul 18 19:08:11 2012 -0500 @@ -79,6 +79,9 @@ elif data is not None: size = len(data) headers = args.pop('headers', {}) + if data is not None and 'Content-Type' not in headers: + headers['Content-Type'] = 'application/mercurial-0.1' + if size and self.ui.configbool('ui', 'usehttp2', False): headers['Expect'] = '100-Continue' diff -r c315842cb25f -r 23b247234454 mercurial/obsolete.py --- a/mercurial/obsolete.py Thu Jul 19 00:54:33 2012 +0200 +++ b/mercurial/obsolete.py Wed Jul 18 19:08:11 2012 -0500 @@ -164,8 +164,7 @@ self.sopener = sopener data = sopener.tryread('obsstore') if data: - for marker in _readmarkers(data): - self._load(marker) + self._load(_readmarkers(data)) def __iter__(self): return iter(self._all) @@ -188,11 +187,15 @@ if len(succ) != 20: raise ValueError(succ) marker = (str(prec), tuple(succs), int(flag), encodemeta(metadata)) - self.add(transaction, marker) + self.add(transaction, [marker]) + + def add(self, transaction, markers): + """Add new markers to the store - def add(self, transaction, marker): - """Add a new marker to the store""" - if marker not in self._all: + Take care of filtering duplicate. + Return the number of new marker.""" + new = [m for m in markers if m not in self._all] + if new: f = self.sopener('obsstore', 'ab') try: # Whether the file's current position is at the begin or at @@ -203,51 +206,48 @@ f.seek(0, 2) # os.SEEK_END offset = f.tell() transaction.add('obsstore', offset) - if offset == 0: - # new file add version header - f.write(_pack('>B', _fmversion)) - _writemarkers(f.write, [marker]) + # offset == 0: new file - add the version header + for bytes in _encodemarkers(new, offset == 0): + f.write(bytes) finally: # XXX: f.close() == filecache invalidation == obsstore rebuilt. # call 'filecacheentry.refresh()' here f.close() - self._load(marker) + self._load(new) + return len(new) def mergemarkers(self, transation, data): - other = _readmarkers(data) - local = set(self._all) - new = [m for m in other if m not in local] - for marker in new: - # XXX: N marker == N x (open, write, close) - # we should write them all at once - self.add(transation, marker) + markers = _readmarkers(data) + self.add(transation, markers) - def _load(self, marker): - self._all.append(marker) - pre, sucs = marker[:2] - self.precursors.setdefault(pre, set()).add(marker) - for suc in sucs: - self.successors.setdefault(suc, set()).add(marker) + def _load(self, markers): + for mark in markers: + self._all.append(mark) + pre, sucs = mark[:2] + self.precursors.setdefault(pre, set()).add(mark) + for suc in sucs: + self.successors.setdefault(suc, set()).add(mark) -def _writemarkers(write, markers): +def _encodemarkers(markers, addheader=False): # Kept separate from flushmarkers(), it will be reused for # markers exchange. + if addheader: + yield _pack('>B', _fmversion) for marker in markers: pre, sucs, flags, metadata = marker nbsuc = len(sucs) format = _fmfixed + (_fmnode * nbsuc) data = [nbsuc, len(metadata), flags, pre] data.extend(sucs) - write(_pack(format, *data)) - write(metadata) + yield _pack(format, *data) + yield metadata def listmarkers(repo): """List markers over pushkey""" if not repo.obsstore: return {} - data = [_pack('>B', _fmversion)] - _writemarkers(data.append, repo.obsstore) - return {'dump': base85.b85encode(''.join(data))} + markers = _encodemarkers(repo.obsstore, True) + return {'dump': base85.b85encode(''.join(markers))} def pushmarker(repo, key, old, new): """Push markers over pushkey""" diff -r c315842cb25f -r 23b247234454 tests/test-hook.t --- a/tests/test-hook.t Thu Jul 19 00:54:33 2012 +0200 +++ b/tests/test-hook.t Wed Jul 18 19:08:11 2012 -0500 @@ -530,6 +530,20 @@ nothing changed [1] + $ echo '[hooks]' > .hg/hgrc + $ echo "update.ne = python:`pwd`/nonexisting.py:testhook" >> .hg/hgrc + $ echo "pre-identify.npmd = python:`pwd`/:no_python_module_dir" >> .hg/hgrc + + $ hg up null + loading update.ne hook failed: + abort: No such file or directory: $TESTTMP/d/repo/nonexisting.py + [255] + + $ hg id + loading pre-identify.npmd hook failed: + abort: No module named repo! + [255] + $ cd ../../b make sure --traceback works on hook import failure