1
# Copyright (C) 2004 Aaron Bentley
2
# <aaron.bentley@utoronto.ca>
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License as published by
6
# the Free Software Foundation; either version 2 of the License, or
7
# (at your option) any later version.
9
# This program is distributed in the hope that it will be useful,
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
# GNU General Public License for more details.
14
# You should have received a copy of the GNU General Public License
15
# along with this program; if not, write to the Free Software
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
from pybaz.backends.baz import sequence_cmd
22
__docformat__ = "restructuredtext"
23
__doc__ = "Utility functions to be used by commands"
25
def direct_merges(merges, excludes=[]):
26
"""Get a list of direct merges, from a list of direct and indirect
28
:param merges: Iterator of merge patchlogs
29
:type merges: iter of `pybaz.Patchlog`
30
:return: The direct merges
31
:rtype: list of `pybaz.Patchlog`
39
this_indirect = set([str(f) for f in log.new_patches
40
if f != log.revision and
41
str(f) not in indirect])
42
except pybaz.errors.NamespaceError:
44
print "log ", log, " unusable, attempting to use archive copy."
45
log = pybaz.Revision(str(log.revision)).patchlog
46
this_indirect = set([str(f) for f in log.new_patches
47
if f != log.revision and
48
str(f) not in indirect])
49
indirect.update(this_indirect)
50
if log.continuation_of is not None:
51
# continuations list everything in new_patches
55
ancestor = log.revision.ancestor
56
except pybaz.errors.ExecProblem:
59
if log.revision.patchlevel != 'version-0':
60
ancestor = namespace_previous(log.revision)
64
# ancestor might be in the tree
65
for tree_log in pybaz.WorkingTree(log.tree).iter_logs(
66
log.revision.version, reverse=True):
68
ancestor = tree_log.revision
70
if tree_log.revision == log.revision:
72
print "ancestor of %s is %s" % (log.revision, ancestor)
73
if ancestor is not None:
74
indirect.add(str(ancestor))
75
return [log.revision for log in logs if not str(log.revision) in indirect
76
and log.revision not in excludes]
79
def namespace_previous(revision):
80
if revision.patchlevel == 'base-0':
82
if revision.patchlevel == 'patch-1':
83
return revision.version['base-0']
84
if revision.patchlevel.startswith('patch'):
85
level = int(revision.patchlevel[len('patch-'):]) -1
86
return revision.version['patch-%d' % level]
87
if revision.patchlevel == 'version-0':
88
raise RuntimeError("cannot determine prior namespace level for a "
89
"version-0 patch ('%s')" % revision)
90
if revision.patchlevel == 'versionfix-1':
91
return revision.version['version-0']
92
if revision.patchlevel.startswith('versionfix'):
93
level = int(revision.patchlevel[len('versionfix-'):]) -1
94
return revision.version['versionfix-%d' % level]
95
raise NotImplementedError
97
def iter_new_merges(tree, version, reverse=False):
98
"""List patchlogs that are new in this tree since the last commit.
100
:param tree: The working tree to calculate new revisions in
102
:param version: The version to use when determining new logs
104
:param reverse: If true, list backwards, from newest to oldest
106
:return: An iterator for new revision logs in this tree
107
:rtype: Iterator of `pybaz.Patchlog`
109
assert (isinstance(version, pybaz.Version))
110
for line in _iter_new_merges(tree, version.fullname, reverse):
111
yield pybaz.Patchlog(line, tree)
113
def _iter_new_merges(directory, version, reverse):
114
"""List patchlogs that are new in this tree since the last commit.
116
:param directory: The working tree to calculate new revisions in
118
:param version: The version to use when determining new logs
120
:param reverse: If true, list backwards, from newest to oldest
122
:return: An iterator for names of revisions new in this tree
123
:rtype: Iterator of str
125
args = [ 'new-merges', '--dir', directory ]
127
args.append('--reverse')
129
return sequence_cmd(args)