##// END OF EJS Templates
obsolete: add a function to compute "exclusive-markers" for a set of nodes...
marmoute -
r32626:00a7f7b1 default
parent child Browse files
Show More
@@ -1313,6 +1313,8 b' def debugnamecomplete(ui, repo, *args):'
1313 ('', 'record-parents', False,
1313 ('', 'record-parents', False,
1314 _('record parent information for the precursor')),
1314 _('record parent information for the precursor')),
1315 ('r', 'rev', [], _('display markers relevant to REV')),
1315 ('r', 'rev', [], _('display markers relevant to REV')),
1316 ('', 'exclusive', False, _('restrict display to markers only '
1317 'relevant to REV')),
1316 ('', 'index', False, _('display index of the marker')),
1318 ('', 'index', False, _('display index of the marker')),
1317 ('', 'delete', [], _('delete markers specified by indices')),
1319 ('', 'delete', [], _('delete markers specified by indices')),
1318 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
1320 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
@@ -1391,7 +1393,8 b' def debugobsolete(ui, repo, precursor=No'
1391 if opts['rev']:
1393 if opts['rev']:
1392 revs = scmutil.revrange(repo, opts['rev'])
1394 revs = scmutil.revrange(repo, opts['rev'])
1393 nodes = [repo[r].node() for r in revs]
1395 nodes = [repo[r].node() for r in revs]
1394 markers = list(obsolete.getmarkers(repo, nodes=nodes))
1396 markers = list(obsolete.getmarkers(repo, nodes=nodes,
1397 exclusive=opts['exclusive']))
1395 markers.sort(key=lambda x: x._data)
1398 markers.sort(key=lambda x: x._data)
1396 else:
1399 else:
1397 markers = obsolete.getmarkers(repo)
1400 markers = obsolete.getmarkers(repo)
@@ -737,6 +737,129 b' class obsstore(object):'
737 seennodes |= pendingnodes
737 seennodes |= pendingnodes
738 return seenmarkers
738 return seenmarkers
739
739
740 def _filterprunes(markers):
741 """return a set with no prune markers"""
742 return set(m for m in markers if m[1])
743
744 def exclusivemarkers(repo, nodes):
745 """set of markers relevant to "nodes" but no other locally-known nodes
746
747 This function compute the set of markers "exclusive" to a locally-known
748 node. This means we walk the markers starting from <nodes> until we reach a
749 locally-known precursors outside of <nodes>. Element of <nodes> with
750 locally-known successors outside of <nodes> are ignored (since their
751 precursors markers are also relevant to these successors).
752
753 For example:
754
755 # (A0 rewritten as A1)
756 #
757 # A0 <-1- A1 # Marker "1" is exclusive to A1
758
759 or
760
761 # (A0 rewritten as AX; AX rewritten as A1; AX is unkown locally)
762 #
763 # <-1- A0 <-2- AX <-3- A1 # Marker "2,3" are exclusive to A1
764
765 or
766
767 # (A0 has unknown precursors, A0 rewritten as A1 and A2 (divergence))
768 #
769 # <-2- A1 # Marker "2" is exclusive to A0,A1
770 # /
771 # <-1- A0
772 # \
773 # <-3- A2 # Marker "3" is exclusive to A0,A2
774 #
775 # in addition:
776 #
777 # Markers "2,3" are exclusive to A1,A2
778 # Markers "1,2,3" are exclusive to A0,A1,A2
779
780 An example usage is strip. When stripping a changeset, we also want to
781 strip the markers exclusive to this changeset. Otherwise we would have
782 "dangling"" obsolescence markers from its precursors: Obsolescence markers
783 marking a node as obsolete without any successors available locally.
784
785 As for relevant markers, the prune markers for children will be followed.
786 Of course, they will only be followed if the pruned children is
787 locally-known. Since the prune markers are relevant to the pruned node.
788 However, while prune markers are considered relevant to the parent of the
789 pruned changesets, prune markers for locally-known changeset (with no
790 successors) are considered exclusive to the pruned nodes. This allows
791 to strip the prune markers (with the rest of the exclusive chain) alongside
792 the pruned changesets.
793 """
794 # running on a filtered repository would be dangerous as markers could be
795 # reported as exclusive when they are relevant for other filtered nodes.
796 unfi = repo.unfiltered()
797
798 # shortcut to various useful item
799 nm = unfi.changelog.nodemap
800 precursorsmarkers = unfi.obsstore.precursors
801 successormarkers = unfi.obsstore.successors
802 childrenmarkers = unfi.obsstore.children
803
804 # exclusive markers (return of the function)
805 exclmarkers = set()
806 # we need fast membership testing
807 nodes = set(nodes)
808 # looking for head in the obshistory
809 #
810 # XXX we are ignoring all issues in regard with cycle for now.
811 stack = [n for n in nodes if not _filterprunes(successormarkers.get(n, ()))]
812 stack.sort()
813 # nodes already stacked
814 seennodes = set(stack)
815 while stack:
816 current = stack.pop()
817 # fetch precursors markers
818 markers = list(precursorsmarkers.get(current, ()))
819 # extend the list with prune markers
820 for mark in successormarkers.get(current, ()):
821 if not mark[1]:
822 markers.append(mark)
823 # and markers from children (looking for prune)
824 for mark in childrenmarkers.get(current, ()):
825 if not mark[1]:
826 markers.append(mark)
827 # traverse the markers
828 for mark in markers:
829 if mark in exclmarkers:
830 # markers already selected
831 continue
832
833 # If the markers is about the current node, select it
834 #
835 # (this delay the addition of markers from children)
836 if mark[1] or mark[0] == current:
837 exclmarkers.add(mark)
838
839 # should we keep traversing through the precursors?
840 prec = mark[0]
841
842 # nodes in the stack or already processed
843 if prec in seennodes:
844 continue
845
846 # is this a locally known node ?
847 known = prec in nm
848 # if locally-known and not in the <nodes> set the traversal
849 # stop here.
850 if known and prec not in nodes:
851 continue
852
853 # do not keep going if there are unselected markers pointing to this
854 # nodes. If we end up traversing these unselected markers later the
855 # node will be taken care of at that point.
856 precmarkers = _filterprunes(successormarkers.get(prec))
857 if precmarkers.issubset(exclmarkers):
858 seennodes.add(prec)
859 stack.append(prec)
860
861 return exclmarkers
862
740 def commonversion(versions):
863 def commonversion(versions):
741 """Return the newest version listed in both versions and our local formats.
864 """Return the newest version listed in both versions and our local formats.
742
865
@@ -804,13 +927,15 b' def pushmarker(repo, key, old, new):'
804 finally:
927 finally:
805 lock.release()
928 lock.release()
806
929
807 def getmarkers(repo, nodes=None):
930 def getmarkers(repo, nodes=None, exclusive=False):
808 """returns markers known in a repository
931 """returns markers known in a repository
809
932
810 If <nodes> is specified, only markers "relevant" to those nodes are are
933 If <nodes> is specified, only markers "relevant" to those nodes are are
811 returned"""
934 returned"""
812 if nodes is None:
935 if nodes is None:
813 rawmarkers = repo.obsstore
936 rawmarkers = repo.obsstore
937 elif exclusive:
938 rawmarkers = exclusivemarkers(repo, nodes)
814 else:
939 else:
815 rawmarkers = repo.obsstore.relevantmarkers(nodes)
940 rawmarkers = repo.obsstore.relevantmarkers(nodes)
816
941
@@ -272,7 +272,7 b' Show all commands + options'
272 debuglocks: force-lock, force-wlock
272 debuglocks: force-lock, force-wlock
273 debugmergestate:
273 debugmergestate:
274 debugnamecomplete:
274 debugnamecomplete:
275 debugobsolete: flags, record-parents, rev, index, delete, date, user, template
275 debugobsolete: flags, record-parents, rev, exclusive, index, delete, date, user, template
276 debugpathcomplete: full, normal, added, removed
276 debugpathcomplete: full, normal, added, removed
277 debugpickmergetool: rev, changedelete, include, exclude, tool
277 debugpickmergetool: rev, changedelete, include, exclude, tool
278 debugpushkey:
278 debugpushkey:
@@ -267,6 +267,42 b' We need to create a clone of 5 and add a'
267 o 0:1f0dee641bb7 (public) [ ] add a
267 o 0:1f0dee641bb7 (public) [ ] add a
268
268
269
269
270 Basic exclusive testing
271
272 $ hg log -G --hidden
273 @ 6:6f9641995072 (draft) [tip ] add n3w_3_c
274 |
275 | x 5:5601fb93a350 (draft *obsolete*) [ ] add new_3_c
276 |/
277 | x 4:ca819180edb9 (draft *obsolete*) [ ] add new_2_c
278 |/
279 | x 3:cdbce2fbb163 (draft *obsolete*) [ ] add new_c
280 |/
281 | o 2:245bde4270cd (public) [ ] add original_c
282 |/
283 o 1:7c3bad9141dc (public) [ ] add b
284 |
285 o 0:1f0dee641bb7 (public) [ ] add a
286
287 $ hg debugobsolete --rev 6f9641995072
288 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
289 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
290 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
291 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
292 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
293 $ hg debugobsolete --rev 6f9641995072 --exclusive
294 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
295 $ hg debugobsolete --rev 5601fb93a350 --hidden
296 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
297 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C (Thu Jan 01 00:00:01 1970 -0002) {'user': 'test'}
298 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
299 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 (Thu Jan 01 00:22:17 1970 +0000) {'user': 'test'}
300 $ hg debugobsolete --rev 5601fb93a350 --hidden --exclusive
301 $ hg debugobsolete --rev 5601fb93a350+6f9641995072 --hidden --exclusive
302 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 (Thu Jan 01 00:22:19 1970 +0000) {'user': 'test'}
303 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
304 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 (Thu Jan 01 00:22:18 1970 +0000) {'user': 'test'}
305
270 $ cd ..
306 $ cd ..
271
307
272 Revision 0 is hidden
308 Revision 0 is hidden
General Comments 0
You need to be logged in to leave comments. Login now