Mercurial > hg
changeset 16544:3d81780deb78 stable
merge with i18n
author | Wagner Bruna <wbruna@yahoo.com> |
---|---|
date | Sat, 28 Apr 2012 13:22:52 -0300 |
parents | 39d1f83eb05d (diff) 715a9fb8ef22 (current diff) |
children | 4b093c30a5f0 |
files | |
diffstat | 18 files changed, 289 insertions(+), 76 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/rebase.py Sun Apr 29 00:48:22 2012 +0900 +++ b/hgext/rebase.py Sat Apr 28 13:22:52 2012 -0300 @@ -446,6 +446,7 @@ mqrebase = {} mq = repo.mq original_series = mq.fullseries[:] + skippedpatches = set() for p in mq.applied: rev = repo[p.node].rev() @@ -453,6 +454,9 @@ repo.ui.debug('revision %d is an mq patch (%s), finalize it.\n' % (rev, p.name)) mqrebase[rev] = (p.name, isagitpatch(repo, p.name)) + else: + # Applied but not rebased, not sure this should happen + skippedpatches.add(p.name) if mqrebase: mq.finish(repo, mqrebase.keys()) @@ -464,14 +468,17 @@ repo.ui.debug('import mq patch %d (%s)\n' % (state[rev], name)) mq.qimport(repo, (), patchname=name, git=isgit, rev=[str(state[rev])]) + else: + # Rebased and skipped + skippedpatches.add(mqrebase[rev][0]) - # restore missing guards - for s in original_series: - pname = mq.guard_re.split(s, 1)[0] - if pname in mq.fullseries: - repo.ui.debug('restoring guard for patch %s' % (pname)) - mq.fullseries[mq.fullseries.index(pname)] = s - mq.series_dirty = True + # Patches were either applied and rebased and imported in + # order, applied and removed or unapplied. Discard the removed + # ones while preserving the original series order and guards. + newseries = [s for s in original_series + if mq.guard_re.split(s, 1)[0] not in skippedpatches] + mq.fullseries[:] = newseries + mq.seriesdirty = True mq.savedirty() def updatebookmarks(repo, nstate, originalbookmarks, **opts):
--- a/mercurial/base85.c Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/base85.c Sat Apr 28 13:22:52 2012 -0300 @@ -109,7 +109,7 @@ if (c < 0) return PyErr_Format( PyExc_ValueError, - "Bad base85 character at position %d", i); + "bad base85 character at position %d", i); acc = acc * 85 + c; } if (i++ < len) @@ -118,13 +118,13 @@ if (c < 0) return PyErr_Format( PyExc_ValueError, - "Bad base85 character at position %d", i); + "bad base85 character at position %d", i); /* overflow detection: 0xffffffff == "|NsC0", * "|NsC" == 0x03030303 */ if (acc > 0x03030303 || (acc *= 85) > 0xffffffff - c) return PyErr_Format( PyExc_ValueError, - "Bad base85 sequence at position %d", i); + "bad base85 sequence at position %d", i); acc += c; }
--- a/mercurial/discovery.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/discovery.py Sat Apr 28 13:22:52 2012 -0300 @@ -153,7 +153,10 @@ branches = set(repo[n].branch() for n in outgoing.missing) # 2. Check for new branches on the remote. - remotemap = remote.branchmap() + if remote.local(): + remotemap = phases.visiblebranchmap(remote) + else: + remotemap = remote.branchmap() newbranches = branches - set(remotemap) if newbranches and not newbranch: # new branch requires --new-branch branchnames = ', '.join(sorted(newbranches))
--- a/mercurial/merge.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/merge.py Sat Apr 28 13:22:52 2012 -0300 @@ -83,7 +83,7 @@ def _checkunknownfile(repo, wctx, mctx, f): return (not repo.dirstate._ignore(f) - and os.path.exists(repo.wjoin(f)) + and os.path.isfile(repo.wjoin(f)) and repo.dirstate.normalize(f) not in repo.dirstate and mctx[f].cmp(wctx[f]))
--- a/mercurial/patch.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/patch.py Sat Apr 28 13:22:52 2012 -0300 @@ -1022,9 +1022,10 @@ class binhunk(object): 'A binary patch file. Only understands literals so far.' - def __init__(self, lr): + def __init__(self, lr, fname): self.text = None self.hunk = ['GIT binary patch\n'] + self._fname = fname self._read(lr) def complete(self): @@ -1034,30 +1035,36 @@ return [self.text] def _read(self, lr): - line = lr.readline() - self.hunk.append(line) + def getline(lr, hunk): + l = lr.readline() + hunk.append(l) + return l.rstrip('\r\n') + + line = getline(lr, self.hunk) while line and not line.startswith('literal '): - line = lr.readline() - self.hunk.append(line) + line = getline(lr, self.hunk) if not line: - raise PatchError(_('could not extract binary patch')) + raise PatchError(_('could not extract "%s" binary data') + % self._fname) size = int(line[8:].rstrip()) dec = [] - line = lr.readline() - self.hunk.append(line) + line = getline(lr, self.hunk) while len(line) > 1: l = line[0] if l <= 'Z' and l >= 'A': l = ord(l) - ord('A') + 1 else: l = ord(l) - ord('a') + 27 - dec.append(base85.b85decode(line[1:-1])[:l]) - line = lr.readline() - self.hunk.append(line) + try: + dec.append(base85.b85decode(line[1:])[:l]) + except ValueError, e: + raise PatchError(_('could not decode "%s" binary patch: %s') + % (self._fname, str(e))) + line = getline(lr, self.hunk) text = zlib.decompress(''.join(dec)) if len(text) != size: - raise PatchError(_('binary patch is %d bytes, not %d') % - len(text), size) + raise PatchError(_('"%s" length is %d bytes, should be %d') + % (self._fname, len(text), size)) self.text = text def parsefilename(str): @@ -1196,7 +1203,7 @@ gitpatches[-1].ispatching(afile, bfile)): gp = gitpatches.pop() if x.startswith('GIT binary patch'): - h = binhunk(lr) + h = binhunk(lr, gp.path) else: if context is None and x.startswith('***************'): context = True @@ -1207,7 +1214,7 @@ yield 'file', (afile, bfile, h, gp and gp.copy() or None) yield 'hunk', h elif x.startswith('diff --git'): - m = gitre.match(x) + m = gitre.match(x.rstrip(' \r\n')) if not m: continue if gitpatches is None:
--- a/mercurial/phases.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/phases.py Sat Apr 28 13:22:52 2012 -0300 @@ -263,6 +263,28 @@ vheads = repo.heads() return vheads +def visiblebranchmap(repo): + """return a branchmap for the visible set""" + # XXX Recomputing this data on the fly is very slow. We should build a + # XXX cached version while computin the standard branchmap version. + sroots = repo._phaseroots[secret] + if sroots: + vbranchmap = {} + for branch, nodes in repo.branchmap().iteritems(): + # search for secret heads. + for n in nodes: + if repo[n].phase() >= secret: + nodes = None + break + # if secreat heads where found we must compute them again + if nodes is None: + s = repo.set('heads(branch(%s) - secret())', branch) + nodes = [c.node() for c in s] + vbranchmap[branch] = nodes + else: + vbranchmap = repo.branchmap() + return vbranchmap + def analyzeremotephases(repo, subset, roots): """Compute phases heads and root in a subset of node from root dict
--- a/mercurial/revlog.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/revlog.py Sat Apr 28 13:22:52 2012 -0300 @@ -812,7 +812,7 @@ else: df = self.opener(self.datafile) - readahead = max(_chunksize, length) + readahead = max(65536, length) df.seek(offset) d = df.read(readahead) df.close()
--- a/mercurial/revset.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/revset.py Sat Apr 28 13:22:52 2012 -0300 @@ -341,23 +341,26 @@ def checkstatus(repo, subset, pat, field): m = None s = [] - fast = not matchmod.patkind(pat) + hasset = matchmod.patkind(pat) == 'set' + fname = None for r in subset: c = repo[r] - if fast: - if pat not in c.files(): + if not m or hasset: + m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c) + if not m.anypats() and len(m.files()) == 1: + fname = m.files()[0] + if fname is not None: + if fname not in c.files(): continue else: - if not m or matchmod.patkind(pat) == 'set': - m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=c) for f in c.files(): if m(f): break else: continue files = repo.status(c.p1().node(), c.node())[field] - if fast: - if pat in files: + if fname is not None: + if fname in files: s.append(r) else: for f in files: @@ -911,19 +914,23 @@ """``matching(revision [, field])`` Changesets in which a given set of fields match the set of fields in the selected revision or set. + To match more than one field pass the list of fields to match separated - by spaces (e.g. 'author description'). - Valid fields are most regular revision fields and some special fields: - * regular fields: - - description, author, branch, date, files, phase, parents, - substate, user. - Note that author and user are synonyms. - * special fields: summary, metadata. - - summary: matches the first line of the description. - - metatadata: It is equivalent to matching 'description user date' - (i.e. it matches the main metadata fields). - metadata is the default field which is used when no fields are specified. - You can match more than one field at a time. + by spaces (e.g. ``author description``). + + Valid fields are most regular revision fields and some special fields. + + Regular revision fields are ``description``, ``author``, ``branch``, + ``date``, ``files``, ``phase``, ``parents``, ``substate`` and ``user``. + Note that ``author`` and ``user`` are synonyms. + + Special fields are ``summary`` and ``metadata``: + ``summary`` matches the first line of the description. + ``metatadata`` is equivalent to matching ``description user date`` + (i.e. it matches the main metadata fields). + + ``metadata`` is the default field which is used when no fields are + specified. You can match more than one field at a time. """ l = getargs(x, 1, 2, _("matching takes 1 or 2 arguments"))
--- a/mercurial/subrepo.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/subrepo.py Sat Apr 28 13:22:52 2012 -0300 @@ -366,7 +366,7 @@ pass def forget(self, ui, match, prefix): - return [] + return ([], []) def revert(self, ui, substate, *pats, **opts): ui.warn('%s: reverting %s subrepos is unsupported\n' \ @@ -680,12 +680,13 @@ return self._wcrevs()[0] def _wcchanged(self): - """Return (changes, extchanges) where changes is True - if the working directory was changed, and extchanges is - True if any of these changes concern an external entry. + """Return (changes, extchanges, missing) where changes is True + if the working directory was changed, extchanges is + True if any of these changes concern an external entry and missing + is True if any change is a missing entry. """ output, err = self._svncommand(['status', '--xml']) - externals, changes = [], [] + externals, changes, missing = [], [], [] doc = xml.dom.minidom.parseString(output) for e in doc.getElementsByTagName('entry'): s = e.getElementsByTagName('wc-status') @@ -696,14 +697,16 @@ path = e.getAttribute('path') if item == 'external': externals.append(path) + elif item == 'missing': + missing.append(path) if (item not in ('', 'normal', 'unversioned', 'external') or props not in ('', 'none', 'normal')): changes.append(path) for path in changes: for ext in externals: if path == ext or path.startswith(ext + os.sep): - return True, True - return bool(changes), False + return True, True, bool(missing) + return bool(changes), False, bool(missing) def dirty(self, ignoreupdate=False): if not self._wcchanged()[0]: @@ -716,16 +719,26 @@ def commit(self, text, user, date): # user and date are out of our hands since svn is centralized - changed, extchanged = self._wcchanged() + changed, extchanged, missing = self._wcchanged() if not changed: return self._wcrev() if extchanged: # Do not try to commit externals raise util.Abort(_('cannot commit svn externals')) + if missing: + # svn can commit with missing entries but aborting like hg + # seems a better approach. + raise util.Abort(_('cannot commit missing svn entries')) commitinfo, err = self._svncommand(['commit', '-m', text]) self._ui.status(commitinfo) newrev = re.search('Committed revision ([0-9]+).', commitinfo) if not newrev: + if not commitinfo.strip(): + # Sometimes, our definition of "changed" differs from + # svn one. For instance, svn ignores missing files + # when committing. If there are only missing files, no + # commit is made, no output and no error code. + raise util.Abort(_('failed to commit svn changes')) raise util.Abort(commitinfo.splitlines()[-1]) newrev = newrev.groups()[0] self._ui.status(self._svncommand(['update', '-r', newrev])[0]) @@ -767,7 +780,7 @@ status, err = self._svncommand(args, failok=True) if not re.search('Checked out revision [0-9]+.', status): if ('is already a working copy for a different URL' in err - and (self._wcchanged() == (False, False))): + and (self._wcchanged()[:2] == (False, False))): # obstructed but clean working copy, so just blow it away. self.remove() self.get(state, overwrite=False)
--- a/mercurial/wireproto.py Sun Apr 29 00:48:22 2012 +0900 +++ b/mercurial/wireproto.py Sat Apr 28 13:22:52 2012 -0300 @@ -396,7 +396,7 @@ return "".join(r) def branchmap(repo, proto): - branchmap = repo.branchmap() + branchmap = phases.visiblebranchmap(repo) heads = [] for branch, nodes in branchmap.iteritems(): branchname = urllib.quote(encoding.fromlocal(branch)) @@ -555,7 +555,7 @@ their_heads = decodelist(heads) def check_heads(): - heads = repo.heads() + heads = phases.visibleheads(repo) heads_hash = util.sha1(''.join(sorted(heads))).digest() return (their_heads == ['force'] or their_heads == heads or their_heads == ['hashed', heads_hash])
--- a/tests/test-convert-svn-source.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-convert-svn-source.t Sat Apr 28 13:22:52 2012 -0300 @@ -34,10 +34,10 @@ $ cd .. $ svnurl="file://$svnpath/svn-repo/proj%20B" - $ svn import -m "init projB" projB "$svnurl" | fixpath + $ svn import -m "init projB" projB "$svnurl" | fixpath | sort + Adding projB/mytrunk Adding projB/tags - Committed revision 1. Update svn repository
--- a/tests/test-import-git.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-import-git.t Sat Apr 28 13:22:52 2012 -0300 @@ -362,6 +362,77 @@ A binary2 text2 R text2 + +Invalid base85 content + + $ hg rollback + repository tip rolled back to revision 15 (undo import) + working directory now based on revision 15 + $ hg revert -aq + $ hg import -d "1000000 0" -m invalid-binary - <<"EOF" + > diff --git a/text2 b/binary2 + > rename from text2 + > rename to binary2 + > index 78981922613b2afb6025042ff6bd878ac1994e85..10efcb362e9f3b3420fcfbfc0e37f3dc16e29757 + > GIT binary patch + > literal 5 + > Mc$`b*O.$Pw00T?_*Z=?k + > + > EOF + applying patch from stdin + abort: could not decode "binary2" binary patch: bad base85 character at position 6 + [255] + + $ hg revert -aq + $ hg import -d "1000000 0" -m rename-as-binary - <<"EOF" + > diff --git a/text2 b/binary2 + > rename from text2 + > rename to binary2 + > index 78981922613b2afb6025042ff6bd878ac1994e85..10efcb362e9f3b3420fcfbfc0e37f3dc16e29757 + > GIT binary patch + > literal 6 + > Mc$`b*O5$Pw00T?_*Z=?k + > + > EOF + applying patch from stdin + abort: "binary2" length is 5 bytes, should be 6 + [255] + + $ hg revert -aq + $ hg import -d "1000000 0" -m rename-as-binary - <<"EOF" + > diff --git a/text2 b/binary2 + > rename from text2 + > rename to binary2 + > index 78981922613b2afb6025042ff6bd878ac1994e85..10efcb362e9f3b3420fcfbfc0e37f3dc16e29757 + > GIT binary patch + > Mc$`b*O5$Pw00T?_*Z=?k + > + > EOF + applying patch from stdin + abort: could not extract "binary2" binary data + [255] + +Simulate a copy/paste turning LF into CRLF (issue2870) + + $ hg revert -aq + $ cat > binary.diff <<"EOF" + > diff --git a/text2 b/binary2 + > rename from text2 + > rename to binary2 + > index 78981922613b2afb6025042ff6bd878ac1994e85..10efcb362e9f3b3420fcfbfc0e37f3dc16e29757 + > GIT binary patch + > literal 5 + > Mc$`b*O5$Pw00T?_*Z=?k + > + > EOF + >>> fp = file('binary.diff', 'rb') + >>> data = fp.read() + >>> fp.close() + >>> file('binary.diff', 'wb').write(data.replace('\n', '\r\n')) + $ rm binary2 + $ hg import --no-commit binary.diff + applying binary.diff + $ cd .. Consecutive import with renames (issue2459)
--- a/tests/test-phases-exchange.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-phases-exchange.t Sat Apr 28 13:22:52 2012 -0300 @@ -833,12 +833,20 @@ o 0 public a-A - 054250a37db4 -pushing a locally public and draft changesets remotly secret should make them appear on the remote side +pushing a locally public and draft changesets remotly secret should make them +appear on the remote side. + $ hg -R ../mu phase --secret --force 967b449fbc94 $ hg push -r 435b5d83910c ../mu pushing to ../mu searching for changes + abort: push creates new remote head 435b5d83910c! + (did you forget to merge? use push -f to force) + [255] + $ hg push -fr 435b5d83910c ../mu # because the push will create new visible head + pushing to ../mu + searching for changes adding changesets adding manifests adding file changes
--- a/tests/test-phases.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-phases.t Sat Apr 28 13:22:52 2012 -0300 @@ -135,6 +135,39 @@ 2 1 C 1 0 B 0 0 A + +(Issue3303) +Check that remote secret changeset are ignore when checking creation of remote heads + +We add a secret head into the push destination. This secreat head shadow a +visible shared between the initial repo and the push destination. + + $ hg up -q 4 # B' + $ mkcommit Z --config phases.new-commit=secret + $ hg phase . + 5: secret + +# We now try to push a new public changeset that descend from the common public +# head shadowed by the remote secret head. + + $ cd ../initialrepo + $ hg up -q 6 #B' + $ mkcommit I + created new head + $ hg push ../push-dest + pushing to ../push-dest + searching for changes + adding changesets + adding manifests + adding file changes + added 1 changesets with 1 changes to 1 files (+1 heads) + +:note: The "(+1 heads)" is wrong as we do not had any visible head + + +Restore condition prior extra insertion. + $ hg -q --config extensions.mq= strip . + $ hg up -q 7 $ cd .. Test secret changeset are not pull
--- a/tests/test-rebase-mq.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-rebase-mq.t Sat Apr 28 13:22:52 2012 -0300 @@ -247,30 +247,41 @@ Create mq repo with guarded patches foo and bar and empty patch: $ hg qinit - $ hg qnew foo - $ hg qguard foo +baz + $ echo guarded > guarded + $ hg add guarded + $ hg qnew guarded + $ hg qnew empty-important -m 'important commit message' + $ echo bar > bar + $ hg add bar + $ hg qnew bar $ echo foo > foo $ hg add foo - $ hg qref - $ hg qpop + $ hg qnew foo + $ hg qpop -a popping foo + popping bar + popping empty-important + popping guarded patch queue now empty - - $ hg qnew empty-important -m 'important commit message' - - $ hg qnew bar + $ hg qguard guarded +guarded $ hg qguard bar +baz - $ echo bar > bar - $ hg add bar - $ hg qref + $ hg qguard foo +baz + $ hg qselect baz + number of unguarded, unapplied patches has changed from 1 to 3 + $ hg qpush bar + applying empty-important + patch empty-important is empty + applying bar + now at: bar $ hg qguard -l + guarded: +guarded empty-important: unguarded bar: +baz foo: +baz $ hg tglog - @ 2: '[mq]: bar' tags: bar qtip tip + @ 2: 'imported patch bar' tags: bar qtip tip | o 1: 'important commit message' tags: empty-important qbase | @@ -303,18 +314,21 @@ removed from the series): $ hg qseries + guarded empty-important bar foo $ [ -f .hg/patches/empty-important ] $ hg -q rebase -d 2 $ hg qseries + guarded bar foo $ [ -f .hg/patches/empty-important ] [1] $ hg qguard -l + guarded: +guarded bar: +baz foo: +baz
--- a/tests/test-revset.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-revset.t Sat Apr 28 13:22:52 2012 -0300 @@ -305,6 +305,13 @@ 6 $ log 'modifies(b)' 4 + $ log 'modifies("path:b")' + 4 + $ log 'modifies("*")' + 4 + 6 + $ log 'modifies("set:modified()")' + 4 $ log 'id(5)' 2 $ log 'outgoing()'
--- a/tests/test-subrepo-git.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-subrepo-git.t Sat Apr 28 13:22:52 2012 -0300 @@ -507,3 +507,8 @@ da5f5b1d8ffcf62fb8327bcd3c89a4367a6018e7 $ cd .. +Test forgetting files, not implemented in git subrepo, used to +traceback + $ hg forget 'notafile*' + notafile*: No such file or directory + [1]
--- a/tests/test-subrepo-svn.t Sun Apr 29 00:48:22 2012 +0900 +++ b/tests/test-subrepo-svn.t Sat Apr 28 13:22:52 2012 -0300 @@ -120,6 +120,15 @@ source file://*/svn-repo/src (glob) revision 2 +missing svn file, commit should fail + + $ rm s/alpha + $ hg commit --subrepos -m 'abort on missing file' + committing subrepository s + abort: cannot commit missing svn entries + [255] + $ svn revert s/alpha > /dev/null + add an unrelated revision in svn and update the subrepo to without bringing any changes. @@ -272,13 +281,13 @@ Checked out revision 3. 1 files updated, 0 files merged, 0 files removed, 0 files unresolved $ cd t/s - $ svn status + $ svn status | sort + ? * a (glob) - X * externals (glob) ? * f1 (glob) ? * f2 (glob) - Performing status on external item at 'externals'* (glob) + X * externals (glob) Sticky subrepositories, no changes $ cd $TESTTMP/sub/t @@ -548,3 +557,10 @@ archiving (s): 2/2 files (100.00%) archiving (recreated): 0/1 files (0.00%) archiving (recreated): 1/1 files (100.00%) + +Test forgetting files, not implemented in svn subrepo, used to +traceback + + $ hg forget 'notafile*' + notafile*: No such file or directory + [1]