# HG changeset patch # User Constantine Linnick # Date 1364058412 -25200 # Node ID 05acdf8e1f233a24917ff9d65fd1b3f323287a28 # Parent a0bff3d4f67b6b6c8e81074672533e0ee3f17d05 convert: add closesort algorithm to mercurial sources If you actively work with branches, sometimes you need to close old branches which last commited hundreds revisions ago. After close you will see long lines in graph visually spoiling history. This sort only moves closed revisions as close as possible to parents and does not increase storage size as datesort do. diff -r a0bff3d4f67b -r 05acdf8e1f23 hgext/convert/__init__.py --- a/hgext/convert/__init__.py Sun Mar 24 16:43:25 2013 -0700 +++ b/hgext/convert/__init__.py Sun Mar 24 00:06:52 2013 +0700 @@ -61,6 +61,10 @@ --sourcesort try to preserve source revisions order, only supported by Mercurial sources. + --closesort try to move closed revisions as close as possible + to parent branches, only supported by Mercurial + sources. + If ``REVMAP`` isn't given, it will be put in a default location (``/.hg/shamap`` by default). The ``REVMAP`` is a simple text file that maps each source commit ID to the destination ID @@ -318,7 +322,8 @@ _('change branch names while converting'), _('FILE')), ('', 'branchsort', None, _('try to sort changesets by branches')), ('', 'datesort', None, _('try to sort changesets by date')), - ('', 'sourcesort', None, _('preserve source changesets order'))], + ('', 'sourcesort', None, _('preserve source changesets order')), + ('', 'closesort', None, _('try to reorder closed revisions'))], _('hg convert [OPTION]... SOURCE [DEST [REVMAP]]')), "debugsvnlog": (debugsvnlog, diff -r a0bff3d4f67b -r 05acdf8e1f23 hgext/convert/common.py --- a/hgext/convert/common.py Sun Mar 24 16:43:25 2013 -0700 +++ b/hgext/convert/common.py Sun Mar 24 00:06:52 2013 +0700 @@ -145,6 +145,11 @@ """ return False + def hasnativeclose(self): + """Return true if this source has ability to close branch. + """ + return False + def lookuprev(self, rev): """If rev is a meaningful revision reference in source, return the referenced identifier in the same format used by getcommit(). diff -r a0bff3d4f67b -r 05acdf8e1f23 hgext/convert/convcmd.py --- a/hgext/convert/convcmd.py Sun Mar 24 16:43:25 2013 -0700 +++ b/hgext/convert/convcmd.py Sun Mar 24 00:06:52 2013 +0700 @@ -227,6 +227,14 @@ return sorted(nodes, key=keyfn)[0] return picknext + def makeclosesorter(): + """Close order sort.""" + keyfn = lambda n: ('close' not in self.commitcache[n].extra, + self.commitcache[n].sortkey) + def picknext(nodes): + return sorted(nodes, key=keyfn)[0] + return picknext + def makedatesorter(): """Sort revisions by date.""" dates = {} @@ -246,6 +254,8 @@ picknext = makedatesorter() elif sortmode == 'sourcesort': picknext = makesourcesorter() + elif sortmode == 'closesort': + picknext = makeclosesorter() else: raise util.Abort(_('unknown sort mode: %s') % sortmode) @@ -446,13 +456,15 @@ shutil.rmtree(path, True) raise - sortmodes = ('branchsort', 'datesort', 'sourcesort') + sortmodes = ('branchsort', 'datesort', 'sourcesort', 'closesort') sortmode = [m for m in sortmodes if opts.get(m)] if len(sortmode) > 1: raise util.Abort(_('more than one sort mode specified')) sortmode = sortmode and sortmode[0] or defaultsort if sortmode == 'sourcesort' and not srcc.hasnativeorder(): raise util.Abort(_('--sourcesort is not supported by this data source')) + if sortmode == 'closesort' and not srcc.hasnativeclose(): + raise util.Abort(_('--closesort is not supported by this data source')) fmap = opts.get('filemap') if fmap: diff -r a0bff3d4f67b -r 05acdf8e1f23 hgext/convert/hg.py --- a/hgext/convert/hg.py Sun Mar 24 16:43:25 2013 -0700 +++ b/hgext/convert/hg.py Sun Mar 24 00:06:52 2013 +0700 @@ -386,6 +386,9 @@ def hasnativeorder(self): return True + def hasnativeclose(self): + return True + def lookuprev(self, rev): try: return hex(self.repo.lookup(rev)) diff -r a0bff3d4f67b -r 05acdf8e1f23 tests/test-convert-datesort.t --- a/tests/test-convert-datesort.t Sun Mar 24 16:43:25 2013 -0700 +++ b/tests/test-convert-datesort.t Sun Mar 24 00:06:52 2013 +0700 @@ -38,6 +38,26 @@ 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ echo b >> b $ hg ci -m b1 -d '9 0' + $ hg up -C 0 + 0 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ echo c >> c + $ hg branch branchc + marked working directory as branch branchc + (branches are permanent and global, did you want a bookmark?) + $ hg ci -Am c0 -d '10 0' + adding c + $ hg up -C brancha + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg ci --close-branch -m a7x -d '11 0' + $ hg up -C branchb + 2 files updated, 0 files merged, 0 files removed, 0 files unresolved + $ hg ci --close-branch -m b2x -d '12 0' + $ hg up -C branchc + 1 files updated, 0 files merged, 1 files removed, 0 files unresolved + $ hg merge branchb + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg ci -m c1 -d '13 0' $ cd .. convert with datesort @@ -47,27 +67,39 @@ scanning source... sorting... converting... - 8 a0 - 7 a1 - 6 a2 - 5 a3 - 4 a4 - 3 b0 - 2 a5 - 1 a6 - 0 b1 + 12 a0 + 11 a1 + 10 a2 + 9 a3 + 8 a4 + 7 b0 + 6 a5 + 5 a6 + 4 b1 + 3 c0 + 2 a7x + 1 b2x + 0 c1 graph converted repo $ hg -R t-datesort glog --template '{rev} "{desc}"\n' - o 8 "b1" - | - | o 7 "a6" + o 12 "c1" + |\ + | o 11 "b2x" | | - | o 6 "a5" - | | - o | 5 "b0" - | | + | | o 10 "a7x" + | | | + o | | 9 "c0" + | | | + | o | 8 "b1" + | | | + | | o 7 "a6" + | | | + | | o 6 "a5" + | | | + | o | 5 "b0" + |/ / | o 4 "a4" | | | o 3 "a3" @@ -86,29 +118,41 @@ scanning source... sorting... converting... - 8 a0 - 7 a1 - 6 a2 - 5 a3 - 4 b0 - 3 a4 - 2 a5 - 1 a6 - 0 b1 + 12 a0 + 11 a1 + 10 a2 + 9 a3 + 8 b0 + 7 a4 + 6 a5 + 5 a6 + 4 b1 + 3 c0 + 2 a7x + 1 b2x + 0 c1 graph converted repo $ hg -R t-sourcesort glog --template '{rev} "{desc}"\n' - o 8 "b1" - | - | o 7 "a6" + o 12 "c1" + |\ + | o 11 "b2x" | | - | o 6 "a5" - | | - | o 5 "a4" - | | - o | 4 "b0" - | | + | | o 10 "a7x" + | | | + o | | 9 "c0" + | | | + | o | 8 "b1" + | | | + | | o 7 "a6" + | | | + | | o 6 "a5" + | | | + | | o 5 "a4" + | | | + | o | 4 "b0" + |/ / | o 3 "a3" | | | o 2 "a2" @@ -117,3 +161,54 @@ |/ o 0 "a0" + +convert with closesort + + $ hg convert --closesort t t-closesort + initializing destination t-closesort repository + scanning source... + sorting... + converting... + 12 a0 + 11 a1 + 10 a2 + 9 a3 + 8 b0 + 7 a4 + 6 a5 + 5 a6 + 4 a7x + 3 b1 + 2 b2x + 1 c0 + 0 c1 + +graph converted repo + + $ hg -R t-closesort glog --template '{rev} "{desc}"\n' + o 12 "c1" + |\ + | o 11 "c0" + | | + o | 10 "b2x" + | | + o | 9 "b1" + | | + | | o 8 "a7x" + | | | + | | o 7 "a6" + | | | + | | o 6 "a5" + | | | + | | o 5 "a4" + | | | + o | | 4 "b0" + |/ / + | o 3 "a3" + | | + | o 2 "a2" + | | + | o 1 "a1" + |/ + o 0 "a0" + diff -r a0bff3d4f67b -r 05acdf8e1f23 tests/test-convert.t --- a/tests/test-convert.t Sun Mar 24 16:43:25 2013 -0700 +++ b/tests/test-convert.t Sun Mar 24 00:06:52 2013 +0700 @@ -46,6 +46,8 @@ larger than the same ones generated by --branchsort. --sourcesort try to preserve source revisions order, only supported by Mercurial sources. + --closesort try to move closed revisions as close as possible to parent + branches, only supported by Mercurial sources. If "REVMAP" isn't given, it will be put in a default location ("/.hg/shamap" by default). The "REVMAP" is a simple text file that @@ -268,6 +270,7 @@ --branchsort try to sort changesets by branches --datesort try to sort changesets by date --sourcesort preserve source changesets order + --closesort try to reorder closed revisions use "hg -v help convert" to show the global options $ hg init a