Merge lp:~jameinel/bzr/2.0rc2-419241-merge-sort into lp:bzr/2.0

Proposed by John A Meinel
Status: Merged
Merged at revision: not available
Proposed branch: lp:~jameinel/bzr/2.0rc2-419241-merge-sort
Merge into: lp:bzr/2.0
Diff against target: 160 lines
To merge this branch: bzr merge lp:~jameinel/bzr/2.0rc2-419241-merge-sort
Reviewer Review Type Date Requested Status
Vincent Ladeuil Approve
Review via email: mp+10755@code.launchpad.net
To post a comment you must log in.
Revision history for this message
John A Meinel (jameinel) wrote :

This fixes a bug in KnownGraph.merge_sort() when there is a ghost as a mainline parent.

The old code didn't notice because we always pruned ghosts when passing in the parent_map, but it seems nicer to have merge_sort handle them directly. (Means fewer calls to _strip_NULL_ghosts :).

This is part of a critical regression right now for stuff like 'bzr log' on branches with mainline ghosts.

The second (more critical) part is coming soon.

(The code is built on the 2.0 release branch so it can be merged there primarily.)

Revision history for this message
Vincent Ladeuil (vila) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2009-08-26 12:54:21 +0000
+++ NEWS 2009-08-26 16:35:14 +0000
@@ -6,6 +6,17 @@
6.. contents:: List of Releases6.. contents:: List of Releases
7 :depth: 17 :depth: 1
88
9bzr 2.0rc2
10##########
11
12Bug Fixes
13*********
14
15* Fix a potential segmentation fault when doing 'log' of a branch that had
16 ghosts in its mainline. (evaluating None as a tuple is bad.)
17 (John Arbash Meinel, #419241)
18
19
9bzr 2.0rc120bzr 2.0rc1
10##########21##########
1122
1223
=== modified file 'bzrlib/_known_graph_pyx.pyx'
--- bzrlib/_known_graph_pyx.pyx 2009-08-18 21:41:08 +0000
+++ bzrlib/_known_graph_pyx.pyx 2009-08-26 16:35:14 +0000
@@ -443,7 +443,8 @@
443 self.completed = 0443 self.completed = 0
444444
445 def __repr__(self):445 def __repr__(self):
446 return '%s(depth:%s rev:%s,%s,%s first:%s seen:%s)' % (self.__class__.__name__,446 return '%s(%s depth:%s rev:%s,%s,%s first:%s seen:%s)' % (
447 self.__class__.__name__, self.key,
447 self.merge_depth,448 self.merge_depth,
448 self._revno_first, self._revno_second, self._revno_last,449 self._revno_first, self._revno_second, self._revno_last,
449 self.is_first_child, self.seen_by_child)450 self.is_first_child, self.seen_by_child)
@@ -497,7 +498,6 @@
497 if (tip_key is not None and tip_key != NULL_REVISION498 if (tip_key is not None and tip_key != NULL_REVISION
498 and tip_key != (NULL_REVISION,)):499 and tip_key != (NULL_REVISION,)):
499 node = self.graph._nodes[tip_key]500 node = self.graph._nodes[tip_key]
500 self._get_ms_node(node)
501 self._push_node(node, 0)501 self._push_node(node, 0)
502502
503 cdef _MergeSortNode _get_ms_node(self, _KnownGraphNode node):503 cdef _MergeSortNode _get_ms_node(self, _KnownGraphNode node):
@@ -518,10 +518,17 @@
518518
519 ms_node = self._get_ms_node(node)519 ms_node = self._get_ms_node(node)
520 ms_node.merge_depth = merge_depth520 ms_node.merge_depth = merge_depth
521 if node.parents is None:
522 raise RuntimeError('ghost nodes should not be pushed'
523 ' onto the stack: %s' % (node,))
521 if PyTuple_GET_SIZE(node.parents) > 0:524 if PyTuple_GET_SIZE(node.parents) > 0:
522 parent_node = _get_parent(node.parents, 0)525 parent_node = _get_parent(node.parents, 0)
523 ms_node.left_parent = parent_node526 ms_node.left_parent = parent_node
524 ms_node.left_pending_parent = parent_node527 if parent_node.parents is None: # left-hand ghost
528 ms_node.left_pending_parent = None
529 ms_node.left_parent = None
530 else:
531 ms_node.left_pending_parent = parent_node
525 if PyTuple_GET_SIZE(node.parents) > 1:532 if PyTuple_GET_SIZE(node.parents) > 1:
526 ms_node.pending_parents = []533 ms_node.pending_parents = []
527 for pos from 1 <= pos < PyTuple_GET_SIZE(node.parents):534 for pos from 1 <= pos < PyTuple_GET_SIZE(node.parents):
528535
=== modified file 'bzrlib/tests/test__known_graph.py'
--- bzrlib/tests/test__known_graph.py 2009-08-18 21:41:08 +0000
+++ bzrlib/tests/test__known_graph.py 2009-08-26 16:35:14 +0000
@@ -731,6 +731,20 @@
731 ('A', 0, (1,), True),731 ('A', 0, (1,), True),
732 ])732 ])
733733
734 def test_lefthand_ghost(self):
735 # ghost
736 # |
737 # A
738 # |
739 # B
740 self.assertSortAndIterate(
741 {'A': ['ghost'],
742 'B': ['A'],
743 }, 'B',
744 [('B', 0, (2,), False),
745 ('A', 0, (1,), True),
746 ])
747
734 def test_graph_cycle(self):748 def test_graph_cycle(self):
735 # merge_sort should fail with a simple error when a graph cycle is749 # merge_sort should fail with a simple error when a graph cycle is
736 # encountered.750 # encountered.
737751
=== modified file 'bzrlib/tsort.py'
--- bzrlib/tsort.py 2009-08-19 16:23:39 +0000
+++ bzrlib/tsort.py 2009-08-26 16:35:14 +0000
@@ -459,9 +459,15 @@
459 left_subtree_pushed_stack_append(False)459 left_subtree_pushed_stack_append(False)
460 pending_parents_stack_append(list(parents))460 pending_parents_stack_append(list(parents))
461 # as we push it, check if it is the first child461 # as we push it, check if it is the first child
462 parent_info = None
462 if parents:463 if parents:
463 # node has parents, assign from the left most parent.464 # node has parents, assign from the left most parent.
464 parent_info = revnos[parents[0]]465 try:
466 parent_info = revnos[parents[0]]
467 except KeyError:
468 # Left-hand parent is a ghost, consider it not to exist
469 pass
470 if parent_info is not None:
465 first_child = parent_info[1]471 first_child = parent_info[1]
466 parent_info[1] = False472 parent_info[1] = False
467 else:473 else:
@@ -495,9 +501,15 @@
495 pending_parents_stack_pop()501 pending_parents_stack_pop()
496502
497 parents = original_graph[node_name]503 parents = original_graph[node_name]
504 parent_revno = None
498 if parents:505 if parents:
499 # node has parents, assign from the left most parent.506 # node has parents, assign from the left most parent.
500 parent_revno = revnos[parents[0]][0]507 try:
508 parent_revno = revnos[parents[0]][0]
509 except KeyError:
510 # left-hand parent is a ghost, treat it as not existing
511 pass
512 if parent_revno is not None:
501 if not first_child:513 if not first_child:
502 # not the first child, make a new branch514 # not the first child, make a new branch
503 base_revno = parent_revno[0]515 base_revno = parent_revno[0]
@@ -628,10 +640,15 @@
628 self._left_subtree_pushed_stack.append(False)640 self._left_subtree_pushed_stack.append(False)
629 self._pending_parents_stack.append(list(parents))641 self._pending_parents_stack.append(list(parents))
630 # as we push it, figure out if this is the first child642 # as we push it, figure out if this is the first child
631 parents = self._original_graph[node_name]643 parent_info = None
632 if parents:644 if parents:
633 # node has parents, assign from the left most parent.645 # node has parents, assign from the left most parent.
634 parent_info = self._revnos[parents[0]]646 try:
647 parent_info = self._revnos[parents[0]]
648 except KeyError:
649 # Left-hand parent is a ghost, consider it not to exist
650 pass
651 if parent_info is not None:
635 first_child = parent_info[1]652 first_child = parent_info[1]
636 parent_info[1] = False653 parent_info[1] = False
637 else:654 else:
@@ -655,9 +672,15 @@
655 self._pending_parents_stack.pop()672 self._pending_parents_stack.pop()
656673
657 parents = self._original_graph[node_name]674 parents = self._original_graph[node_name]
675 parent_revno = None
658 if parents:676 if parents:
659 # node has parents, assign from the left most parent.677 # node has parents, assign from the left most parent.
660 parent_revno = self._revnos[parents[0]][0]678 try:
679 parent_revno = self._revnos[parents[0]][0]
680 except KeyError:
681 # left-hand parent is a ghost, treat it as not existing
682 pass
683 if parent_revno is not None:
661 if not first_child:684 if not first_child:
662 # not the first child, make a new branch685 # not the first child, make a new branch
663 base_revno = parent_revno[0]686 base_revno = parent_revno[0]

Subscribers

People subscribed via source and target branches