bzr branch
http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
| 485
by Martin Pool - move commit code into its own module | 1 | # Copyright (C) 2005 Canonical Ltd
 | 
| 1248
by Martin Pool - new weave based cleanup [broken] | 2 | #
 | 
| 485
by Martin Pool - move commit code into its own module | 3 | # This program is free software; you can redistribute it and/or modify
 | 
| 4 | # it under the terms of the GNU General Public License as published by
 | |
| 5 | # the Free Software Foundation; either version 2 of the License, or
 | |
| 6 | # (at your option) any later version.
 | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 7 | #
 | 
| 485
by Martin Pool - move commit code into its own module | 8 | # This program is distributed in the hope that it will be useful,
 | 
| 9 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| 10 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| 11 | # GNU General Public License for more details.
 | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 12 | #
 | 
| 485
by Martin Pool - move commit code into its own module | 13 | # You should have received a copy of the GNU General Public License
 | 
| 14 | # along with this program; if not, write to the Free Software
 | |
| 15 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 | |
| 16 | ||
| 17 | ||
| 1248
by Martin Pool - new weave based cleanup [broken] | 18 | # XXX: Can we do any better about making interrupted commits change
 | 
| 19 | # nothing?  Perhaps the best approach is to integrate commit of
 | |
| 20 | # AtomicFiles with releasing the lock on the Branch.
 | |
| 21 | ||
| 22 | # TODO: Separate 'prepare' phase where we find a list of potentially
 | |
| 23 | # committed files.  We then can then pause the commit to prompt for a
 | |
| 24 | # commit message, knowing the summary will be the same as what's
 | |
| 25 | # actually used for the commit.  (But perhaps simpler to simply get
 | |
| 26 | # the tree status, then use that for a selective commit?)
 | |
| 27 | ||
| 28 | # The newly committed revision is going to have a shape corresponding
 | |
| 29 | # to that of the working inventory.  Files that are not in the
 | |
| 30 | # working tree and that were in the predecessor are reported as
 | |
| 31 | # removed --- this can include files that were either removed from the
 | |
| 32 | # inventory or deleted in the working tree.  If they were only
 | |
| 33 | # deleted from disk, they are removed from the working inventory.
 | |
| 34 | ||
| 35 | # We then consider the remaining entries, which will be in the new
 | |
| 36 | # version.  Directory entries are simply copied across.  File entries
 | |
| 37 | # must be checked to see if a new version of the file should be
 | |
| 38 | # recorded.  For each parent revision inventory, we check to see what
 | |
| 39 | # version of the file was present.  If the file was present in at
 | |
| 40 | # least one tree, and if it was the same version in all the trees,
 | |
| 41 | # then we can just refer to that version.  Otherwise, a new version
 | |
| 42 | # representing the merger of the file versions must be added.
 | |
| 43 | ||
| 44 | # TODO: Update hashcache before and after - or does the WorkingTree
 | |
| 45 | # look after that?
 | |
| 1245
by Martin Pool doc | 46 | |
| 1339
by Martin Pool - doc | 47 | # TODO: Rather than mashing together the ancestry and storing it back,
 | 
| 48 | # perhaps the weave should have single method which does it all in one
 | |
| 49 | # go, avoiding a lot of redundant work.
 | |
| 1335
by Martin Pool doc | 50 | |
| 1341
by Martin Pool - doc | 51 | # TODO: Perhaps give a warning if one of the revisions marked as
 | 
| 52 | # merged is already in the ancestry, and then don't record it as a
 | |
| 53 | # distinct parent.
 | |
| 54 | ||
| 1343
by Martin Pool - fix up test for merge of trees | 55 | # TODO: If the file is newly merged but unchanged from the version it
 | 
| 56 | # merges from, then it should still be reported as newly added
 | |
| 57 | # relative to the basis revision.
 | |
| 58 | ||
| 1194
by Martin Pool - [BROKEN] more progress of commit into weaves | 59 | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 60 | import os | 
| 1390
by Robert Collins pair programming worx... merge integration and weave | 61 | import re | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 62 | import sys | 
| 1188
by Martin Pool - clean up imports in commit code | 63 | import time | 
| 1248
by Martin Pool - new weave based cleanup [broken] | 64 | import pdb | 
| 1194
by Martin Pool - [BROKEN] more progress of commit into weaves | 65 | |
| 1188
by Martin Pool - clean up imports in commit code | 66 | from binascii import hexlify | 
| 1194
by Martin Pool - [BROKEN] more progress of commit into weaves | 67 | from cStringIO import StringIO | 
| 1188
by Martin Pool - clean up imports in commit code | 68 | |
| 69 | from bzrlib.osutils import (local_time_offset, username, | |
| 70 | rand_bytes, compact_date, user_email, | |
| 71 | kind_marker, is_inside_any, quotefn, | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 72 | sha_string, sha_strings, sha_file, isdir, isfile, | 
| 73 | split_lines) | |
| 1352
by Martin Pool - store control weaves in .bzr/, not mixed in with file weaves | 74 | from bzrlib.branch import gen_file_id | 
| 1264
by Martin Pool - Raise a better error from commit when a parent is absent | 75 | from bzrlib.errors import (BzrError, PointlessCommit, | 
| 76 | HistoryMissing, | |
| 77 |                            )
 | |
| 1311
by Martin Pool - remove RevisionReference; just hold parent ids directly | 78 | from bzrlib.revision import Revision | 
| 1264
by Martin Pool - Raise a better error from commit when a parent is absent | 79 | from bzrlib.trace import mutter, note, warning | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 80 | from bzrlib.xml5 import serializer_v5 | 
| 1188
by Martin Pool - clean up imports in commit code | 81 | from bzrlib.inventory import Inventory | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 82 | from bzrlib.weave import Weave | 
| 83 | from bzrlib.weavefile import read_weave, write_weave_v5 | |
| 84 | from bzrlib.atomicfile import AtomicFile | |
| 85 | ||
| 86 | ||
| 1205
by Martin Pool - add bzrlib.commit.commit compatability interface | 87 | def commit(*args, **kwargs): | 
| 88 | """Commit a new revision to a branch. | |
| 89 | ||
| 90 |     Function-style interface for convenience of old callers.
 | |
| 91 | ||
| 92 |     New code should use the Commit class instead.
 | |
| 93 |     """
 | |
| 1276
by Martin Pool - make Branch.commit accept (and ignore) verbose argument | 94 |     ## XXX: Remove this in favor of Branch.commit?
 | 
| 1205
by Martin Pool - add bzrlib.commit.commit compatability interface | 95 | Commit().commit(*args, **kwargs) | 
| 96 | ||
| 97 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 98 | class NullCommitReporter(object): | 
| 99 | """I report on progress of a commit.""" | |
| 100 | def added(self, path): | |
| 101 |         pass
 | |
| 102 | ||
| 103 | def removed(self, path): | |
| 104 |         pass
 | |
| 105 | ||
| 106 | def renamed(self, old_path, new_path): | |
| 107 |         pass
 | |
| 108 | ||
| 109 | ||
| 110 | class ReportCommitToLog(NullCommitReporter): | |
| 111 | def added(self, path): | |
| 112 | note('added %s', path) | |
| 113 | ||
| 114 | def removed(self, path): | |
| 115 | note('removed %s', path) | |
| 116 | ||
| 117 | def renamed(self, old_path, new_path): | |
| 118 | note('renamed %s => %s', old_path, new_path) | |
| 119 | ||
| 120 | ||
| 121 | class Commit(object): | |
| 122 | """Task of committing a new revision. | |
| 123 | ||
| 124 |     This is a MethodObject: it accumulates state as the commit is
 | |
| 125 |     prepared, and then it is discarded.  It doesn't represent
 | |
| 126 |     historical revisions, just the act of recording a new one.
 | |
| 127 | ||
| 128 |             missing_ids
 | |
| 129 |             Modified to hold a list of files that have been deleted from
 | |
| 130 |             the working directory; these should be removed from the
 | |
| 131 |             working inventory.
 | |
| 485
by Martin Pool - move commit code into its own module | 132 |     """
 | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 133 | def __init__(self, | 
| 134 | reporter=None): | |
| 135 | if reporter is not None: | |
| 136 | self.reporter = reporter | |
| 137 | else: | |
| 138 | self.reporter = NullCommitReporter() | |
| 139 | ||
| 140 | ||
| 141 | def commit(self, | |
| 142 | branch, message, | |
| 143 | timestamp=None, | |
| 144 | timezone=None, | |
| 145 | committer=None, | |
| 146 | specific_files=None, | |
| 147 | rev_id=None, | |
| 1276
by Martin Pool - make Branch.commit accept (and ignore) verbose argument | 148 | allow_pointless=True, | 
| 149 | verbose=False): | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 150 | """Commit working copy as a new revision. | 
| 151 | ||
| 152 |         timestamp -- if not None, seconds-since-epoch for a
 | |
| 153 |              postdated/predated commit.
 | |
| 154 | ||
| 1253
by Martin Pool - test that pointless commits are trapped | 155 |         specific_files -- If true, commit only those files.
 | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 156 | |
| 1253
by Martin Pool - test that pointless commits are trapped | 157 |         rev_id -- If set, use this as the new revision id.
 | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 158 |             Useful for test or import commands that need to tightly
 | 
| 159 |             control what revisions are assigned.  If you duplicate
 | |
| 160 |             a revision id that exists elsewhere it is your own fault.
 | |
| 161 |             If null (default), a time/random revision id is generated.
 | |
| 1253
by Martin Pool - test that pointless commits are trapped | 162 | |
| 163 |         allow_pointless -- If true (default), commit even if nothing
 | |
| 164 |             has changed and no merges are recorded.
 | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 165 |         """
 | 
| 1285
by Martin Pool - fix bug in committing files that are renamed but not modified | 166 | mutter('preparing to commit') | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 167 | |
| 168 | self.branch = branch | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 169 | self.weave_store = branch.weave_store | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 170 | self.rev_id = rev_id | 
| 171 | self.specific_files = specific_files | |
| 1194
by Martin Pool - [BROKEN] more progress of commit into weaves | 172 | self.allow_pointless = allow_pointless | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 173 | |
| 174 | if timestamp is None: | |
| 175 | self.timestamp = time.time() | |
| 176 | else: | |
| 177 | self.timestamp = long(timestamp) | |
| 178 | ||
| 1248
by Martin Pool - new weave based cleanup [broken] | 179 | if rev_id is None: | 
| 180 | self.rev_id = _gen_revision_id(self.branch, self.timestamp) | |
| 181 | else: | |
| 182 | self.rev_id = rev_id | |
| 183 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 184 | if committer is None: | 
| 185 | self.committer = username(self.branch) | |
| 186 | else: | |
| 187 | assert isinstance(committer, basestring), type(committer) | |
| 188 | self.committer = committer | |
| 189 | ||
| 190 | if timezone is None: | |
| 191 | self.timezone = local_time_offset() | |
| 192 | else: | |
| 193 | self.timezone = int(timezone) | |
| 194 | ||
| 195 | assert isinstance(message, basestring), type(message) | |
| 196 | self.message = message | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 197 | self._escape_commit_message() | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 198 | |
| 1245
by Martin Pool doc | 199 | self.branch.lock_write() | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 200 | try: | 
| 201 | self.work_tree = self.branch.working_tree() | |
| 202 | self.work_inv = self.work_tree.inventory | |
| 203 | self.basis_tree = self.branch.basis_tree() | |
| 204 | self.basis_inv = self.basis_tree.inventory | |
| 205 | ||
| 1223
by Martin Pool - store inventories in weave | 206 | self._gather_parents() | 
| 1344
by Martin Pool - disallow selected-file commit of merges | 207 | if len(self.parents) > 1 and self.specific_files: | 
| 208 | raise NotImplementedError('selected-file commit of merges is not supported yet') | |
| 1284
by Martin Pool - in commit, avoid reading basis inventory twice | 209 | self._check_parents_present() | 
| 210 | ||
| 1251
by Martin Pool - fix up commit in directory with some deleted files | 211 | self._remove_deleted() | 
| 1092.2.22
by Robert Collins text_version and name_version unification looking reasonable | 212 | self._populate_new_inv() | 
| 213 | self._store_snapshot() | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 214 | self._report_deletes() | 
| 1245
by Martin Pool doc | 215 | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 216 | if not (self.allow_pointless | 
| 1279
by Martin Pool - pointless commit of r1 no longer allowed | 217 | or len(self.parents) > 1 | 
| 1249
by Martin Pool - improvements to weave commit [broken] | 218 | or self.new_inv != self.basis_inv): | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 219 | raise PointlessCommit() | 
| 220 | ||
| 221 | self._record_inventory() | |
| 1225
by Martin Pool - branch now tracks ancestry - all merged revisions | 222 | self._record_ancestry() | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 223 | self._make_revision() | 
| 1250
by Martin Pool typo | 224 | note('committed r%d {%s}', (self.branch.revno() + 1), | 
| 1194
by Martin Pool - [BROKEN] more progress of commit into weaves | 225 | self.rev_id) | 
| 226 | self.branch.append_revision(self.rev_id) | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 227 | self.branch.set_pending_merges([]) | 
| 228 | finally: | |
| 229 | self.branch.unlock() | |
| 230 | ||
| 231 | def _record_inventory(self): | |
| 1223
by Martin Pool - store inventories in weave | 232 | """Store the inventory for the new revision.""" | 
| 1248
by Martin Pool - new weave based cleanup [broken] | 233 | inv_text = serializer_v5.write_inventory_to_string(self.new_inv) | 
| 234 | self.inv_sha1 = sha_string(inv_text) | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 235 | s = self.branch.control_weaves | 
| 1352
by Martin Pool - store control weaves in .bzr/, not mixed in with file weaves | 236 | s.add_text('inventory', self.rev_id, | 
| 1092.2.25
by Robert Collins support ghosts in commits | 237 | split_lines(inv_text), self.present_parents) | 
| 1223
by Martin Pool - store inventories in weave | 238 | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 239 | def _escape_commit_message(self): | 
| 240 | """Replace xml-incompatible control characters.""" | |
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 241 |         # Python strings can include characters that can't be
 | 
| 242 |         # represented in well-formed XML; escape characters that
 | |
| 243 |         # aren't listed in the XML specification
 | |
| 244 |         # (http://www.w3.org/TR/REC-xml/#NT-Char).
 | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 245 | if isinstance(self.message, unicode): | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 246 | char_pattern = u'[^\x09\x0A\x0D\u0020-\uD7FF\uE000-\uFFFD]' | 
| 247 | else: | |
| 248 |             # Use a regular 'str' as pattern to avoid having re.subn
 | |
| 249 |             # return 'unicode' results.
 | |
| 250 | char_pattern = '[^x09\x0A\x0D\x20-\xFF]' | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 251 | self.message, escape_count = re.subn( | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 252 | char_pattern, | 
| 253 | lambda match: match.group(0).encode('unicode_escape'), | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 254 | self.message) | 
| 1185.11.5
by John Arbash Meinel Merged up-to-date against mainline, still broken. | 255 | if escape_count: | 
| 256 | note("replaced %d control characters in message", escape_count) | |
| 1223
by Martin Pool - store inventories in weave | 257 | |
| 1225
by Martin Pool - branch now tracks ancestry - all merged revisions | 258 | def _record_ancestry(self): | 
| 1270
by Martin Pool - fix recording of merged ancestry lines | 259 | """Append merged revision ancestry to the ancestry file. | 
| 260 | ||
| 261 |         This should be the merged ancestry of all parents, plus the
 | |
| 262 |         new revision id."""
 | |
| 1390
by Robert Collins pair programming worx... merge integration and weave | 263 | s = self.branch.control_weaves | 
| 1352
by Martin Pool - store control weaves in .bzr/, not mixed in with file weaves | 264 | w = s.get_weave_or_empty('ancestry') | 
| 1333
by Martin Pool - split out merge-ancestry stuff where it can be reused | 265 | lines = self._make_ancestry(w) | 
| 1092.2.25
by Robert Collins support ghosts in commits | 266 | w.add(self.rev_id, self.present_parents, lines) | 
| 1352
by Martin Pool - store control weaves in .bzr/, not mixed in with file weaves | 267 | s.put_weave('ancestry', w) | 
| 1225
by Martin Pool - branch now tracks ancestry - all merged revisions | 268 | |
| 1333
by Martin Pool - split out merge-ancestry stuff where it can be reused | 269 | def _make_ancestry(self, ancestry_weave): | 
| 1270
by Martin Pool - fix recording of merged ancestry lines | 270 | """Return merged ancestry lines. | 
| 271 | ||
| 272 |         The lines are revision-ids followed by newlines."""
 | |
| 1092.2.25
by Robert Collins support ghosts in commits | 273 | parent_ancestries = [ancestry_weave.get(p) for p in self.present_parents] | 
| 1333
by Martin Pool - split out merge-ancestry stuff where it can be reused | 274 | new_lines = merge_ancestry_lines(self.rev_id, parent_ancestries) | 
| 275 | mutter('merged ancestry of {%s}:\n%s', self.rev_id, ''.join(new_lines)) | |
| 276 | return new_lines | |
| 1270
by Martin Pool - fix recording of merged ancestry lines | 277 | |
| 1223
by Martin Pool - store inventories in weave | 278 | def _gather_parents(self): | 
| 1092.2.25
by Robert Collins support ghosts in commits | 279 | """Record the parents of a merge for merge detection.""" | 
| 1223
by Martin Pool - store inventories in weave | 280 | pending_merges = self.branch.pending_merges() | 
| 281 | self.parents = [] | |
| 1408
by Robert Collins we do not need revision_trees in commit, parent inventories are sufficient | 282 | self.parent_invs = [] | 
| 1092.2.25
by Robert Collins support ghosts in commits | 283 | self.present_parents = [] | 
| 1241
by Martin Pool - rename last_patch to last_revision | 284 | precursor_id = self.branch.last_revision() | 
| 1223
by Martin Pool - store inventories in weave | 285 | if precursor_id: | 
| 286 | self.parents.append(precursor_id) | |
| 287 | self.parents += pending_merges | |
| 1092.2.25
by Robert Collins support ghosts in commits | 288 | for revision in self.parents: | 
| 289 | if self.branch.has_revision(revision): | |
| 1408
by Robert Collins we do not need revision_trees in commit, parent inventories are sufficient | 290 | self.parent_invs.append(self.branch.get_inventory(revision)) | 
| 1092.2.25
by Robert Collins support ghosts in commits | 291 | self.present_parents.append(revision) | 
| 1284
by Martin Pool - in commit, avoid reading basis inventory twice | 292 | |
| 293 | def _check_parents_present(self): | |
| 1264
by Martin Pool - Raise a better error from commit when a parent is absent | 294 | for parent_id in self.parents: | 
| 1270
by Martin Pool - fix recording of merged ancestry lines | 295 | mutter('commit parent revision {%s}', parent_id) | 
| 1264
by Martin Pool - Raise a better error from commit when a parent is absent | 296 | if not self.branch.has_revision(parent_id): | 
| 1092.2.25
by Robert Collins support ghosts in commits | 297 | if parent_id == self.branch.last_revision(): | 
| 298 | warning("parent is pissing %r", parent_id) | |
| 299 | raise HistoryMissing(self.branch, 'revision', parent_id) | |
| 300 | else: | |
| 301 | mutter("commit will ghost revision %r", parent_id) | |
| 1284
by Martin Pool - in commit, avoid reading basis inventory twice | 302 | |
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 303 | def _make_revision(self): | 
| 304 | """Record a new revision object for this commit.""" | |
| 305 | self.rev = Revision(timestamp=self.timestamp, | |
| 306 | timezone=self.timezone, | |
| 307 | committer=self.committer, | |
| 308 | message=self.message, | |
| 309 | inventory_sha1=self.inv_sha1, | |
| 310 | revision_id=self.rev_id) | |
| 1313
by Martin Pool - rename to Revision.parent_ids to avoid confusion with old usage | 311 | self.rev.parent_ids = self.parents | 
| 1248
by Martin Pool - new weave based cleanup [broken] | 312 | rev_tmp = StringIO() | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 313 | serializer_v5.write_revision(self.rev, rev_tmp) | 
| 580
by Martin Pool - Use explicit lock methods on a branch, rather than doing it | 314 | rev_tmp.seek(0) | 
| 1393.2.3
by John Arbash Meinel Fixing typos, updating stores, getting tests to pass. | 315 | self.branch.revision_store.add(rev_tmp, self.rev_id) | 
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 316 | mutter('new revision_id is {%s}', self.rev_id) | 
| 317 | ||
| 318 | ||
| 319 | def _remove_deleted(self): | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 320 | """Remove deleted files from the working inventories. | 
| 321 | ||
| 322 |         This is done prior to taking the working inventory as the
 | |
| 323 |         basis for the new committed inventory.
 | |
| 324 | ||
| 325 |         This returns true if any files
 | |
| 326 |         *that existed in the basis inventory* were deleted.
 | |
| 327 |         Files that were added and deleted
 | |
| 328 |         in the working copy don't matter.
 | |
| 329 |         """
 | |
| 1254
by Martin Pool - fix handling of selective commit with deleted files | 330 | specific = self.specific_files | 
| 331 | deleted_ids = [] | |
| 332 | for path, ie in self.work_inv.iter_entries(): | |
| 333 | if specific and not is_inside_any(specific, path): | |
| 334 |                 continue
 | |
| 335 | if not self.work_tree.has_filename(path): | |
| 336 | note('missing %s', path) | |
| 337 | deleted_ids.append(ie.file_id) | |
| 338 | if deleted_ids: | |
| 339 | for file_id in deleted_ids: | |
| 1393.1.21
by Martin Pool - merge merge and export fixes from aaron | 340 | if file_id in self.work_inv: | 
| 341 | del self.work_inv[file_id] | |
| 1249
by Martin Pool - improvements to weave commit [broken] | 342 | self.branch._write_inventory(self.work_inv) | 
| 1248
by Martin Pool - new weave based cleanup [broken] | 343 | |
| 1092.2.22
by Robert Collins text_version and name_version unification looking reasonable | 344 | def _store_snapshot(self): | 
| 345 | """Pass over inventory and record a snapshot. | |
| 1303
by Martin Pool - commit updates entry_version | 346 | |
| 1092.2.21
by Robert Collins convert name_version to revision in inventory entries | 347 |         Entries get a new revision when they are modified in 
 | 
| 348 |         any way, which includes a merge with a new set of
 | |
| 1411
by Robert Collins use weave ancestry to determine inventory entry previous heads, prevent propogating 'I did a merge' merges. | 349 |         parents that have the same entry. 
 | 
| 1092.2.21
by Robert Collins convert name_version to revision in inventory entries | 350 |         """
 | 
| 1303
by Martin Pool - commit updates entry_version | 351 |         # XXX: Need to think more here about when the user has
 | 
| 352 |         # made a specific decision on a particular value -- c.f.
 | |
| 353 |         # mark-merge.  
 | |
| 354 | for path, ie in self.new_inv.iter_entries(): | |
| 1411
by Robert Collins use weave ancestry to determine inventory entry previous heads, prevent propogating 'I did a merge' merges. | 355 | previous_entries = ie.find_previous_heads( | 
| 356 | self.parent_invs, | |
| 357 | self.weave_store.get_weave_or_empty(ie.file_id)) | |
| 1092.2.23
by Robert Collins move inventory entry centric snapshot taking logic to inventory.py | 358 | if ie.revision is None: | 
| 359 | change = ie.snapshot(self.rev_id, path, previous_entries, | |
| 360 | self.work_tree, self.weave_store) | |
| 361 | else: | |
| 362 | change = "unchanged" | |
| 363 | note("%s %s", change, path) | |
| 1092.2.22
by Robert Collins text_version and name_version unification looking reasonable | 364 | |
| 365 | def _populate_new_inv(self): | |
| 366 | """Build revision inventory. | |
| 367 | ||
| 368 |         This creates a new empty inventory. Depending on
 | |
| 369 |         which files are selected for commit, and what is present in the
 | |
| 370 |         current tree, the new inventory is populated. inventory entries 
 | |
| 371 |         which are candidates for modification have their revision set to
 | |
| 372 |         None; inventory entries that are carried over untouched have their
 | |
| 373 |         revision set to their prior value.
 | |
| 1301
by Martin Pool - more docs in commit code | 374 |         """
 | 
| 1092.2.22
by Robert Collins text_version and name_version unification looking reasonable | 375 | mutter("Selecting files for commit with filter %s", self.specific_files) | 
| 376 | self.new_inv = Inventory() | |
| 1249
by Martin Pool - improvements to weave commit [broken] | 377 | for path, new_ie in self.work_inv.iter_entries(): | 
| 378 | file_id = new_ie.file_id | |
| 379 | mutter('check %s {%s}', path, new_ie.file_id) | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 380 | if self.specific_files: | 
| 381 | if not is_inside_any(self.specific_files, path): | |
| 1249
by Martin Pool - improvements to weave commit [broken] | 382 | mutter('%s not selected for commit', path) | 
| 383 | self._carry_file(file_id) | |
| 384 |                     continue
 | |
| 1092.2.22
by Robert Collins text_version and name_version unification looking reasonable | 385 | mutter('%s selected for commit', path) | 
| 386 | ie = new_ie.copy() | |
| 387 | ie.revision = None | |
| 388 | self.new_inv.add(ie) | |
| 1249
by Martin Pool - improvements to weave commit [broken] | 389 | |
| 390 | def _carry_file(self, file_id): | |
| 1285
by Martin Pool - fix bug in committing files that are renamed but not modified | 391 | """Carry the file unchanged from the basis revision.""" | 
| 1249
by Martin Pool - improvements to weave commit [broken] | 392 | if self.basis_inv.has_id(file_id): | 
| 393 | self.new_inv.add(self.basis_inv[file_id].copy()) | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 394 | |
| 395 | def _report_deletes(self): | |
| 396 | for file_id in self.basis_inv: | |
| 397 | if file_id not in self.new_inv: | |
| 398 | note('deleted %s', self.basis_inv.id2path(file_id)) | |
| 399 | ||
| 400 | ||
| 1189
by Martin Pool - BROKEN: partial support for commit into weave | 401 | |
| 402 | def _gen_revision_id(branch, when): | |
| 403 | """Return new revision-id.""" | |
| 404 | s = '%s-%s-' % (user_email(branch), compact_date(when)) | |
| 405 | s += hexlify(rand_bytes(8)) | |
| 406 | return s | |
| 633
by Martin Pool - Show added/renamed/modified messages from commit for non-file | 407 | |
| 1248
by Martin Pool - new weave based cleanup [broken] | 408 | |
| 409 | ||
| 410 | ||
| 1333
by Martin Pool - split out merge-ancestry stuff where it can be reused | 411 | def merge_ancestry_lines(rev_id, ancestries): | 
| 412 | """Return merged ancestry lines. | |
| 413 | ||
| 414 |     rev_id -- id of the new revision
 | |
| 415 |     
 | |
| 416 |     ancestries -- a sequence of ancestries for parent revisions,
 | |
| 417 |         as newline-terminated line lists.
 | |
| 418 |     """
 | |
| 419 | if len(ancestries) == 0: | |
| 420 | return [rev_id + '\n'] | |
| 421 | seen = set(ancestries[0]) | |
| 422 | ancs = ancestries[0][:] | |
| 423 | for parent_ancestry in ancestries[1:]: | |
| 424 | for line in parent_ancestry: | |
| 425 | assert line[-1] == '\n' | |
| 426 | if line not in seen: | |
| 427 | ancs.append(line) | |
| 428 | seen.add(line) | |
| 429 | r = rev_id + '\n' | |
| 430 | assert r not in seen | |
| 431 | ancs.append(r) | |
| 432 | return ancs |