~bzr-pqm/bzr/bzr.dev

3250.4.1 by Martin Albisetti
Added integration guide for developers
1
=======================
2
Integrating with Bazaar
3
=======================
4
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
5
This page should hopefully become a quick guide to integrating other
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
6
(Python-based) software with Bazaar.
3250.4.1 by Martin Albisetti
Added integration guide for developers
7
8
Manipulating the Working Tree
9
=============================
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
10
Most objects in Bazaar are in files, named after the class they contain.
11
To manipulate the Working Tree we need a valid WorkingTree object, which
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
12
is loaded from the workingtree.py file, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
13
14
  from bzrlib import workingtree
15
  wt = workingtree.WorkingTree.open('/home/jebw/bzrtest')
16
17
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
18
This gives us a WorkingTree object, which has various methods spread over
19
itself, and its parent classes MutableTree and Tree - its worth having a
20
look through these three files (workingtree.py, mutabletree.py and tree.py)
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
21
to see which methods are available.
3250.4.1 by Martin Albisetti
Added integration guide for developers
22
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
23
Compare trees
3250.4.1 by Martin Albisetti
Added integration guide for developers
24
===============
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
25
There are two methods for comparing trees: ``changes_from`` and
26
``iter_changes``.  ``iter_changes`` is more regular and precise, but it is
27
somewhat harder to work with.  See the API documentation for more details.
28
29
``changes_from`` creates a Delta object showing changes::
3250.4.1 by Martin Albisetti
Added integration guide for developers
30
31
  from bzrlib import delta
32
  changes = wt.changes_from(wt.basis_tree())
33
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
34
This gives us a Delta object, which has several lists of files for each type of
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
35
change, eg changes.added is a list of added files, changes.removed is list
36
of removed files, changes.modified is a list of modified files. The contents
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
37
of the lists aren't just filenames, but include other information as well.
3344.1.2 by Martin Pool
Fix ReST syntax in integration guide
38
To grab just the filename we want the first value, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
39
40
  print("list of newly added files")
41
  for filename in changes.added:
42
    print("%s has been added" % filename[0])
43
44
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
45
The exception to this is changes.renamed, where the list returned for each
46
renamed files contains both the old and new names -- one or both may interest
47
you, depending on what you're doing.
3250.4.1 by Martin Albisetti
Added integration guide for developers
48
49
For example::
50
51
  print("list of renamed files")
52
  for filename in changes.renamed:
53
    print("%s has been renamed to %s" % (filename[0], filename[1]))
54
55
56
Adding Files
57
============
58
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
59
If you want to add files the same way ``bzr add`` does, you can use
60
MutableTree.smart_add.  By default, this is recursive. Paths can either be
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
61
absolute or relative to the workingtree::
3250.4.1 by Martin Albisetti
Added integration guide for developers
62
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
63
  wt.smart_add(['dir1/filea.txt', 'fileb.txt',
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
64
                '/home/jebw/bzrtesttree/filec.txt'])
3250.4.1 by Martin Albisetti
Added integration guide for developers
65
66
67
For more precise control over which files to add, use MutableTree.add::
68
69
  wt.add(['dir1/filea.txt', 'fileb.txt', '/home/jebw/bzrtesttree/filec.txt'])
70
71
72
Removing Files
73
==============
74
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
75
You can remove multiple files at once.  The file paths need to be relative
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
76
to the workingtree::
3250.4.1 by Martin Albisetti
Added integration guide for developers
77
78
  wt.remove(['filea.txt', 'fileb.txt', 'dir1'])
79
80
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
81
By default, the files are not deleted, just removed from the inventory.
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
82
To delete them from the filesystem as well::
3250.4.1 by Martin Albisetti
Added integration guide for developers
83
84
  wt.remove(['filea.txt', 'fileb.txt', 'dir1'], keep_files=False)
85
86
87
Renaming a File
88
===============
89
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
90
You can rename one file to a different name using WorkingTree.rename_one.
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
91
You just provide the old and new names, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
92
93
  wt.rename_one('oldfile.txt','newfile.txt')
94
95
96
Moving Files
97
============
98
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
99
You can move multiple files from one directory into another using
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
100
WorkingTree.move::
3250.4.1 by Martin Albisetti
Added integration guide for developers
101
102
  wt.move(['olddir/file.txt'], 'newdir')
103
104
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
105
More complicated renames/moves can be done with transform.TreeTransform,
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
106
which is outside the scope of this document.
3250.4.1 by Martin Albisetti
Added integration guide for developers
107
108
109
Committing Changes
110
==================
111
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
112
To commit _all_ the changes to our working tree we can just call the
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
113
WorkingTree's commit method, giving it a commit message, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
114
115
  wt.commit('this is my commit message')
116
117
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
118
To commit only certain files, we need to provide a list of filenames which we
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
119
want committing, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
120
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
121
  wt.commit(message='this is my commit message', specific_files=['fileA.txt',
122
            'dir2/fileB.txt', 'fileD.txt'])
3250.4.1 by Martin Albisetti
Added integration guide for developers
123
124
125
Generating a Log for a File
126
===========================
127
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
128
Generating a log is, in itself, simple.  Grab a branch (see below) and pass
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
129
it to show_log together with a log formatter, eg::
3250.4.1 by Martin Albisetti
Added integration guide for developers
130
131
  from bzrlib import log
132
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
133
3250.4.1 by Martin Albisetti
Added integration guide for developers
134
  b = branch.Branch.open('/path/to/bazaar/branch')
135
  lf = log.LongLogFormatter(to_file=sys.stdout)
136
  log.show_log(b, lf)
137
138
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
139
Three log formatters are included with bzrlib: LongLogFormatter,
140
ShortLogFormatter and LineLogFormatter.  These provide long, short and
141
single-line log output formats. It's also possible to write your own in
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
142
very little code.
3250.4.1 by Martin Albisetti
Added integration guide for developers
143
144
Annotating a File
145
=================
146
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
147
To annotate a file, we want to walk every line of a file, retrieving the
148
revision which last modified/created that line and then retrieving the
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
149
information for that revision.
3250.4.1 by Martin Albisetti
Added integration guide for developers
150
151
First we get an annotation iterator for the file we are interested in::
152
153
  tree, relpath = workingtree.WorkingTree.open_containing('/path/to/file.txt')
154
  fileid = tree.path2id(relpath)
155
  annotation = list(tree.annotate_iter(fileid))
156
157
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
158
To avoid repeatedly retrieving the same revisions we grab all revisions
159
associated with the file at once and build up a map of id to revision
160
information. We also build an map of revision numbers, again indexed
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
161
by the revision id::
3250.4.1 by Martin Albisetti
Added integration guide for developers
162
163
  revision_ids = set(revision_id for revision_id, text in annotation)
164
  revisions = tree.branch.repository.get_revisions(revision_ids)
165
  revision_map = dict(izip(revision_ids, revisions))
166
  revno_map = tree.branch.get_revision_id_to_revno_map()
167
168
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
169
Finally, we use our annotation iterator to walk the lines of the file,
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
170
displaying the information from our revision maps as we go::
3250.4.1 by Martin Albisetti
Added integration guide for developers
171
172
  for revision_id, text in annotation :
173
      rev = revision_map[revision_id]
174
      revno = revno_map[revision_id]
175
      revno_string = '.'.join(str(i) for i in revno)
176
      print "%s, %s: %s" % (revno_string, rev.committer, text)
177
178
179
Working with branches
180
=====================
181
182
To work with a branch you need a branch object, created from your branch::
183
184
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
185
3250.4.1 by Martin Albisetti
Added integration guide for developers
186
  b = branch.Branch.open('/home/jebw/bzrtest')
187
188
189
Branching from an existing branch
190
=================================
191
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
192
To branch you create a branch object representing the branch you are
193
branching from, and supply a path/url to the new branch location.
194
The following code clones the bzr.dev branch (the latest copy of the Bazaar
195
source code) - be warned it has to download 60meg so takes a while to run
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
196
with no feedback::
3250.4.1 by Martin Albisetti
Added integration guide for developers
197
198
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
199
3250.4.1 by Martin Albisetti
Added integration guide for developers
200
  b = branch.Branch.open('http://bazaar-vcs.org/bzr/bzr.dev')
201
  nb = b.bzrdir.sprout('/tmp/newBzrBranch').open_branch()
202
203
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
204
This provides no feedback, since Bazaar automatically uses the 'silent' UI.
3250.4.1 by Martin Albisetti
Added integration guide for developers
205
206
207
Pushing and pulling branches
208
============================
209
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
210
To push a branch you need to open the source and destination branches, then
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
211
just call push with the other branch as a parameter::
3250.4.1 by Martin Albisetti
Added integration guide for developers
212
213
  from bzrlib import branch
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
214
3250.4.1 by Martin Albisetti
Added integration guide for developers
215
  b1 = branch.Branch.open('file:///home/user/mybranch')
216
  b2 = branch.Branch.open('http://bazaar-vcs.org/bzr/bzr.dev')
217
  b1.push(b2)
218
219
220
Pulling is much the same::
221
222
  b1.pull(b2)
223
224
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
225
If you have a working tree, as well as a branch, you should use
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
226
WorkingTree.pull, not Branch.pull.
3250.4.1 by Martin Albisetti
Added integration guide for developers
227
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
228
This won't handle conflicts automatically though, so any conflicts will be
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
229
left in the working tree for the user to resolve.
3250.4.1 by Martin Albisetti
Added integration guide for developers
230
231
232
Checkout from an existing branch
233
================================
234
235
This performs a Lightweight checkout from an existing Branch::
236
237
  from bzrlib import bzrdir
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
238
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
239
  accelerator_tree, source = bzrdir.BzrDir.open_tree_or_branch('http:URL')
3250.4.1 by Martin Albisetti
Added integration guide for developers
240
  source.create_checkout('/tmp/newBzrCheckout', None, True, accelerator_tree)
241
242
243
To make a heavyweight checkout, change the last line to::
244
245
  source.create_checkout('/tmp/newBzrCheckout', None, False, accelerator_tree
246
247
==================
248
History Operations
249
==================
250
251
Finding the last revision number or id
252
======================================
253
254
To get the last revision number and id of a branch use::
255
256
  revision_number, revision_id = branch.last_revision_info()
257
258
259
If all you care about is the revision_id there is also the
260
method::
261
262
  revision_id = branch.last_revision()
263
264
265
Getting the list of revision ids that make up a branch
266
======================================================
267
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
268
IMPORTANT: This should be avoided wherever possible, as it scales with the
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
269
length of history::
3250.4.1 by Martin Albisetti
Added integration guide for developers
270
271
  revisions = branch.revision_history()
272
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
273
now revisions[0] is the revision id of the first commit, and revs[-1] is the
274
revision id of the most recent. Note that if all you want is the last
275
revision then you should use branch.last_revision() as described above, as
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
276
it is vastly more efficient.
3250.4.1 by Martin Albisetti
Added integration guide for developers
277
278
279
Getting a Revision object from a revision id
280
============================================
281
282
The Revision object has attributes like "message" to get the information
283
about the revision::
284
285
  repo = branch.repository
286
  revision = repo.get_revision(rev_id)
287
288
289
Accessing the files from a revision
290
===================================
291
292
To get the file contents and tree shape for a specific revision you need
293
a RevisionTree. These are supplied by the repository for a specific
294
revision id::
295
296
  revtree = repo.revision_tree(rev_id)
297
3250.4.6 by Martin Albisetti
Added changes sent by Aaron Bently
298
RevisionTrees, like all trees, can be compared as described in "Comparing
299
Trees" above.
3250.4.1 by Martin Albisetti
Added integration guide for developers
300
3250.4.5 by Martin Albisetti
Removed trailing whitespaces
301
The most common way to list files in a tree is ``Tree.iter_entries()``.
302
The simplest way to get file content is ``Tree.get_file()``.  The best way
303
to retrieve file content for large numbers of files `Tree.iter_files_bytes()``
3250.4.4 by Martin Albisetti
Shortened to under 80 characters per line, and removed all wiki-specific information
304