Mercurial > hg-stable
changeset 15716:049643a31b9a
merge with i18n
author | Matt Mackall <mpm@selenic.com> |
---|---|
date | Thu, 22 Dec 2011 15:56:17 -0600 |
parents | cff25e4b37d2 (diff) bd280b2bf669 (current diff) |
children | 9cf1620e1e75 |
files | |
diffstat | 17 files changed, 293 insertions(+), 43 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Wed Dec 21 11:48:18 2011 +0200 +++ b/.hgignore Thu Dec 22 15:56:17 2011 -0600 @@ -49,3 +49,8 @@ syntax: regexp ^\.pc/ ^\.(pydev)?project + +# hackable windows distribution additions +^hg-python26/ +^hg.exe$ +^hg.py$
--- a/hgext/largefiles/lfutil.py Wed Dec 21 11:48:18 2011 +0200 +++ b/hgext/largefiles/lfutil.py Thu Dec 22 15:56:17 2011 -0600 @@ -79,7 +79,7 @@ except OSError: # if hardlinks fail, fallback on atomic copy dst = util.atomictempfile(dest) - for chunk in util.filechunkiter(open(src)): + for chunk in util.filechunkiter(open(src, 'rb')): dst.write(chunk) dst.close() os.chmod(dest, os.stat(src).st_mode) @@ -238,7 +238,7 @@ link(usercachepath(repo.ui, hash), storepath(repo, hash)) else: dst = util.atomictempfile(storepath(repo, hash)) - for chunk in util.filechunkiter(open(file)): + for chunk in util.filechunkiter(open(file, 'rb')): dst.write(chunk) dst.close() util.copymode(file, storepath(repo, hash))
--- a/hgext/mq.py Wed Dec 21 11:48:18 2011 +0200 +++ b/hgext/mq.py Thu Dec 22 15:56:17 2011 -0600 @@ -1765,6 +1765,9 @@ diffopts = self.diffopts({'git': git}) for r in rev: + if not repo[r].mutable(): + raise util.Abort(_('revision %d is not mutable') % r, + hint=_('see "hg help phases" for details')) p1, p2 = repo.changelog.parentrevs(r) n = repo.changelog.node(r) if p2 != nullrev:
--- a/mercurial/cmdutil.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/cmdutil.py Thu Dec 22 15:56:17 2011 -0600 @@ -588,16 +588,17 @@ ctx1 = repo[node1] ctx2 = repo[node2] for subpath, sub in subrepo.itersubrepos(ctx1, ctx2): + tempnode2 = node2 try: if node2 is not None: - node2 = ctx2.substate[subpath][1] + tempnode2 = ctx2.substate[subpath][1] except KeyError: # A subrepo that existed in node1 was deleted between node1 and # node2 (inclusive). Thus, ctx2's substate won't contain that # subpath. The best we can do is to ignore it. - node2 = None + tempnode2 = None submatch = matchmod.narrowmatcher(subpath, match) - sub.diff(diffopts, node2, submatch, changes=changes, + sub.diff(diffopts, tempnode2, submatch, changes=changes, stat=stat, fp=fp, prefix=prefix) class changeset_printer(object):
--- a/mercurial/commands.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/commands.py Thu Dec 22 15:56:17 2011 -0600 @@ -4362,7 +4362,7 @@ c = repo[''] subs = c.substate # only repos that are committed for s in sorted(subs): - if not c.sub(s).push(opts.get('force')): + if not c.sub(s).push(opts): return False finally: del repo._subtoppath
--- a/mercurial/context.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/context.py Thu Dec 22 15:56:17 2011 -0600 @@ -124,6 +124,8 @@ # outdated cache del self._repo._phaserev return self._repo._phaserev[self._rev] + def mutable(self): + return self._repo._phaserev[self._rev] > 0 def hidden(self): return self._rev in self._repo.changelog.hiddenrevs @@ -803,6 +805,15 @@ b.extend(p.bookmarks()) return b + def phase(self): + phase = 1 # default phase to draft + for p in self.parents(): + phase = max(phase, p.phase()) + return phase + + def hidden(self): + return False + def children(self): return []
--- a/mercurial/discovery.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/discovery.py Thu Dec 22 15:56:17 2011 -0600 @@ -85,12 +85,28 @@ _common, inc, remoteheads = commoninc cl = repo.changelog - outg = cl.findmissing(common, revs) + alloutg = cl.findmissing(common, revs) + outg = [] + secret = [] + for o in alloutg: + if repo[o].phase() >= 2: + secret.append(o) + else: + outg.append(o) if not outg: - repo.ui.status(_("no changes found\n")) + if secret: + repo.ui.status(_("no changes to push but %i secret changesets\n") + % len(secret)) + else: + repo.ui.status(_("no changes found\n")) return None, 1, common + if secret: + # recompute target revs + revs = [ctx.node() for ctx in repo.set('heads(::(%ld))', + map(repo.changelog.rev, outg))] + if not force and remoteheads != [nullid]: if remote.capable('branchmap'): # Check for each named branch if we're creating new remote heads.
--- a/mercurial/localrepo.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/localrepo.py Thu Dec 22 15:56:17 2011 -0600 @@ -1251,8 +1251,15 @@ self.hook('pretxncommit', throw=True, node=hex(n), parent1=xp1, parent2=xp2, pending=p) self.changelog.finalize(trp) - # ensure the new commit is 1-phase - phases.retractboundary(self, 1, [n]) + # set the new commit is proper phase + targetphase = self.ui.configint('phases', 'new-commit', 1) + if targetphase: + # retract boundary do not alter parent changeset. + # if a parent have higher the resulting phase will + # be compliant anyway + # + # if minimal phase was 0 we don't need to retract anything + phases.retractboundary(self, targetphase, [n]) tr.close() if self._branchcache:
--- a/mercurial/phases.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/phases.py Thu Dec 22 15:56:17 2011 -0600 @@ -34,6 +34,7 @@ immutable shared public: X X draft: X + secret: local commits are draft by default @@ -50,6 +51,8 @@ * pull never changes server states * publish and old server csets are seen as public by client +* Any secret changeset seens in another repository is lowered to at least draft + Here is the final table summing up the 49 possible usecase of phase exchange:
--- a/mercurial/posix.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/posix.py Thu Dec 22 15:56:17 2011 -0600 @@ -238,6 +238,38 @@ # Fallback to the likely inadequate Python builtin function. realpath = os.path.realpath +if sys.platform == 'cygwin': + # workaround for cygwin, in which mount point part of path is + # treated as case sensitive, even though underlying NTFS is case + # insensitive. + + # default mount points + cygwinmountpoints = sorted([ + "/usr/bin", + "/usr/lib", + "/cygdrive", + ], reverse=True) + + # use upper-ing as normcase as same as NTFS workaround + def normcase(path): + pathlen = len(path) + if (pathlen == 0) or (path[0] != os.sep): + # treat as relative + return encodingupper(path) + + # to preserve case of mountpoint part + for mp in cygwinmountpoints: + if not path.startswith(mp): + continue + + mplen = len(mp) + if mplen == pathlen: # mount point itself + return mp + if path[mplen] == os.sep: + return mp + encodingupper(path[mplen:]) + + return encodingupper(path) + def shellquote(s): if os.sys.platform == 'OpenVMS': return '"%s"' % s
--- a/mercurial/setdiscovery.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/setdiscovery.py Thu Dec 22 15:56:17 2011 -0600 @@ -9,6 +9,7 @@ from node import nullid from i18n import _ import random, collections, util, dagutil +import phases def _updatesample(dag, nodes, sample, always, quicksamplesize=0): # if nodes is empty we scan the entire graph @@ -99,7 +100,7 @@ sample = ownheads if remote.local(): # stopgap until we have a proper localpeer that supports batch() - srvheadhashes = remote.heads() + srvheadhashes = phases.visibleheads(remote) yesno = remote.known(dag.externalizeall(sample)) elif remote.capable('batch'): batch = remote.batch()
--- a/mercurial/subrepo.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/subrepo.py Thu Dec 22 15:56:17 2011 -0600 @@ -303,7 +303,7 @@ """merge currently-saved state with the new state.""" raise NotImplementedError - def push(self, force): + def push(self, opts): """perform whatever action is analogous to 'hg push' This may be a no-op on some systems. @@ -519,19 +519,23 @@ else: mergefunc() - def push(self, force): + def push(self, opts): + force = opts.get('force') + newbranch = opts.get('new_branch') + ssh = opts.get('ssh') + # push subrepos depth-first for coherent ordering c = self._repo[''] subs = c.substate # only repos that are committed for s in sorted(subs): - if not c.sub(s).push(force): + if not c.sub(s).push(opts): return False dsturl = _abssource(self._repo, True) self._repo.ui.status(_('pushing subrepo %s to %s\n') % (subrelpath(self), dsturl)) - other = hg.peer(self._repo.ui, {}, dsturl) - return self._repo.push(other, force) + other = hg.peer(self._repo.ui, {'ssh': ssh}, dsturl) + return self._repo.push(other, force, newbranch=newbranch) def outgoing(self, ui, dest, opts): return hg.outgoing(ui, self._repo, _abssource(self._repo, True), opts) @@ -731,7 +735,7 @@ if _updateprompt(self._ui, self, dirty, self._wcrev(), new): self.get(state, False) - def push(self, force): + def push(self, opts): # push is a no-op for SVN return True @@ -1025,7 +1029,9 @@ else: mergefunc() - def push(self, force): + def push(self, opts): + force = opts.get('force') + if not self._state[1]: return True if self._gitmissing():
--- a/mercurial/util.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/util.py Thu Dec 22 15:56:17 2011 -0600 @@ -614,20 +614,18 @@ def fspath(name, root): '''Get name in the case stored in the filesystem - The name is either relative to root, or it is an absolute path starting - with root. Note that this function is unnecessary, and should not be + The name should be relative to root, and be normcase-ed for efficiency. + + Note that this function is unnecessary, and should not be called, for case-sensitive filesystems (simply because it's expensive). - Both name and root should be normcase-ed. + The root should be normcase-ed, too. ''' - # If name is absolute, make it relative - if name.startswith(root): - l = len(root) - if name[l] == os.sep or name[l] == os.altsep: - l = l + 1 - name = name[l:] - - if not os.path.lexists(os.path.join(root, name)): + def find(p, contents): + lenp = len(p) + for n in contents: + if lenp == len(n) and normcase(n) == p: + return n return None seps = os.sep @@ -643,18 +641,19 @@ result.append(sep) continue - if dir not in _fspathcache: - _fspathcache[dir] = os.listdir(dir) - contents = _fspathcache[dir] + contents = _fspathcache.get(dir, None) + if contents is None: + contents = os.listdir(dir) + _fspathcache[dir] = contents - lenp = len(part) - for n in contents: - if lenp == len(n) and normcase(n) == part: - result.append(n) - break - else: - # Cannot happen, as the file exists! - result.append(part) + found = find(part, contents) + if not found: + # retry once for the corner case: add files after dir walking + contents = os.listdir(dir) + _fspathcache[dir] = contents + found = find(part, contents) + + result.append(found or part) dir = os.path.join(dir, part) return ''.join(result)
--- a/mercurial/wireproto.py Wed Dec 21 11:48:18 2011 +0200 +++ b/mercurial/wireproto.py Thu Dec 22 15:56:17 2011 -0600 @@ -10,6 +10,7 @@ from node import bin, hex import changegroup as changegroupmod import repo, error, encoding, util, store +import phases # abstract batching support @@ -449,7 +450,7 @@ return streamres(proto.groupchunks(cg)) def heads(repo, proto): - h = repo.heads() + h = phases.visibleheads(repo) return encodelist(h) + "\n" def hello(repo, proto):
--- a/tests/test-mq-qimport-fail-cleanup.t Wed Dec 21 11:48:18 2011 +0200 +++ b/tests/test-mq-qimport-fail-cleanup.t Thu Dec 22 15:56:17 2011 -0600 @@ -32,3 +32,9 @@ $ hg qseries b.patch + + $ hg pull -q -r 0 . # update phase + $ hg qimport -r 0 + abort: revision 0 is not mutable + (see "hg help phases" for details) + [255]
--- a/tests/test-phases-exchange.t Wed Dec 21 11:48:18 2011 +0200 +++ b/tests/test-phases-exchange.t Thu Dec 22 15:56:17 2011 -0600 @@ -7,7 +7,9 @@ $ mkcommit() { > echo "$1" > "$1" > hg add "$1" - > hg ci -m "$1" + > message="$1" + > shift + > hg ci -m "$message" $* > } $ hg init alpha @@ -478,6 +480,7 @@ Pushing to Publish=True (common changeset from publish=False) +(in mu) $ hg push ../alpha pushing to ../alpha searching for changes @@ -506,3 +509,62 @@ 1 0 a-B - 548a3d25dbf0 0 0 a-A - 054250a37db4 + +Discovery locally secret changeset on a remote repository: + +- should make it non-secret + + $ cd ../alpha + $ mkcommit A-secret --config phases.new-commit=2 + $ hgph + 11 2 A-secret - 435b5d83910c + 10 0 a-H - 967b449fbc94 + 9 1 a-G - 3e27b6f1eee1 + 8 0 a-F - b740e3e5c05d + 7 0 a-E - e9f537e46dea + 6 0 n-B - 145e75495359 + 5 0 n-A - d6bcb4f74035 + 4 0 b-A - f54f1bb90ff3 + 3 0 a-D - b555f63b6063 + 2 0 a-C - 54acac6f23ab + 1 0 a-B - 548a3d25dbf0 + 0 0 a-A - 054250a37db4 + $ hg bundle --base 'parents(.)' -r . ../secret-bundle.hg + 1 changesets found + $ hg -R ../mu unbundle ../secret-bundle.hg + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files + (run 'hg update' to get a working copy) + $ hgph -R ../mu + 10 1 A-secret - 435b5d83910c + 9 0 a-H - 967b449fbc94 + 8 0 a-F - b740e3e5c05d + 7 0 a-E - e9f537e46dea + 6 0 n-B - 145e75495359 + 5 0 n-A - d6bcb4f74035 + 4 0 a-D - b555f63b6063 + 3 0 a-C - 54acac6f23ab + 2 0 b-A - f54f1bb90ff3 + 1 0 a-B - 548a3d25dbf0 + 0 0 a-A - 054250a37db4 + $ hg pull ../mu + pulling from ../mu + searching for changes + no changes found + $ hgph + 11 1 A-secret - 435b5d83910c + 10 0 a-H - 967b449fbc94 + 9 1 a-G - 3e27b6f1eee1 + 8 0 a-F - b740e3e5c05d + 7 0 a-E - e9f537e46dea + 6 0 n-B - 145e75495359 + 5 0 n-A - d6bcb4f74035 + 4 0 b-A - f54f1bb90ff3 + 3 0 a-D - b555f63b6063 + 2 0 a-C - 54acac6f23ab + 1 0 a-B - 548a3d25dbf0 + 0 0 a-A - 054250a37db4 + +
--- a/tests/test-phases.t Wed Dec 21 11:48:18 2011 +0200 +++ b/tests/test-phases.t Thu Dec 22 15:56:17 2011 -0600 @@ -2,7 +2,9 @@ $ mkcommit() { > echo "$1" > "$1" > hg add "$1" - > hg ci -m "$1" + > message="$1" + > shift + > hg ci -m "$message" $* > } $ hg init initialrepo @@ -37,3 +39,98 @@ 2 1 C 1 0 B 0 0 A + +Test creating changeset as secret + + $ mkcommit E --config phases.new-commit=2 + $ hglog + 4 2 E + 3 1 D + 2 1 C + 1 0 B + 0 0 A + +Test the secret property is inherited + + $ mkcommit H + $ hglog + 5 2 H + 4 2 E + 3 1 D + 2 1 C + 1 0 B + 0 0 A + +Even on merge + + $ hg up -q 1 + $ mkcommit "B'" + created new head + $ hglog + 6 1 B' + 5 2 H + 4 2 E + 3 1 D + 2 1 C + 1 0 B + 0 0 A + $ hg merge 4 # E + 3 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m "merge B' and E" + $ hglog + 7 2 merge B' and E + 6 1 B' + 5 2 H + 4 2 E + 3 1 D + 2 1 C + 1 0 B + 0 0 A + +Test secret changeset are not pushed + + $ hg init ../push-dest + $ hg push ../push-dest -f # force because we push multiple heads + pushing to ../push-dest + searching for changes + adding changesets + adding manifests + adding file changes + added 5 changesets with 5 changes to 5 files (+1 heads) + $ hglog + 7 2 merge B' and E + 6 0 B' + 5 2 H + 4 2 E + 3 0 D + 2 0 C + 1 0 B + 0 0 A + $ cd ../push-dest + $ hglog + 4 0 B' + 3 0 D + 2 0 C + 1 0 B + 0 0 A + $ cd .. + +Test secret changeset are not pull + + $ hg init pull-dest + $ cd pull-dest + $ hg pull ../initialrepo + pulling from ../initialrepo + requesting all changes + adding changesets + adding manifests + adding file changes + added 5 changesets with 5 changes to 5 files (+1 heads) + (run 'hg heads' to see heads, 'hg merge' to merge) + $ hglog + 4 0 B' + 3 0 D + 2 0 C + 1 0 B + 0 0 A