##// 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 1313 ('', 'record-parents', False,
1314 1314 _('record parent information for the precursor')),
1315 1315 ('r', 'rev', [], _('display markers relevant to REV')),
1316 ('', 'exclusive', False, _('restrict display to markers only '
1317 'relevant to REV')),
1316 1318 ('', 'index', False, _('display index of the marker')),
1317 1319 ('', 'delete', [], _('delete markers specified by indices')),
1318 1320 ] + cmdutil.commitopts2 + cmdutil.formatteropts,
@@ -1391,7 +1393,8 b' def debugobsolete(ui, repo, precursor=No'
1391 1393 if opts['rev']:
1392 1394 revs = scmutil.revrange(repo, opts['rev'])
1393 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 1398 markers.sort(key=lambda x: x._data)
1396 1399 else:
1397 1400 markers = obsolete.getmarkers(repo)
@@ -737,6 +737,129 b' class obsstore(object):'
737 737 seennodes |= pendingnodes
738 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 863 def commonversion(versions):
741 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 927 finally:
805 928 lock.release()
806 929
807 def getmarkers(repo, nodes=None):
930 def getmarkers(repo, nodes=None, exclusive=False):
808 931 """returns markers known in a repository
809 932
810 933 If <nodes> is specified, only markers "relevant" to those nodes are are
811 934 returned"""
812 935 if nodes is None:
813 936 rawmarkers = repo.obsstore
937 elif exclusive:
938 rawmarkers = exclusivemarkers(repo, nodes)
814 939 else:
815 940 rawmarkers = repo.obsstore.relevantmarkers(nodes)
816 941
@@ -272,7 +272,7 b' Show all commands + options'
272 272 debuglocks: force-lock, force-wlock
273 273 debugmergestate:
274 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 276 debugpathcomplete: full, normal, added, removed
277 277 debugpickmergetool: rev, changedelete, include, exclude, tool
278 278 debugpushkey:
@@ -267,6 +267,42 b' We need to create a clone of 5 and add a'
267 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 306 $ cd ..
271 307
272 308 Revision 0 is hidden
General Comments 0
You need to be logged in to leave comments. Login now