rebase: allow creation obsolescence relation instead of stripping

When obsolescence feature is enabled we now create markers from the rebased
set to the resulting set instead of stripping. The "state" mapping built by
rebase holds all necessary data.

Changesets "deleted" by the rebase are marked "succeeded" by the changeset they
would be rebased one. That the best guess of "successors" we have. Getting a
successors as meaningful as possible is important for automatic resolution of
obsolescence troubles. In other word, emptied changeset will looks collapsed
with their former parents. (see "empty changeset" section of the test if you are
still confused)
This commit is contained in:
Pierre-Yves David 2012-09-18 23:13:31 +02:00
parent f0bddab386
commit be6378e49d
2 changed files with 192 additions and 9 deletions

View File

@ -15,7 +15,7 @@ http://mercurial.selenic.com/wiki/RebaseExtension
'''
from mercurial import hg, util, repair, merge, cmdutil, commands, bookmarks
from mercurial import extensions, patch, scmutil, phases
from mercurial import extensions, patch, scmutil, phases, obsolete
from mercurial.commands import templateopts
from mercurial.node import nullrev
from mercurial.lock import release
@ -658,14 +658,22 @@ def buildstate(repo, dest, rebaseset, collapse):
def clearrebased(ui, repo, state):
"""dispose of rebased revision at the end of the rebase"""
rebased = [rev for rev in state if state[rev] != nullmerge]
if rebased:
if set(repo.changelog.descendants([min(rebased)])) - set(state):
ui.warn(_("warning: new changesets detected "
"on source branch, not stripping\n"))
else:
# backup the old csets by default
repair.strip(ui, repo, repo[min(rebased)].node(), "all")
if obsolete._enabled:
markers = []
for rev, newrev in sorted(state.items()):
if newrev >= 0:
markers.append((repo[rev], (repo[newrev],)))
if markers:
obsolete.createmarkers(repo, markers)
else:
rebased = [rev for rev in state if state[rev] != nullmerge]
if rebased:
if set(repo.changelog.descendants([min(rebased)])) - set(state):
ui.warn(_("warning: new changesets detected "
"on source branch, not stripping\n"))
else:
# backup the old csets by default
repair.strip(ui, repo, repo[min(rebased)].node(), "all")
def pullrebase(orig, ui, repo, *args, **opts):

View File

@ -0,0 +1,175 @@
==========================
Test rebase with obsolete
==========================
Enable obsolete
$ cat > ${TESTTMP}/obs.py << EOF
> import mercurial.obsolete
> mercurial.obsolete._enabled = True
> EOF
$ cat >> $HGRCPATH << EOF
> [ui]
> logtemplate= {rev}:{node|short} {desc|firstline}
> [phases]
> publish=False
> [extensions]'
> rebase=
>
> obs=${TESTTMP}/obs.py
> EOF
Setup rebase canonical repo
$ hg init base
$ cd base
$ hg unbundle "$TESTDIR/bundles/rebase.hg"
adding changesets
adding manifests
adding file changes
added 8 changesets with 7 changes to 7 files (+2 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)
$ hg up tip
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg log -G
@ 7:02de42196ebe H
|
| o 6:eea13746799a G
|/|
o | 5:24b6387c8c8c F
| |
| o 4:9520eea781bc E
|/
| o 3:32af7686d403 D
| |
| o 2:5fddd98957c8 C
| |
| o 1:42ccdea3bb16 B
|/
o 0:cd010b8cd998 A
$ cd ..
simple rebase
---------------------------------
$ hg clone base simple
updating to branch default
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd simple
$ hg up 32af7686d403
3 files updated, 0 files merged, 2 files removed, 0 files unresolved
$ hg rebase -d eea13746799a
$ hg log -G
@ 10:8eeb3c33ad33 D
|
o 9:2327fea05063 C
|
o 8:e4e5be0395b2 B
|
| o 7:02de42196ebe H
| |
o | 6:eea13746799a G
|\|
| o 5:24b6387c8c8c F
| |
o | 4:9520eea781bc E
|/
o 0:cd010b8cd998 A
$ hg log --hidden -G
@ 10:8eeb3c33ad33 D
|
o 9:2327fea05063 C
|
o 8:e4e5be0395b2 B
|
| o 7:02de42196ebe H
| |
o | 6:eea13746799a G
|\|
| o 5:24b6387c8c8c F
| |
o | 4:9520eea781bc E
|/
| x 3:32af7686d403 D
| |
| x 2:5fddd98957c8 C
| |
| x 1:42ccdea3bb16 B
|/
o 0:cd010b8cd998 A
$ hg debugobsolete
42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 e4e5be0395b2cbd471ed22a26b1b6a1a0658a794 0 {'date': '*', 'user': 'test'} (glob)
5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 2327fea05063f39961b14cb69435a9898dc9a245 0 {'date': '*', 'user': 'test'} (glob)
32af7686d403cf45b5d95f2d70cebea587ac806a 8eeb3c33ad33d452c89e5dcf611c347f978fb42b 0 {'date': '*', 'user': 'test'} (glob)
$ cd ..
empty changeset
---------------------------------
$ hg clone base empty
updating to branch default
3 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ cd empty
$ hg up eea13746799a
1 files updated, 0 files merged, 1 files removed, 0 files unresolved
We make a copy of both the first changeset in the rebased and some other in the
set.
$ hg graft 42ccdea3bb16 32af7686d403
grafting revision 1
grafting revision 3
$ hg rebase -s 42ccdea3bb16 -d .
$ hg log -G
@ 10:5ae4c968c6ac C
|
o 9:08483444fef9 D
|
o 8:8877864f1edb B
|
| o 7:02de42196ebe H
| |
o | 6:eea13746799a G
|\|
| o 5:24b6387c8c8c F
| |
o | 4:9520eea781bc E
|/
o 0:cd010b8cd998 A
$ hg log --hidden -G
@ 10:5ae4c968c6ac C
|
o 9:08483444fef9 D
|
o 8:8877864f1edb B
|
| o 7:02de42196ebe H
| |
o | 6:eea13746799a G
|\|
| o 5:24b6387c8c8c F
| |
o | 4:9520eea781bc E
|/
| x 3:32af7686d403 D
| |
| x 2:5fddd98957c8 C
| |
| x 1:42ccdea3bb16 B
|/
o 0:cd010b8cd998 A
$ hg debugobsolete
42ccdea3bb16d28e1848c95fe2e44c000f3f21b1 08483444fef91d6224f6655ee586a65d263ad34c 0 {'date': '*', 'user': 'test'} (glob)
5fddd98957c8a54a4d436dfe1da9d87f21a1b97b 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '*', 'user': 'test'} (glob)
32af7686d403cf45b5d95f2d70cebea587ac806a 5ae4c968c6aca831df823664e706c9d4aa34473d 0 {'date': '*', 'user': 'test'} (glob)
$ cd ..