--- a/.hgsigs Tue Oct 01 10:44:59 2013 -0700
+++ b/.hgsigs Tue Oct 01 17:00:03 2013 -0700
@@ -77,3 +77,4 @@
f0d7721d7322dcfb5af33599c2543f27335334bb 0 iD8DBQBR8taaywK+sNU5EO8RAqeEAJ4idDhhDuEsgsUjeQgWNj498matHACfT67gSF5w0ylsrBx1Hb52HkGXDm0=
f37b5a17e6a0ee17afde2cdde5393dd74715fb58 0 iD8DBQBR+ymFywK+sNU5EO8RAuSdAJkBMcd9DAZ3rWE9WGKPm2YZ8LBoXACfXn/wbEsVy7ZgJoUwiWmHSnQaWCI=
335a558f81dc73afeab4d7be63617392b130117f 0 iQIVAwUAUiZrIyBXgaxoKi1yAQK2iw//cquNqqSkc8Re5/TZT9I6NH+lh6DbOKjJP0Xl1Wqq0K+KSIUgZG4G32ovaEb2l5X0uY+3unRPiZ0ebl0YSw4Fb2ZiPIADXLBTOYRrY2Wwd3tpJeGI6wEgZt3SfcITV/g7NJrCjT3FlYoSOIayrExM80InSdcEM0Q3Rx6HKzY2acyxzgZeAtAW5ohFvHilSvY6p5Gcm4+QptMxvw45GPdreUmjeXZxNXNXZ8P+MjMz/QJbai/N7PjmK8lqnhkBsT48Ng/KhhmOkGntNJ2/ImBWLFGcWngSvJ7sfWwnyhndvGhe0Hq1NcCf7I8TjNDxU5TR+m+uW7xjXdLoDbUjBdX4sKXnh8ZjbYiODKBOrrDq25cf8nA/tnpKyE/qsVy60kOk6loY4XKiYmn1V49Ta0emmDx0hqo3HgxHHsHX0NDnGdWGol7cPRET0RzVobKq1A0jnrhPooWidvLh9bPzLonrWDo+ib+DuySoRkuYUK4pgZJ2mbg6daFOBEZygkSyRB8bo1UQUP7EgQDrWe4khb/5GHEfDkrQz3qu/sXvc0Ir1mOUWBFPHC2DjjCn/oMJuUkG1SwM8l2Bfv7h67ssES6YQ2+RjOix4yid7EXS/Ogl45PzCIPSI5+BbNs10JhE0w5uErBHlF53EDTe/TSLc+GU6DB6PP6dH912Njdr3jpNSUQ=
+e7fa36d2ad3a7944a52dca126458d6f482db3524 0 iQIVAwUAUktg4yBXgaxoKi1yAQLO0g//du/2ypYYUfmM/yZ4zztNKIvgMSGTDVbCCGB2y2/wk2EcolpjpGTkcgnJT413ksYtw78ZU+mvv0RjgrFCm8DQ8kroJaQZ2qHmtSUb42hPBPvtg6kL9YaA4yvp87uUBpFRavGS5uX4hhEIyvZKzhXUBvqtL3TfwR7ld21bj8j00wudqELyyU9IrojIY9jkJ3XL/4shBGgP7u6OK5g8yJ6zTnWgysUetxHBPrYjG25lziiiZQFvZqK1B3PUqAOaFPltQs0PB8ipOCAHQgJsjaREj8VmC3+rskmSSy66NHm6gAB9+E8oAgOcU7FzWbdYgnz4kR3M7TQvHX9U61NinPXC6Q9d1VPhO3E6sIGvqJ4YeQOn65V9ezYuIpFSlgQzCHMmLVnOV96Uv1R/Z39I4w7D3S5qoZcQT/siQwGbsZoPMGFYmqOK1da5TZWrrJWkYzc9xvzT9m3q3Wds5pmCmo4b/dIqDifWwYEcNAZ0/YLHwCN5SEZWuunkEwtU5o7TZAv3bvDDA6WxUrrHI/y9/qvvhXxsJnY8IueNhshdmWZfXKz+lJi2Dvk7DUlEQ1zZWSsozi1E+3biMPJO47jsxjoT/jmE5+GHLCgcnXXDVBeaVal99IOaTRFukiz2EMsry1s8fnwEE5XKDKRlU/dOPfsje0gc7bgE0QD/u3E4NJ99g9A=
--- a/.hgtags Tue Oct 01 10:44:59 2013 -0700
+++ b/.hgtags Tue Oct 01 17:00:03 2013 -0700
@@ -90,3 +90,4 @@
f0d7721d7322dcfb5af33599c2543f27335334bb 2.7-rc
f37b5a17e6a0ee17afde2cdde5393dd74715fb58 2.7
335a558f81dc73afeab4d7be63617392b130117f 2.7.1
+e7fa36d2ad3a7944a52dca126458d6f482db3524 2.7.2
--- a/hgext/histedit.py Tue Oct 01 10:44:59 2013 -0700
+++ b/hgext/histedit.py Tue Oct 01 17:00:03 2013 -0700
@@ -641,8 +641,7 @@
# `parentctxnode` should match but no result. This means that
# currentnode is not a descendant from parentctxnode.
msg = _('%s is not an ancestor of working directory')
- hint = _('update to %s or descendant and run "hg histedit '
- '--continue" again') % parentctx
+ hint = _('use "histedit --abort" to clear broken state')
raise util.Abort(msg % parentctx, hint=hint)
newchildren.pop(0) # remove parentctxnode
# Commit dirty working directory if necessary
--- a/hgext/rebase.py Tue Oct 01 10:44:59 2013 -0700
+++ b/hgext/rebase.py Tue Oct 01 17:00:03 2013 -0700
@@ -159,8 +159,19 @@
if opts.get('tool', False):
ui.warn(_('tool option will be ignored\n'))
- (originalwd, target, state, skipped, collapsef, keepf,
- keepbranchesf, external, activebookmark) = restorestatus(repo)
+ try:
+ (originalwd, target, state, skipped, collapsef, keepf,
+ keepbranchesf, external, activebookmark) = restorestatus(repo)
+ except error.RepoLookupError:
+ if abortf:
+ clearstatus(repo)
+ repo.ui.warn(_('rebase aborted (no revision is removed,'
+ ' only broken state is cleared)\n'))
+ return 0
+ else:
+ msg = _('cannot continue inconsistent rebase')
+ hint = _('use "hg rebase --abort" to clear borken state')
+ raise util.Abort(msg, hint=hint)
if abortf:
return abort(repo, originalwd, target, state)
else:
@@ -801,7 +812,13 @@
def summaryhook(ui, repo):
if not os.path.exists(repo.join('rebasestate')):
return
- state = restorestatus(repo)[2]
+ try:
+ state = restorestatus(repo)[2]
+ except error.RepoLookupError:
+ # i18n: column positioning for "hg summary"
+ msg = _('rebase: (use "hg rebase --abort" to clear broken state)\n')
+ ui.write(msg)
+ return
numrebased = len([i for i in state.itervalues() if i != -1])
# i18n: column positioning for "hg summary"
ui.write(_('rebase: %s, %s (rebase --continue)\n') %
--- a/i18n/pt_BR.po Tue Oct 01 10:44:59 2013 -0700
+++ b/i18n/pt_BR.po Tue Oct 01 17:00:03 2013 -0700
@@ -4262,6 +4262,12 @@
msgid "no outgoing ancestors"
msgstr "nenhum ancestral a ser enviado"
+msgid "there are ambiguous outgoing revisions"
+msgstr "algumas revisões a serem enviadas são ambíguas"
+
+msgid "see \"hg help histedit\" for more detail"
+msgstr "veja \"hg help histedit\" para mais detalhes"
+
msgid "Read history edits from the specified file."
msgstr "Lê alterações de histórico a partir do arquivo especificado."
@@ -4299,12 +4305,33 @@
msgid ""
" With --outgoing, this edits changesets not found in the\n"
" destination repository. If URL of the destination is omitted, the\n"
-" 'default-push' (or 'default') path will be used.\n"
-" "
+" 'default-push' (or 'default') path will be used."
msgstr ""
" Com --outgoing, edita revisões não encontradas no repositório de\n"
" destino. Se a URL do destino for omitida, o caminho definido em\n"
-" 'default-push' (ou 'default') será usado.\n"
+" 'default-push' (ou 'default') será usado."
+
+msgid ""
+" For safety, this command is aborted, also if there are ambiguous\n"
+" outgoing revisions which may confuse users: for example, there are\n"
+" multiple branches containing outgoing revisions."
+msgstr ""
+" Por segurança, este comando também é abortado se o conjunto de\n"
+" revisões a serem enviadas for ambíguo, pois isso pode confundir\n"
+" os usuários: por exemplo, se vários ramos possuírem revisões a\n"
+" serem enviadas."
+
+msgid ""
+" Use \"min(outgoing() and ::.)\" or similar revset specification\n"
+" instead of --outgoing to specify edit target revision exactly in\n"
+" such ambiguous situation. See :hg:`help revsets` for detail about\n"
+" selecting revisions.\n"
+" "
+msgstr ""
+" Ao invés de --outgoing, use \"min(outgoing() and ::.)\" ou outro\n"
+" revset semelhante para especificar com exatidão as revisões a serem\n"
+" editadas nessas situações.Veja :hg:`help revsets` para detalhes sobre\n"
+" seleção de revisões.\n"
" "
msgid "source has mq patches applied"
--- a/mercurial/localrepo.py Tue Oct 01 10:44:59 2013 -0700
+++ b/mercurial/localrepo.py Tue Oct 01 17:00:03 2013 -0700
@@ -39,9 +39,10 @@
"""propertycache that apply to unfiltered repo only"""
def __get__(self, repo, type=None):
- if hasunfilteredcache(repo, self.name):
- return getattr(repo.unfiltered(), self.name)
- return super(unfilteredpropertycache, self).__get__(repo.unfiltered())
+ unfi = repo.unfiltered()
+ if unfi is repo:
+ return super(unfilteredpropertycache, self).__get__(unfi)
+ return getattr(unfi, self.name)
class filteredpropertycache(propertycache):
"""propertycache that must take filtering in account"""
--- a/mercurial/util.py Tue Oct 01 10:44:59 2013 -0700
+++ b/mercurial/util.py Tue Oct 01 17:00:03 2013 -0700
@@ -283,7 +283,8 @@
return result
def cachevalue(self, obj, value):
- setattr(obj, self.name, value)
+ # __dict__ assigment required to bypass __setattr__ (eg: repoview)
+ obj.__dict__[self.name] = value
def pipefilter(s, cmd):
'''filter string S through command CMD, returning its output'''
--- a/tests/test-histedit-arguments.t Tue Oct 01 10:44:59 2013 -0700
+++ b/tests/test-histedit-arguments.t Tue Oct 01 17:00:03 2013 -0700
@@ -70,6 +70,35 @@
[255]
$ hg up --quiet
+Run on a revision not descendants of the initial parent
+--------------------------------------------------------------------
+
+Test the message shown for inconsistent histedit state, which may be
+created (and forgotten) by Mercurial earlier than 2.7. This emulates
+Mercurial earlier than 2.7 by renaming ".hg/histedit-state"
+temporarily.
+
+ $ HGEDITOR=cat hg histedit -r 4 --commands - << EOF
+ > edit 08d98a8350f3 4 five
+ > EOF
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ reverting alpha
+ Make changes as needed, you may commit or record as needed now.
+ When you are finished, run hg histedit --continue to resume.
+ [1]
+
+ $ mv .hg/histedit-state .hg/histedit-state.back
+ $ hg update --quiet --clean 2
+ $ mv .hg/histedit-state.back .hg/histedit-state
+
+ $ hg histedit --continue
+ abort: c8e68270e35a is not an ancestor of working directory
+ (use "histedit --abort" to clear broken state)
+ [255]
+
+ $ hg histedit --abort
+ $ hg update --quiet --clean
+
Test that missing revisions are detected
---------------------------------------
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-propertycache.py Tue Oct 01 17:00:03 2013 -0700
@@ -0,0 +1,179 @@
+"""test behavior of propertycache and unfiltered propertycache
+
+The repoview overlay is quite complexe. We test the behavior of
+property cache of both localrepo and repoview to prevent
+regression."""
+
+import os, subprocess
+import mercurial.localrepo
+import mercurial.repoview
+import mercurial.util
+import mercurial.hg
+import mercurial.ui as uimod
+
+
+# create some special property cache that trace they call
+
+calllog = []
+@mercurial.util.propertycache
+def testcachedfoobar(repo):
+ name = repo.filtername
+ if name is None:
+ name = ''
+ val = len(name)
+ calllog.append(val)
+ return val
+
+unficalllog = []
+@mercurial.localrepo.unfilteredpropertycache
+def testcachedunfifoobar(repo):
+ name = repo.filtername
+ if name is None:
+ name = ''
+ val = 100 + len(name)
+ unficalllog.append(val)
+ return val
+
+#plug them on repo
+mercurial.localrepo.localrepository.testcachedfoobar = testcachedfoobar
+mercurial.localrepo.localrepository.testcachedunfifoobar = testcachedunfifoobar
+
+
+# create an empty repo. and instanciate it. It is important to run
+# those test on the real object to detect regression.
+repopath = os.path.join(os.environ['TESTTMP'], 'repo')
+subprocess.check_call(['hg', 'init', repopath])
+ui = uimod.ui()
+repo = mercurial.hg.repository(ui, path=repopath).unfiltered()
+
+
+print ''
+print '=== property cache ==='
+print ''
+print 'calllog:', calllog
+print 'cached value (unfiltered):',
+print vars(repo).get('testcachedfoobar', 'NOCACHE')
+
+print ''
+print '= first access on unfiltered, should do a call'
+print 'access:', repo.testcachedfoobar
+print 'calllog:', calllog
+print 'cached value (unfiltered):',
+print vars(repo).get('testcachedfoobar', 'NOCACHE')
+
+print ''
+print '= second access on unfiltered, should not do call'
+print 'access', repo.testcachedfoobar
+print 'calllog:', calllog
+print 'cached value (unfiltered):',
+print vars(repo).get('testcachedfoobar', 'NOCACHE')
+
+print ''
+print '= first access on "visible" view, should do a call'
+visibleview = repo.filtered('visible')
+print 'cached value ("visible" view):',
+print vars(visibleview).get('testcachedfoobar', 'NOCACHE')
+print 'access:', visibleview.testcachedfoobar
+print 'calllog:', calllog
+print 'cached value (unfiltered):',
+print vars(repo).get('testcachedfoobar', 'NOCACHE')
+print 'cached value ("visible" view):',
+print vars(visibleview).get('testcachedfoobar', 'NOCACHE')
+
+print ''
+print '= second access on "visible view", should not do call'
+print 'access:', visibleview.testcachedfoobar
+print 'calllog:', calllog
+print 'cached value (unfiltered):',
+print vars(repo).get('testcachedfoobar', 'NOCACHE')
+print 'cached value ("visible" view):',
+print vars(visibleview).get('testcachedfoobar', 'NOCACHE')
+
+print ''
+print '= no effect on other view'
+immutableview = repo.filtered('immutable')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedfoobar', 'NOCACHE')
+print 'access:', immutableview.testcachedfoobar
+print 'calllog:', calllog
+print 'cached value (unfiltered):',
+print vars(repo).get('testcachedfoobar', 'NOCACHE')
+print 'cached value ("visible" view):',
+print vars(visibleview).get('testcachedfoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedfoobar', 'NOCACHE')
+
+# unfiltered property cache test
+print ''
+print ''
+print '=== unfiltered property cache ==='
+print ''
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("visible" view): ',
+print vars(visibleview).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedunfifoobar', 'NOCACHE')
+
+print ''
+print '= first access on unfiltered, should do a call'
+print 'access (unfiltered):', repo.testcachedunfifoobar
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+
+print ''
+print '= second access on unfiltered, should not do call'
+print 'access (unfiltered):', repo.testcachedunfifoobar
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+
+print ''
+print '= access on view should use the unfiltered cache'
+print 'access (unfiltered): ', repo.testcachedunfifoobar
+print 'access ("visible" view): ', visibleview.testcachedunfifoobar
+print 'access ("immutable" view):', immutableview.testcachedunfifoobar
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("visible" view): ',
+print vars(visibleview).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedunfifoobar', 'NOCACHE')
+
+print ''
+print '= even if we clear the unfiltered cache'
+del repo.__dict__['testcachedunfifoobar']
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("visible" view): ',
+print vars(visibleview).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedunfifoobar', 'NOCACHE')
+print 'unficalllog:', unficalllog
+print 'access ("visible" view): ', visibleview.testcachedunfifoobar
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("visible" view): ',
+print vars(visibleview).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedunfifoobar', 'NOCACHE')
+print 'access ("immutable" view):', immutableview.testcachedunfifoobar
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("visible" view): ',
+print vars(visibleview).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedunfifoobar', 'NOCACHE')
+print 'access (unfiltered): ', repo.testcachedunfifoobar
+print 'unficalllog:', unficalllog
+print 'cached value (unfiltered): ',
+print vars(repo).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("visible" view): ',
+print vars(visibleview).get('testcachedunfifoobar', 'NOCACHE')
+print 'cached value ("immutable" view):',
+print vars(immutableview).get('testcachedunfifoobar', 'NOCACHE')
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-propertycache.py.out Tue Oct 01 17:00:03 2013 -0700
@@ -0,0 +1,84 @@
+
+=== property cache ===
+
+calllog: []
+cached value (unfiltered): NOCACHE
+
+= first access on unfiltered, should do a call
+access: 0
+calllog: [0]
+cached value (unfiltered): 0
+
+= second access on unfiltered, should not do call
+access 0
+calllog: [0]
+cached value (unfiltered): 0
+
+= first access on "visible" view, should do a call
+cached value ("visible" view): NOCACHE
+access: 7
+calllog: [0, 7]
+cached value (unfiltered): 0
+cached value ("visible" view): 7
+
+= second access on "visible view", should not do call
+access: 7
+calllog: [0, 7]
+cached value (unfiltered): 0
+cached value ("visible" view): 7
+
+= no effect on other view
+cached value ("immutable" view): NOCACHE
+access: 9
+calllog: [0, 7, 9]
+cached value (unfiltered): 0
+cached value ("visible" view): 7
+cached value ("immutable" view): 9
+
+
+=== unfiltered property cache ===
+
+unficalllog: []
+cached value (unfiltered): NOCACHE
+cached value ("visible" view): NOCACHE
+cached value ("immutable" view): NOCACHE
+
+= first access on unfiltered, should do a call
+access (unfiltered): 100
+unficalllog: [100]
+cached value (unfiltered): 100
+
+= second access on unfiltered, should not do call
+access (unfiltered): 100
+unficalllog: [100]
+cached value (unfiltered): 100
+
+= access on view should use the unfiltered cache
+access (unfiltered): 100
+access ("visible" view): 100
+access ("immutable" view): 100
+unficalllog: [100]
+cached value (unfiltered): 100
+cached value ("visible" view): NOCACHE
+cached value ("immutable" view): NOCACHE
+
+= even if we clear the unfiltered cache
+cached value (unfiltered): NOCACHE
+cached value ("visible" view): NOCACHE
+cached value ("immutable" view): NOCACHE
+unficalllog: [100]
+access ("visible" view): 100
+unficalllog: [100, 100]
+cached value (unfiltered): 100
+cached value ("visible" view): NOCACHE
+cached value ("immutable" view): NOCACHE
+access ("immutable" view): 100
+unficalllog: [100, 100]
+cached value (unfiltered): 100
+cached value ("visible" view): NOCACHE
+cached value ("immutable" view): NOCACHE
+access (unfiltered): 100
+unficalllog: [100, 100]
+cached value (unfiltered): 100
+cached value ("visible" view): NOCACHE
+cached value ("immutable" view): NOCACHE
--- a/tests/test-rebase-abort.t Tue Oct 01 10:44:59 2013 -0700
+++ b/tests/test-rebase-abort.t Tue Oct 01 17:00:03 2013 -0700
@@ -75,6 +75,31 @@
|
o 0:draft 'C1'
+Test safety for inconsistent rebase state, which may be created (and
+forgotten) by Mercurial earlier than 2.7. This emulates Mercurial
+earlier than 2.7 by renaming ".hg/rebasestate" temporarily.
+
+ $ hg rebase -s 3 -d 2
+ merging common
+ warning: conflicts during merge.
+ merging common incomplete! (edit conflicts, then use 'hg resolve --mark')
+ unresolved conflicts (see hg resolve, then hg rebase --continue)
+ [1]
+
+ $ mv .hg/rebasestate .hg/rebasestate.back
+ $ hg update --quiet --clean 2
+ $ hg --config extensions.mq= strip --quiet "destination()"
+ $ mv .hg/rebasestate.back .hg/rebasestate
+
+ $ hg rebase --continue
+ abort: cannot continue inconsistent rebase
+ (use "hg rebase --abort" to clear borken state)
+ [255]
+ $ hg summary | grep '^rebase: '
+ rebase: (use "hg rebase --abort" to clear broken state)
+ $ hg rebase --abort
+ rebase aborted (no revision is removed, only broken state is cleared)
+
$ cd ..