Mercurial > hg
changeset 23970:8a544fb645bb stable
rebase: ensure rebase revision remains visible (issue4504)
Before this changeset rebase was getting very confused if any revision in the
rebase set became hidden. This was fairly easy to achieve if a rebased revision
was made visible by the working copy location. The rebase process would update
somewhere else and the revision would become hidden.
To work around this issue, we ensure rebased revisions remain visible for the
whole process.
This is a simple change suitable for stable. More subtle usage of unfiltered
repository in rebase may solve this issue more cleanly.
author | Pierre-Yves David <pierre-yves.david@fb.com> |
---|---|
date | Tue, 27 Jan 2015 12:33:56 +0000 |
parents | 01e5b7323a48 |
children | 6becb9dbca25 9a391d720cf9 |
files | hgext/rebase.py tests/test-rebase-obsolete.t |
diffstat | 2 files changed, 75 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/hgext/rebase.py Wed Jan 28 02:28:39 2015 +0100 +++ b/hgext/rebase.py Tue Jan 27 12:33:56 2015 +0000 @@ -16,7 +16,7 @@ from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks from mercurial import extensions, patch, scmutil, phases, obsolete, error -from mercurial import copies +from mercurial import copies, repoview from mercurial.commands import templateopts from mercurial.node import nullrev, nullid, hex, short from mercurial.lock import release @@ -778,6 +778,7 @@ def clearstatus(repo): 'Remove the status files' + _clearrebasesetvisibiliy(repo) util.unlinkpath(repo.join("rebasestate"), ignoremissing=True) def restorestatus(repo): @@ -831,6 +832,7 @@ repo.ui.debug('computed skipped revs: %s\n' % (' '.join(str(r) for r in sorted(skipped)) or None)) repo.ui.debug('rebase status resumed\n') + _setrebasesetvisibility(repo, state.keys()) return (originalwd, target, state, skipped, collapse, keep, keepbranches, external, activebookmark) except IOError, err: @@ -892,6 +894,7 @@ dest: context rebaseset: set of rev ''' + _setrebasesetvisibility(repo, rebaseset) # This check isn't strictly necessary, since mq detects commits over an # applied patch. But it prevents messing up the working directory when @@ -1044,6 +1047,31 @@ raise util.Abort(_('--tool can only be used with --rebase')) orig(ui, repo, *args, **opts) +def _setrebasesetvisibility(repo, revs): + """store the currently rebased set on the repo object + + This is used by another function to prevent rebased revision to because + hidden (see issue4505)""" + repo = repo.unfiltered() + revs = set(revs) + repo._rebaseset = revs + # invalidate cache if visibility changes + hiddens = repo.filteredrevcache.get('visible', set()) + if revs & hiddens: + repo.invalidatevolatilesets() + +def _clearrebasesetvisibiliy(repo): + """remove rebaseset data from the repo""" + repo = repo.unfiltered() + if '_rebaseset' in vars(repo): + del repo._rebaseset + +def _rebasedvisible(orig, repo): + """ensure rebased revs stay visible (see issue4505)""" + blockers = orig(repo) + blockers.update(getattr(repo, '_rebaseset', ())) + return blockers + def summaryhook(ui, repo): if not os.path.exists(repo.join('rebasestate')): return @@ -1062,7 +1090,7 @@ (len(state) - numrebased))) def uisetup(ui): - 'Replace pull with a decorator to provide --rebase option' + #Replace pull with a decorator to provide --rebase option entry = extensions.wrapcommand(commands.table, 'pull', pullrebase) entry[1].append(('', 'rebase', None, _("rebase working directory to branch head"))) @@ -1072,3 +1100,6 @@ cmdutil.unfinishedstates.append( ['rebasestate', False, False, _('rebase in progress'), _("use 'hg rebase --continue' or 'hg rebase --abort'")]) + # ensure rebased rev are not hidden + extensions.wrapfunction(repoview, '_getdynamicblockers', _rebasedvisible) +
--- a/tests/test-rebase-obsolete.t Wed Jan 28 02:28:39 2015 +0100 +++ b/tests/test-rebase-obsolete.t Tue Jan 27 12:33:56 2015 +0000 @@ -498,3 +498,45 @@ |/ o 0:cd010b8cd998 A + +Test hidden changesets in the rebase set (issue4504) + + $ hg up --hidden 9 + 3 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo J > J + $ hg add J + $ hg commit -m J + $ hg debugobsolete `hg log --rev . -T '{node}'` + + $ hg rebase --rev .~1::. --dest 'max(desc(D))' --traceback + rebasing 9:4bde274eefcf "I" + rebasing 13:06edfc82198f "J" (tip) + $ hg log -G + @ 15:5ae8a643467b J + | + o 14:9ad579b4a5de I + | + | o 12:acd174b7ab39 I + | | + | o 11:6c11a6218c97 H + | | + o | 10:b5313c85b22e D + |/ + | o 8:53a6a128b2b7 M + | |\ + | | x 7:02de42196ebe H + | | | + o---+ 6:eea13746799a G + | | | + | | o 5:24b6387c8c8c F + | | | + o---+ 4:9520eea781bc E + / / + x | 3:32af7686d403 D + | | + o | 2:5fddd98957c8 C + | | + o | 1:42ccdea3bb16 B + |/ + o 0:cd010b8cd998 A +