Rev 3188: (jameinel) Switch dotted revnos to always be 3 digits long. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/
Canonical.com Patch Queue Manager
pqm at pqm.ubuntu.com
Wed Jan 16 21:12:08 GMT 2008
At file:///home/pqm/archives/thelove/bzr/%2Btrunk/
------------------------------------------------------------
revno: 3188
revision-id:pqm at pqm.ubuntu.com-20080116211201-fy431qtj4d3vre5x
parent: pqm at pqm.ubuntu.com-20080116053913-ny7sihxkms5v6d7j
parent: john at arbash-meinel.com-20080115214200-27y5bnbuf3dbtqnm
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2008-01-16 21:12:01 +0000
message:
(jameinel) Switch dotted revnos to always be 3 digits long.
added:
doc/en/user-guide/revnos.txt revnos.txt-20080111231928-pbntxea0ynh9ww1t-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
bzrlib/tests/test_annotate.py test_annotate.py-20061213215015-sttc9agsxomls7q0-1
bzrlib/tests/test_log.py testlog.py-20050728115707-1a514809d7d49309
bzrlib/tests/test_tsort.py testtsort.py-20051025073946-27da871c394d5be4
bzrlib/tsort.py tsort.py-20051025073946-7808f6aaf7d07208
doc/en/user-guide/core_concepts.txt core_concepts.txt-20071114035000-q36a9h57ps06uvnl-2
doc/en/user-guide/index.txt index.txt-20060622101119-tgwtdci8z769bjb9-2
------------------------------------------------------------
revno: 3170.3.8
revision-id:john at arbash-meinel.com-20080115214200-27y5bnbuf3dbtqnm
parent: john at arbash-meinel.com-20080115210031-7hhwowgkmo2monk8
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dotted_revnos
timestamp: Tue 2008-01-15 15:42:00 -0600
message:
Finish the rest of the review feedback.
modified:
bzrlib/tests/test_tsort.py testtsort.py-20051025073946-27da871c394d5be4
doc/en/user-guide/revnos.txt revnos.txt-20080111231928-pbntxea0ynh9ww1t-1
------------------------------------------------------------
revno: 3170.3.7
revision-id:john at arbash-meinel.com-20080115210031-7hhwowgkmo2monk8
parent: john at arbash-meinel.com-20080115205515-a2eyt2w1imuxgv1v
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dotted_revnos
timestamp: Tue 2008-01-15 15:00:31 -0600
message:
update MergeSorter.__init__() docstring
modified:
bzrlib/tsort.py tsort.py-20051025073946-7808f6aaf7d07208
------------------------------------------------------------
revno: 3170.3.6
revision-id:john at arbash-meinel.com-20080115205515-a2eyt2w1imuxgv1v
parent: meinel at lululaptop-20080111231953-044hfb9u9gyuffgy
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: dotted_revnos
timestamp: Tue 2008-01-15 14:55:15 -0600
message:
Documentation feedback.
Link the new doc from the index, and cross reference it from core_concepts.
modified:
doc/en/user-guide/core_concepts.txt core_concepts.txt-20071114035000-q36a9h57ps06uvnl-2
doc/en/user-guide/index.txt index.txt-20060622101119-tgwtdci8z769bjb9-2
doc/en/user-guide/revnos.txt revnos.txt-20080111231928-pbntxea0ynh9ww1t-1
------------------------------------------------------------
revno: 3170.3.5
revision-id:meinel at lululaptop-20080111231953-044hfb9u9gyuffgy
parent: meinel at lululaptop-20080110223409-2d2w3l1wkc0f2kap
committer: John Arbash Meinel <John Arbash Meinel at LULULAPTOP>
branch nick: dotted_revnos
timestamp: Fri 2008-01-11 17:19:53 -0600
message:
Add a NEWS entry and a revision number document.
added:
doc/en/user-guide/revnos.txt revnos.txt-20080111231928-pbntxea0ynh9ww1t-1
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
------------------------------------------------------------
revno: 3170.3.4
revision-id:meinel at lululaptop-20080110223409-2d2w3l1wkc0f2kap
parent: meinel at lululaptop-20080110165447-pwcd7orl015rtsrs
committer: John Arbash Meinel <John Arbash Meinel at LULULAPTOP>
branch nick: dotted_revnos
timestamp: Thu 2008-01-10 16:34:09 -0600
message:
Update the tests for the new revision numbering.
modified:
bzrlib/tests/blackbox/test_log.py test_log.py-20060112090212-78f6ea560c868e24
bzrlib/tests/test_annotate.py test_annotate.py-20061213215015-sttc9agsxomls7q0-1
bzrlib/tests/test_log.py testlog.py-20050728115707-1a514809d7d49309
bzrlib/tests/test_tsort.py testtsort.py-20051025073946-27da871c394d5be4
------------------------------------------------------------
revno: 3170.3.3
revision-id:meinel at lululaptop-20080110165447-pwcd7orl015rtsrs
parent: meinel at lululaptop-20080109211018-oyh76zn4fb21qda1
parent: pqm at pqm.ubuntu.com-20080110025628-6tl4b9cmdn335suw
committer: John Arbash Meinel <John Arbash Meinel at LULULAPTOP>
branch nick: dotted_revnos
timestamp: Thu 2008-01-10 10:54:47 -0600
message:
Merge bzr.dev 3172
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/bzrdir.py bzrdir.py-20060131065624-156dfea39c4387cb
bzrlib/debug.py debug.py-20061102062349-vdhrw9qdpck8cl35-1
bzrlib/fetch.py fetch.py-20050818234941-26fea6105696365d
bzrlib/help_topics/__init__.py help_topics.py-20060920210027-rnim90q9e0bwxvy4-1
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/interrepository_implementations/test_interrepository.py test_interrepository.py-20060220061411-1ec13fa99e5e3eee
bzrlib/tests/repository_implementations/test_repository.py test_repository.py-20060131092128-ad07f494f5c9d26c
bzrlib/tests/test_osutils.py test_osutils.py-20051201224856-e48ee24c12182989
bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
bzrlib/trace.py trace.py-20050309040759-c8ed824bdcd4748a
bzrlib/xml_serializer.py xml.py-20050309040759-57d51586fdec365d
------------------------------------------------------------
revno: 3170.3.2
revision-id:meinel at lululaptop-20080109211018-oyh76zn4fb21qda1
parent: meinel at lululaptop-20080109194739-q5nyw06zus444na3
committer: John Arbash Meinel <John Arbash Meinel at LULULAPTOP>
branch nick: dotted_revnos
timestamp: Wed 2008-01-09 15:10:18 -0600
message:
Implement the new dotted revision numbering.
modified:
bzrlib/tests/test_tsort.py testtsort.py-20051025073946-27da871c394d5be4
bzrlib/tsort.py tsort.py-20051025073946-7808f6aaf7d07208
------------------------------------------------------------
revno: 3170.3.1
revision-id:meinel at lululaptop-20080109194739-q5nyw06zus444na3
parent: pqm at pqm.ubuntu.com-20080107174938-hvwo399dzshh3cod
committer: John Arbash Meinel <John Arbash Meinel at LULULAPTOP>
branch nick: dotted_revnos
timestamp: Wed 2008-01-09 13:47:39 -0600
message:
Write up a simple test that is getting ready to fix up deeply nested dotted revnos.
modified:
bzrlib/tests/test_tsort.py testtsort.py-20051025073946-27da871c394d5be4
=== added file 'doc/en/user-guide/revnos.txt'
--- a/doc/en/user-guide/revnos.txt 1970-01-01 00:00:00 +0000
+++ b/doc/en/user-guide/revnos.txt 2008-01-15 21:42:00 +0000
@@ -0,0 +1,33 @@
+Understanding Revision Numbers
+==============================
+
+All revisions in the mainline of a branch will have a simple increasing
+integer. (First commit gets 1, 10th commit gets 10, etc.) This makes them
+fairly natural to use when you want to say "grab the 10th revision from my
+branch", or "fixed in revision 3050".
+
+For revisions which have been merged into a branch, a dotted notation is
+used (eg, 3112.1.5). Dotted revision numbers have three numbers. The first
+number indicates what mainline revision change is derived from. The second
+number is the branch counter. There can be many branches derived from the
+same revision, so they all get a unique number. The third number is the
+number of revisions since the branch started. For example, 3112.1.5 is the
+first branch from revision 3112, the fifth revision on that branch.
+
+Revisions are numbered in a stable way, such that if two branches have the
+same revision in their mainline, all revisions in the ancestry of that
+revision will have the same revision numbers. (So if Alice and Bob's
+branches agree on revision 10, they will agree on all revisions before
+that.) Future merges will not change revision numbers. However doing
+``bzr pull`` can change revision numbers, because it changes the
+mainline revisions.
+
+
+bzr versions < 1.2
+------------------
+Versions prior to bzr 1.2 used a slightly different algorithm. Some nested
+branches would get extra numbers (such as 1.1.1.1.1) rather than the
+simpler 3-number system.
+
+..
+ vim: ft=rst tw=74 ai
=== modified file 'NEWS'
--- a/NEWS 2008-01-16 04:10:03 +0000
+++ b/NEWS 2008-01-16 21:12:01 +0000
@@ -81,6 +81,11 @@
CHANGES:
+ * Dotted revision numbers have been revised. Instead of growing longer with
+ nested branches the branch number just increases. (eg instead of 1.1.1.1.1
+ we now report 1.2.1.) This helps scale long lived branches which have many
+ feature branches merged between them. (John Arbash Meinel)
+
* The syntax ``bzr diff branch1 branch2`` is no longer supported.
Use ``bzr diff branch1 --new branch2`` instead. This change has
been made to remove the ambiguity where ``branch2`` is in fact a
=== modified file 'bzrlib/tests/blackbox/test_log.py'
--- a/bzrlib/tests/blackbox/test_log.py 2007-12-27 08:25:04 +0000
+++ b/bzrlib/tests/blackbox/test_log.py 2008-01-10 22:34:09 +0000
@@ -222,7 +222,7 @@
message:
merge branch 2
------------------------------------------------------------
- revno: 1.1.1.1.1
+ revno: 1.2.1
committer: Lorem Ipsum <test at example.com>
branch nick: smallerchild
timestamp: Just now
@@ -258,7 +258,7 @@
message:
merge branch 2
------------------------------------------------------------
- revno: 1.1.1.1.1
+ revno: 1.2.1
committer: Lorem Ipsum <test at example.com>
branch nick: smallerchild
timestamp: Just now
@@ -280,7 +280,7 @@
message:
merge branch 2
------------------------------------------------------------
- revno: 1.1.1.1.1
+ revno: 1.2.1
committer: Lorem Ipsum <test at example.com>
branch nick: smallerchild
timestamp: Just now
=== modified file 'bzrlib/tests/test_annotate.py'
--- a/bzrlib/tests/test_annotate.py 2007-11-21 21:57:11 +0000
+++ b/bzrlib/tests/test_annotate.py 2008-01-10 22:34:09 +0000
@@ -162,11 +162,11 @@
| | |
+------+ |
| | |
- rev-3 rev-1_1_2 rev-1_1_1_1_1 --+
+ rev-3 rev-1_1_2 rev-1_2_1 ------+
| | | |
+------+ | |
| | |
- rev-4 rev-1_1_1_1_2 rev-1_1_1_1_1_1_1
+ rev-4 rev-1_2_2 rev-1_3_1
| | |
+-----------------+ |
| |
@@ -186,13 +186,13 @@
tree1.commit('noop merge', rev_id='rev-4')
self.build_tree_contents([('tree3/a', 'first\nthird\nfourth\n')])
- tree3.commit('four', rev_id='rev-1_1_1_1_1',
+ tree3.commit('four', rev_id='rev-1_2_1',
committer='jerry at foo.com',
timestamp=1166046003.00, timezone=0)
tree4 = tree3.bzrdir.clone('tree4').open_workingtree()
- tree3.commit('noop', rev_id='rev-1_1_1_1_2',
+ tree3.commit('noop', rev_id='rev-1_2_2',
committer='jerry at foo.com',
timestamp=1166046004.00, timezone=0)
self.assertEqual(0, tree1.merge_from_branch(tree3.branch))
@@ -200,7 +200,7 @@
self.build_tree_contents([('tree4/a',
'first\nthird\nfourth\nfifth\nsixth\n')])
- tree4.commit('five and six', rev_id='rev-1_1_1_1_1_1_1',
+ tree4.commit('five and six', rev_id='rev-1_3_1',
committer='george at foo.com',
timestamp=1166046005.00, timezone=0)
self.assertEqual(0, tree1.merge_from_branch(tree4.branch))
@@ -226,46 +226,46 @@
sio = StringIO()
annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
to_file=sio, verbose=False, full=False)
- self.assertEqualDiff('1 joe at foo | first\n'
- '2 joe at foo | second\n'
- '1.1.1 barry at f | third\n'
- '1.1.1.1.1 jerry at f | fourth\n'
- '1.1.1.1.1.1> george@ | fifth\n'
- ' | sixth\n',
+ self.assertEqualDiff('1 joe at foo | first\n'
+ '2 joe at foo | second\n'
+ '1.1.1 barry at f | third\n'
+ '1.2.1 jerry at f | fourth\n'
+ '1.3.1 george@ | fifth\n'
+ ' | sixth\n',
sio.getvalue())
sio = StringIO()
annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
to_file=sio, verbose=False, full=True)
- self.assertEqualDiff('1 joe at foo | first\n'
- '2 joe at foo | second\n'
- '1.1.1 barry at f | third\n'
- '1.1.1.1.1 jerry at f | fourth\n'
- '1.1.1.1.1.1> george@ | fifth\n'
- '1.1.1.1.1.1> george@ | sixth\n',
+ self.assertEqualDiff('1 joe at foo | first\n'
+ '2 joe at foo | second\n'
+ '1.1.1 barry at f | third\n'
+ '1.2.1 jerry at f | fourth\n'
+ '1.3.1 george@ | fifth\n'
+ '1.3.1 george@ | sixth\n',
sio.getvalue())
# verbose=True shows everything, the full revno, user id, and date
sio = StringIO()
annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
to_file=sio, verbose=True, full=False)
- self.assertEqualDiff('1 joe at foo.com 20061213 | first\n'
- '2 joe at foo.com 20061213 | second\n'
- '1.1.1 barry at foo.com 20061213 | third\n'
- '1.1.1.1.1 jerry at foo.com 20061213 | fourth\n'
- '1.1.1.1.1.1.1 george at foo.com 20061213 | fifth\n'
- ' | sixth\n',
+ self.assertEqualDiff('1 joe at foo.com 20061213 | first\n'
+ '2 joe at foo.com 20061213 | second\n'
+ '1.1.1 barry at foo.com 20061213 | third\n'
+ '1.2.1 jerry at foo.com 20061213 | fourth\n'
+ '1.3.1 george at foo.com 20061213 | fifth\n'
+ ' | sixth\n',
sio.getvalue())
sio = StringIO()
annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
to_file=sio, verbose=True, full=True)
- self.assertEqualDiff('1 joe at foo.com 20061213 | first\n'
- '2 joe at foo.com 20061213 | second\n'
- '1.1.1 barry at foo.com 20061213 | third\n'
- '1.1.1.1.1 jerry at foo.com 20061213 | fourth\n'
- '1.1.1.1.1.1.1 george at foo.com 20061213 | fifth\n'
- '1.1.1.1.1.1.1 george at foo.com 20061213 | sixth\n',
+ self.assertEqualDiff('1 joe at foo.com 20061213 | first\n'
+ '2 joe at foo.com 20061213 | second\n'
+ '1.1.1 barry at foo.com 20061213 | third\n'
+ '1.2.1 jerry at foo.com 20061213 | fourth\n'
+ '1.3.1 george at foo.com 20061213 | fifth\n'
+ '1.3.1 george at foo.com 20061213 | sixth\n',
sio.getvalue())
def test_annotate_uses_branch_context(self):
@@ -277,13 +277,13 @@
tree1 = self.create_deeply_merged_trees()
sio = StringIO()
- annotate.annotate_file(tree1.branch, 'rev-1_1_1_1_1_1_1', 'a-id',
+ annotate.annotate_file(tree1.branch, 'rev-1_3_1', 'a-id',
to_file=sio, verbose=False, full=False)
- self.assertEqualDiff('1 joe at foo | first\n'
- '1.1.1 barry at f | third\n'
- '1.1.1.1.1 jerry at f | fourth\n'
- '1.1.1.1.1.1> george@ | fifth\n'
- ' | sixth\n',
+ self.assertEqualDiff('1 joe at foo | first\n'
+ '1.1.1 barry at f | third\n'
+ '1.2.1 jerry at f | fourth\n'
+ '1.3.1 george@ | fifth\n'
+ ' | sixth\n',
sio.getvalue())
def test_annotate_show_ids(self):
@@ -294,24 +294,24 @@
to_file=sio, show_ids=True, full=False)
# It looks better with real revision ids :)
- self.assertEqualDiff(' rev-1 | first\n'
- ' rev-2 | second\n'
- ' rev-1_1_1 | third\n'
- ' rev-1_1_1_1_1 | fourth\n'
- 'rev-1_1_1_1_1_1_1 | fifth\n'
- ' | sixth\n',
+ self.assertEqualDiff(' rev-1 | first\n'
+ ' rev-2 | second\n'
+ 'rev-1_1_1 | third\n'
+ 'rev-1_2_1 | fourth\n'
+ 'rev-1_3_1 | fifth\n'
+ ' | sixth\n',
sio.getvalue())
sio = StringIO()
annotate.annotate_file(tree1.branch, 'rev-6', 'a-id',
to_file=sio, show_ids=True, full=True)
- self.assertEqualDiff(' rev-1 | first\n'
- ' rev-2 | second\n'
- ' rev-1_1_1 | third\n'
- ' rev-1_1_1_1_1 | fourth\n'
- 'rev-1_1_1_1_1_1_1 | fifth\n'
- 'rev-1_1_1_1_1_1_1 | sixth\n',
+ self.assertEqualDiff(' rev-1 | first\n'
+ ' rev-2 | second\n'
+ 'rev-1_1_1 | third\n'
+ 'rev-1_2_1 | fourth\n'
+ 'rev-1_3_1 | fifth\n'
+ 'rev-1_3_1 | sixth\n',
sio.getvalue())
def test_annotate_unicode_author(self):
=== modified file 'bzrlib/tests/test_log.py'
--- a/bzrlib/tests/test_log.py 2007-12-05 18:47:51 +0000
+++ b/bzrlib/tests/test_log.py 2008-01-10 22:34:09 +0000
@@ -425,7 +425,7 @@
message:
merge branch 2
------------------------------------------------------------
- revno: 1.1.1.1.1
+ revno: 1.2.1
committer: Lorem Ipsum <test at example.com>
branch nick: smallerchild
timestamp: Just now
@@ -674,10 +674,10 @@
full_rev_nos_for_reference = {
'1': '1',
'2': '2',
- '3a': '2.2.1', #first commit tree 3
- '3b': '2.1.1', # first commit tree 2
+ '3a': '2.1.1', #first commit tree 3
+ '3b': '2.2.1', # first commit tree 2
'3c': '3', #merges 3b to main
- '4a': '2.1.2', # second commit tree 2
+ '4a': '2.2.2', # second commit tree 2
'4b': '4', # merges 4a to main
}
return mainline_revs, rev_nos, wt
@@ -738,8 +738,8 @@
revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
'forward'))
expected = [('1', '1', 0), ('2', '2', 0), ('3c', '3', 0),
- ('3a', '2.2.1', 1), ('3b', '2.1.1', 1), ('4b', '4', 0),
- ('4a', '2.1.2', 1)]
+ ('3a', '2.1.1', 1), ('3b', '2.2.1', 1), ('4b', '4', 0),
+ ('4a', '2.2.2', 1)]
self.assertEqual(expected, revisions)
revisions = list(get_view_revisions(mainline_revs, rev_nos, wt.branch,
'forward', include_merges=False))
=== modified file 'bzrlib/tests/test_tsort.py'
--- a/bzrlib/tests/test_tsort.py 2007-06-21 01:58:29 +0000
+++ b/bzrlib/tests/test_tsort.py 2008-01-15 21:42:00 +0000
@@ -181,7 +181,55 @@
],
True
)
-
+
+ def test_merge_sort_race(self):
+ # A
+ # |
+ # B-.
+ # |\ \
+ # | | C
+ # | |/
+ # | D
+ # |/
+ # F
+ graph = {'A': [],
+ 'B': ['A'],
+ 'C': ['B'],
+ 'D': ['B', 'C'],
+ 'F': ['B', 'D'],
+ }
+ self.assertSortAndIterate(graph, 'F',
+ [(0, 'F', 0, (3,), False),
+ (1, 'D', 1, (2,2,1), False),
+ (2, 'C', 1, (2,1,1), True), # XXX: Shouldn't it be merge_depth=2?
+ (3, 'B', 0, (2,), False),
+ (4, 'A', 0, (1,), True),
+ ], True)
+ # A
+ # |
+ # B-.
+ # |\ \
+ # | X C
+ # | |/
+ # | D
+ # |/
+ # F
+ graph = {'A': [],
+ 'B': ['A'],
+ 'C': ['B'],
+ 'X': ['B'],
+ 'D': ['X', 'C'],
+ 'F': ['B', 'D'],
+ }
+ self.assertSortAndIterate(graph, 'F',
+ [(0, 'F', 0, (3,), False),
+ (1, 'D', 1, (2,1,2), False),
+ (2, 'C', 2, (2,2,1), True),
+ (3, 'X', 1, (2,1,1), True),
+ (4, 'B', 0, (2,), False),
+ (5, 'A', 0, (1,), True),
+ ], True)
+
def test_merge_depth_with_nested_merges(self):
# the merge depth marker should reflect the depth of the revision
# in terms of merges out from the mainline
@@ -228,17 +276,96 @@
}.items(),
'A',
[(0, 'A', 0, (3,), False),
- (1, 'B', 1, (1,2,2), False),
- (2, 'C', 1, (1,2,1), True),
+ (1, 'B', 1, (1,3,2), False),
+ (2, 'C', 1, (1,3,1), True),
(3, 'D', 0, (2,), False),
(4, 'E', 1, (1,1,2), False),
- (5, 'F', 2, (1,1,1,1,1), True),
+ (5, 'F', 2, (1,2,1), True),
(6, 'G', 1, (1,1,1), True),
(7, 'H', 0, (1,), True),
],
True
)
-
+
+ def test_dotted_revnos_with_simple_merges(self):
+ # A 1
+ # |\
+ # B C 2, 1.1.1
+ # | |\
+ # D E F 3, 1.1.2, 1.2.1
+ # |/ /|
+ # G H I 4, 1.2.2, 1.3.1
+ # |/ /
+ # J K 5, 1.3.2
+ # |/
+ # L 6
+ self.assertSortAndIterate(
+ {'A': [],
+ 'B': ['A'],
+ 'C': ['A'],
+ 'D': ['B'],
+ 'E': ['C'],
+ 'F': ['C'],
+ 'G': ['D', 'E'],
+ 'H': ['F'],
+ 'I': ['F'],
+ 'J': ['G', 'H'],
+ 'K': ['I'],
+ 'L': ['J', 'K'],
+ }.items(),
+ 'L',
+ [(0, 'L', 0, (6,), False),
+ (1, 'K', 1, (1,3,2), False),
+ (2, 'I', 1, (1,3,1), True),
+ (3, 'J', 0, (5,), False),
+ (4, 'H', 1, (1,2,2), False),
+ (5, 'F', 1, (1,2,1), True),
+ (6, 'G', 0, (4,), False),
+ (7, 'E', 1, (1,1,2), False),
+ (8, 'C', 1, (1,1,1), True),
+ (9, 'D', 0, (3,), False),
+ (10, 'B', 0, (2,), False),
+ (11, 'A', 0, (1,), True),
+ ],
+ True
+ )
+ # Adding a shortcut from the first revision should not change any of
+ # the existing numbers
+ self.assertSortAndIterate(
+ {'A': [],
+ 'B': ['A'],
+ 'C': ['A'],
+ 'D': ['B'],
+ 'E': ['C'],
+ 'F': ['C'],
+ 'G': ['D', 'E'],
+ 'H': ['F'],
+ 'I': ['F'],
+ 'J': ['G', 'H'],
+ 'K': ['I'],
+ 'L': ['J', 'K'],
+ 'M': ['A'],
+ 'N': ['L', 'M'],
+ }.items(),
+ 'N',
+ [(0, 'N', 0, (7,), False),
+ (1, 'M', 1, (1,4,1), True),
+ (2, 'L', 0, (6,), False),
+ (3, 'K', 1, (1,3,2), False),
+ (4, 'I', 1, (1,3,1), True),
+ (5, 'J', 0, (5,), False),
+ (6, 'H', 1, (1,2,2), False),
+ (7, 'F', 1, (1,2,1), True),
+ (8, 'G', 0, (4,), False),
+ (9, 'E', 1, (1,1,2), False),
+ (10, 'C', 1, (1,1,1), True),
+ (11, 'D', 0, (3,), False),
+ (12, 'B', 0, (2,), False),
+ (13, 'A', 0, (1,), True),
+ ],
+ True
+ )
+
def test_end_of_merge_not_last_revision_in_branch(self):
# within a branch only the last revision gets an
# end of merge marker.
@@ -311,11 +438,11 @@
},
'A',
[(0, 'A', 0, (2,), False),
- (1, 'B', 1, (1,2,2), False),
- (2, 'C', 2, (1,2,1,1,1), True),
- (3, 'D', 1, (1,2,1), True),
+ (1, 'B', 1, (1,3,2), False),
+ (2, 'C', 2, (1,4,1), True),
+ (3, 'D', 1, (1,3,1), True),
(4, 'E', 1, (1,1,2), False),
- (5, 'F', 2, (1,1,1,1,1), True),
+ (5, 'F', 2, (1,2,1), True),
(6, 'G', 1, (1,1,1), True),
(7, 'H', 0, (1,), True),
],
=== modified file 'bzrlib/tsort.py'
--- a/bzrlib/tsort.py 2007-06-21 01:58:29 +0000
+++ b/bzrlib/tsort.py 2008-01-15 21:00:31 +0000
@@ -192,7 +192,7 @@
__slots__ = ['_node_name_stack',
'_node_merge_depth_stack',
'_pending_parents_stack',
- '_assigned_sequence_stack',
+ '_first_child_stack',
'_left_subtree_pushed_stack',
'_generate_revno',
'_graph',
@@ -200,7 +200,7 @@
'_stop_revision',
'_original_graph',
'_revnos',
- '_root_sequence',
+ '_revno_to_branch_count',
'_completed_node_names',
'_scheduled_nodes',
]
@@ -239,7 +239,7 @@
found.
* revno_sequence: When requested this field provides a sequence of
revision numbers for all revisions. The format is:
- REVNO[[.BRANCHREVNO.REVNO] ...]. BRANCHREVNO is the number of the
+ (REVNO, BRANCHNUM, BRANCHREVNO). BRANCHNUM is the number of the
branch that the revno is on. From left to right the REVNO numbers
are the sequence numbers within that branch of the revision.
For instance, the graph {A:[], B:['A'], C:['A', 'B']} will get
@@ -362,15 +362,15 @@
self._original_graph = dict(self._graph.items())
# we need to know the revision numbers of revisions to determine
# the revision numbers of their descendants
- # this is a graph from node to [revno_tuple, sequence_number]
- # where sequence is the number of branches made from the node,
+ # this is a graph from node to [revno_tuple, first_child]
+ # where first_child is True if no other children have seen this node
# and revno_tuple is the tuple that was assigned to the node.
# we dont know revnos to start with, so we start it seeded with
- # [None, 0]
- self._revnos = dict((revision, [None, 0]) for revision in self._graph)
- # the global implicit root node has revno 0, but we need to know
- # the sequence number for it too:
- self._root_sequence = 0
+ # [None, True]
+ self._revnos = dict((revision, [None, True])
+ for revision in self._graph)
+ # Each mainline revision counts how many child branches have spawned from it.
+ self._revno_to_branch_count = {}
# this is a stack storing the depth first search into the graph.
self._node_name_stack = []
@@ -382,7 +382,7 @@
self._pending_parents_stack = []
# When we first look at a node we assign it a seqence number from its
# leftmost parent.
- self._assigned_sequence_stack = []
+ self._first_child_stack = []
# this is a set of the nodes who have been completely analysed for fast
# membership checking
self._completed_node_names = set()
@@ -439,8 +439,7 @@
node_merge_depth_stack_append=node_merge_depth_stack.append,
left_subtree_pushed_stack_append=left_subtree_pushed_stack.append,
pending_parents_stack_append=pending_parents_stack.append,
- assigned_sequence_stack_append=self._assigned_sequence_stack.append,
- original_graph=self._original_graph,
+ first_child_stack_append=self._first_child_stack.append,
revnos=self._revnos,
):
"""Add node_name to the pending node stack.
@@ -455,28 +454,28 @@
node_merge_depth_stack_append(merge_depth)
left_subtree_pushed_stack_append(False)
pending_parents_stack_append(list(parents))
- # as we push it, assign it a sequence number against its parent:
- parents = original_graph[node_name]
+ # as we push it, check if it is the first child
if parents:
# node has parents, assign from the left most parent.
- parent_revno = revnos[parents[0]]
- sequence = parent_revno[1]
- parent_revno[1] += 1
+ parent_info = revnos[parents[0]]
+ first_child = parent_info[1]
+ parent_info[1] = False
else:
- # no parents, use the root sequence
- sequence = self._root_sequence
- self._root_sequence +=1
- assigned_sequence_stack_append(sequence)
+ # We don't use the same algorithm here, but we need to keep the
+ # stack in line
+ first_child = None
+ first_child_stack_append(first_child)
def pop_node(node_name_stack_pop=node_name_stack.pop,
node_merge_depth_stack_pop=node_merge_depth_stack.pop,
- assigned_sequence_stack_pop=self._assigned_sequence_stack.pop,
+ first_child_stack_pop=self._first_child_stack.pop,
left_subtree_pushed_stack_pop=left_subtree_pushed_stack.pop,
pending_parents_stack_pop=pending_parents_stack.pop,
original_graph=self._original_graph,
revnos=self._revnos,
completed_node_names_add=self._completed_node_names.add,
scheduled_nodes_append=scheduled_nodes.append,
+ revno_to_branch_count=self._revno_to_branch_count,
):
"""Pop the top node off the stack
@@ -486,7 +485,7 @@
# pop off the local variables
node_name = node_name_stack_pop()
merge_depth = node_merge_depth_stack_pop()
- sequence = assigned_sequence_stack_pop()
+ first_child = first_child_stack_pop()
# remove this node from the pending lists:
left_subtree_pushed_stack_pop()
pending_parents_stack_pop()
@@ -494,20 +493,28 @@
parents = original_graph[node_name]
if parents:
# node has parents, assign from the left most parent.
- parent_revno = revnos[parents[0]]
- if sequence:
+ parent_revno = revnos[parents[0]][0]
+ if not first_child:
# not the first child, make a new branch
- revno = parent_revno[0] + (sequence, 1)
+ base_revno = parent_revno[0]
+ branch_count = revno_to_branch_count.get(base_revno, 0)
+ branch_count += 1
+ revno_to_branch_count[base_revno] = branch_count
+ revno = (parent_revno[0], branch_count, 1)
+ # revno = (parent_revno[0], branch_count, parent_revno[-1]+1)
else:
- # increment the sequence number within the branch
- revno = parent_revno[0][:-1] + (parent_revno[0][-1] + 1,)
+ # as the first child, we just increase the final revision
+ # number
+ revno = parent_revno[:-1] + (parent_revno[-1] + 1,)
else:
# no parents, use the root sequence
- if sequence:
- # make a parallel import revision number
- revno = (0, sequence, 1)
+ root_count = revno_to_branch_count.get(0, 0)
+ if root_count:
+ revno = (0, root_count, 1)
else:
revno = (1,)
+ root_count += 1
+ revno_to_branch_count[0] = root_count
# store the revno for this node for future reference
revnos[node_name][0] = revno
@@ -610,18 +617,18 @@
self._node_merge_depth_stack.append(merge_depth)
self._left_subtree_pushed_stack.append(False)
self._pending_parents_stack.append(list(parents))
- # as we push it, assign it a sequence number against its parent:
+ # as we push it, figure out if this is the first child
parents = self._original_graph[node_name]
if parents:
# node has parents, assign from the left most parent.
- parent_revno = self._revnos[parents[0]]
- sequence = parent_revno[1]
- parent_revno[1] += 1
+ parent_info = self._revnos[parents[0]]
+ first_child = parent_info[1]
+ parent_info[1] = False
else:
- # no parents, use the root sequence
- sequence = self._root_sequence
- self._root_sequence +=1
- self._assigned_sequence_stack.append(sequence)
+ # We don't use the same algorithm here, but we need to keep the
+ # stack in line
+ first_child = None
+ self._first_child_stack.append(first_child)
def _pop_node(self):
"""Pop the top node off the stack
@@ -632,7 +639,7 @@
# pop off the local variables
node_name = self._node_name_stack.pop()
merge_depth = self._node_merge_depth_stack.pop()
- sequence = self._assigned_sequence_stack.pop()
+ first_child = self._first_child_stack.pop()
# remove this node from the pending lists:
self._left_subtree_pushed_stack.pop()
self._pending_parents_stack.pop()
@@ -640,20 +647,28 @@
parents = self._original_graph[node_name]
if parents:
# node has parents, assign from the left most parent.
- parent_revno = self._revnos[parents[0]]
- if sequence:
+ parent_revno = self._revnos[parents[0]][0]
+ if not first_child:
# not the first child, make a new branch
- revno = parent_revno[0] + (sequence, 1)
+ base_revno = parent_revno[0]
+ branch_count = self._revno_to_branch_count.get(base_revno, 0)
+ branch_count += 1
+ self._revno_to_branch_count[base_revno] = branch_count
+ revno = (parent_revno[0], branch_count, 1)
+ # revno = (parent_revno[0], branch_count, parent_revno[-1]+1)
else:
- # increment the sequence number within the branch
- revno = parent_revno[0][:-1] + (parent_revno[0][-1] + 1,)
+ # as the first child, we just increase the final revision
+ # number
+ revno = parent_revno[:-1] + (parent_revno[-1] + 1,)
else:
# no parents, use the root sequence
- if sequence:
- # make a parallel import revision number
- revno = (0, sequence, 1)
+ root_count = self._revno_to_branch_count.get(0, 0)
+ if root_count:
+ revno = (0, root_count, 1)
else:
revno = (1,)
+ root_count += 1
+ self._revno_to_branch_count[0] = root_count
# store the revno for this node for future reference
self._revnos[node_name][0] = revno
=== modified file 'doc/en/user-guide/core_concepts.txt'
--- a/doc/en/user-guide/core_concepts.txt 2007-12-14 07:35:49 +0000
+++ b/doc/en/user-guide/core_concepts.txt 2008-01-15 20:55:15 +0000
@@ -40,7 +40,8 @@
interface for humans. Typical revision numbers are 1, 42 and 2977.1.59.
See `Specifying revisions`_ in the appendices for a closer look at
the numerous ways that revisions and ranges of revisions can be specified
-in Bazaar.
+in Bazaar, and `Understanding Revision Numbers` for a more details about
+numbering.
.. *TODO: add diagram*
=== modified file 'doc/en/user-guide/index.txt'
--- a/doc/en/user-guide/index.txt 2007-12-17 01:45:32 +0000
+++ b/doc/en/user-guide/index.txt 2008-01-15 20:55:15 +0000
@@ -27,6 +27,7 @@
.. include:: installing_bazaar.txt
.. include:: entering_commands.txt
+.. include:: revnos.txt
.. include:: getting_help.txt
.. include:: configuring_bazaar.txt
.. include:: using_aliases.txt
More information about the bazaar-commits
mailing list