##// END OF EJS Templates
rebase: do not invent successor to skipped changeset...
rebase: do not invent successor to skipped changeset When rebase results in an empty a changeset it is "skipped" and no related changeset is created at all. When we added obsolescence support to rebase (in fc2a6114f0a0) it seemed a good idea to use its parent successor as the successors for such dropped changesets. (see old version of the altered test). This option was chosen because it seems a good way to hint about were the dropped changeset "intended" to be. Such hint would have been used by automatic evolution mechanism to rebase potential unstable children. However, field testing of this version are not conclusive. It very often leads to the creation of (totally unfounded) evolution divergence. This changeset changes this behavior and mark skipped changesets as pruned (obsolete without successors). This prevents the issue and seems semantically better probably a win for obsolescence reading tool. See example bellow for details: User Babar has five changesets of interest: - O, its current base of development. - U, the new upstream - A and C, some development changesets - B another development changeset independent from A O - A - B - C \ U Babar decides that B is more critical than the A and C and rebase it first $ hg rebase --rev B --dest U B is now obsolete (in lower case bellow). Rebase result, B', is its successors.(note, C is unstable) O - A - b - C \ U - B' Babar is now done with B', and want to rebase the rest of its history: $ hg rebase --source A --dest B' hg rebase process A, B and C. B is skipped as all its changes are already contained in B'. O - U - B' - A' - C' Babar have the expected result graph wise, obsolescence marker are as follow: B -> B' (from first rebase) A -> A' (from second rebase) C -> C' (from second rebase) B -> ?? (from second rebase) Before this changeset, the last marker is `B -> A'`. This cause two issues: - This is semantically wrong. B have nothing to do with A' - B has now two successors sets: (B',) and (A',). We detect a divergent rewriting. The B' and A' are reported as "divergent" to Babar, confusion ensues. In addition such divergent situation (divergent changeset are children to each other) is tricky to solve. With this changeset the last marker is `B -> ΓΈ`: - This is semantically better. - B has a single successors set (B',) This scenario is added to the tests suite.

File last commit:

r14975:b6453836 default
r18444:55aff0c2 default
Show More
i18n.py
63 lines | 2.1 KiB | text/x-python | PythonLexer
Martin Geisler
put license and copyright info into comment blocks
r8226 # i18n.py - internationalization support for mercurial
#
# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Benoit Boissinot
i18n first part: make '_' available for files who need it
r1400
Simon Heimberg
separate import lines from mercurial and general python modules
r8312 import encoding
import gettext, sys, os
Martin Geisler
i18n: lookup .mo files in private locale/ directory...
r7650
# modelled after templater.templatepath:
Augie Fackler
i18n: use getattr instead of hasattr...
r14975 if getattr(sys, 'frozen', None) is not None:
Martin Geisler
i18n: lookup .mo files in private locale/ directory...
r7650 module = sys.executable
else:
module = __file__
base = os.path.dirname(module)
for dir in ('.', '..'):
Martin Geisler
i18n: remove unnecessary os.path.normpath call
r9538 localedir = os.path.join(base, dir, 'locale')
Martin Geisler
i18n: lookup .mo files in private locale/ directory...
r7650 if os.path.isdir(localedir):
break
t = gettext.translation('hg', localedir, fallback=True)
Martin Geisler
i18n: encode output in user's local encoding...
r7651
def gettext(message):
"""Translate message.
The message is looked up in the catalog to get a Unicode string,
which is encoded in the local encoding before being returned.
Important: message is restricted to characters in the encoding
given by sys.getdefaultencoding() which is most likely 'ascii'.
"""
# If message is None, t.ugettext will return u'None' as the
# translation whereas our callers expect us to return None.
if message is None:
return message
Martin Geisler
i18n: fix translation of empty paragraphs
r11403 paragraphs = message.split('\n\n')
# Be careful not to translate the empty string -- it holds the
# meta data of the .po file.
u = u'\n\n'.join([p and t.ugettext(p) or '' for p in paragraphs])
Martin Geisler
i18n: encode output in user's local encoding...
r7651 try:
Martin Geisler
i18n: updated outdated comment
r9319 # encoding.tolocal cannot be used since it will first try to
# decode the Unicode string. Calling u.decode(enc) really
# means u.encode(sys.getdefaultencoding()).decode(enc). Since
# the Python encoding defaults to 'ascii', this fails if the
# translated string use non-ASCII characters.
Matt Mackall
move encoding bits from util to encoding...
r7948 return u.encode(encoding.encoding, "replace")
Martin Geisler
i18n: encode output in user's local encoding...
r7651 except LookupError:
Martin Geisler
i18n: move unrelated line out of try-except block
r9320 # An unknown encoding results in a LookupError.
Martin Geisler
i18n: encode output in user's local encoding...
r7651 return message
Brodie Rao
HGPLAIN: allow exceptions to plain mode, like i18n, via HGPLAINEXCEPT...
r13849 def _plain():
if 'HGPLAIN' not in os.environ and 'HGPLAINEXCEPT' not in os.environ:
return False
exceptions = os.environ.get('HGPLAINEXCEPT', '').strip().split(',')
return 'i18n' not in exceptions
if _plain():
Brodie Rao
ui: add HGPLAIN environment variable for easier scripting...
r10455 _ = lambda message: message
else:
_ = gettext