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