~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/knit.py

  • Committer: Robert Collins
  • Date: 2007-09-19 05:14:14 UTC
  • mto: (2835.1.1 ianc-integration)
  • mto: This revision was merged to the branch mainline in revision 2836.
  • Revision ID: robertc@robertcollins.net-20070919051414-2tgjqteg7k3ps4h0
* ``pull``, ``merge`` and ``push`` will no longer silently correct some
  repository index errors that occured as a result of the Weave disk format.
  Instead the ``reconcile`` command needs to be run to correct those
  problems if they exist (and it has been able to fix most such problems
  since bzr 0.8). Some new problems have been identified during this release
  and you should run ``bzr check`` once on every repository to see if you
  need to reconcile. If you cannot ``pull`` or ``merge`` from a remote
  repository due to mismatched parent errors - a symptom of index errors -
  you should simply take a full copy of that remote repository to a clean
  directory outside any local repositories, then run reconcile on it, and
  finally pull from it locally. (And naturally email the repositories owner
  to ask them to upgrade and run reconcile).
  (Robert Collins)

* ``VersionedFile.fix_parents`` has been removed as a harmful API.
  ``VersionedFile.join`` will no longer accept different parents on either
  side of a join - it will either ignore them, or error, depending on the
  implementation. See notes when upgrading for more information.
  (Robert Collins)

Show diffs side-by-side

added added

removed removed

Lines of Context:
534
534
        return KnitVersionedFile(name, transport, factory=self.factory,
535
535
                                 delta=self.delta, create=True)
536
536
    
537
 
    def _fix_parents(self, version_id, new_parents):
538
 
        """Fix the parents list for version.
539
 
        
540
 
        This is done by appending a new version to the index
541
 
        with identical data except for the parents list.
542
 
        the parents list must be a superset of the current
543
 
        list.
544
 
        """
545
 
        current_values = self._index._cache[version_id]
546
 
        assert set(current_values[4]).difference(set(new_parents)) == set()
547
 
        self._index.add_version(version_id,
548
 
                                current_values[1],
549
 
                                (None, current_values[2], current_values[3]),
550
 
                                new_parents)
551
 
 
552
537
    def get_data_stream(self, required_versions):
553
538
        """Get a data stream for the specified versions.
554
539
 
2201
2186
    
2202
2187
            self.source_ancestry = set(self.source.get_ancestry(version_ids))
2203
2188
            this_versions = set(self.target._index.get_versions())
 
2189
            # XXX: For efficiency we should not look at the whole index,
 
2190
            #      we only need to consider the referenced revisions - they
 
2191
            #      must all be present, or the method must be full-text.
 
2192
            #      TODO, RBC 20070919
2204
2193
            needed_versions = self.source_ancestry - this_versions
2205
 
            cross_check_versions = self.source_ancestry.intersection(this_versions)
2206
 
            mismatched_versions = set()
2207
 
            for version in cross_check_versions:
2208
 
                # scan to include needed parents.
2209
 
                n1 = set(self.target.get_parents_with_ghosts(version))
2210
 
                n2 = set(self.source.get_parents_with_ghosts(version))
2211
 
                if n1 != n2:
2212
 
                    # FIXME TEST this check for cycles being introduced works
2213
 
                    # the logic is we have a cycle if in our graph we are an
2214
 
                    # ancestor of any of the n2 revisions.
2215
 
                    for parent in n2:
2216
 
                        if parent in n1:
2217
 
                            # safe
2218
 
                            continue
2219
 
                        else:
2220
 
                            parent_ancestors = self.source.get_ancestry(parent)
2221
 
                            if version in parent_ancestors:
2222
 
                                raise errors.GraphCycleError([parent, version])
2223
 
                    # ensure this parent will be available later.
2224
 
                    new_parents = n2.difference(n1)
2225
 
                    needed_versions.update(new_parents.difference(this_versions))
2226
 
                    mismatched_versions.add(version)
2227
2194
    
2228
 
            if not needed_versions and not mismatched_versions:
 
2195
            if not needed_versions:
2229
2196
                return 0
2230
2197
            full_list = topo_sort(self.source.get_graph())
2231
2198
    
2268
2235
                raw_records.append((version_id, options, parents, len(raw_data)))
2269
2236
                raw_datum.append(raw_data)
2270
2237
            self.target._add_raw_records(raw_records, ''.join(raw_datum))
2271
 
 
2272
 
            for version in mismatched_versions:
2273
 
                # FIXME RBC 20060309 is this needed?
2274
 
                n1 = set(self.target.get_parents_with_ghosts(version))
2275
 
                n2 = set(self.source.get_parents_with_ghosts(version))
2276
 
                # write a combined record to our history preserving the current 
2277
 
                # parents as first in the list
2278
 
                new_parents = self.target.get_parents_with_ghosts(version) + list(n2.difference(n1))
2279
 
                self.target.fix_parents(version, new_parents)
2280
2238
            return count
2281
2239
        finally:
2282
2240
            pb.finished()
2317
2275
            self.source_ancestry = set(self.source.get_ancestry(version_ids))
2318
2276
            this_versions = set(self.target._index.get_versions())
2319
2277
            needed_versions = self.source_ancestry - this_versions
2320
 
            cross_check_versions = self.source_ancestry.intersection(this_versions)
2321
 
            mismatched_versions = set()
2322
 
            for version in cross_check_versions:
2323
 
                # scan to include needed parents.
2324
 
                n1 = set(self.target.get_parents_with_ghosts(version))
2325
 
                n2 = set(self.source.get_parents(version))
2326
 
                # if all of n2's parents are in n1, then its fine.
2327
 
                if n2.difference(n1):
2328
 
                    # FIXME TEST this check for cycles being introduced works
2329
 
                    # the logic is we have a cycle if in our graph we are an
2330
 
                    # ancestor of any of the n2 revisions.
2331
 
                    for parent in n2:
2332
 
                        if parent in n1:
2333
 
                            # safe
2334
 
                            continue
2335
 
                        else:
2336
 
                            parent_ancestors = self.source.get_ancestry(parent)
2337
 
                            if version in parent_ancestors:
2338
 
                                raise errors.GraphCycleError([parent, version])
2339
 
                    # ensure this parent will be available later.
2340
 
                    new_parents = n2.difference(n1)
2341
 
                    needed_versions.update(new_parents.difference(this_versions))
2342
 
                    mismatched_versions.add(version)
2343
2278
    
2344
 
            if not needed_versions and not mismatched_versions:
 
2279
            if not needed_versions:
2345
2280
                return 0
2346
2281
            full_list = topo_sort(self.source.get_graph())
2347
2282
    
2361
2296
                self.target.add_lines(
2362
2297
                    version_id, parents, self.source.get_lines(version_id))
2363
2298
                count = count + 1
2364
 
 
2365
 
            for version in mismatched_versions:
2366
 
                # FIXME RBC 20060309 is this needed?
2367
 
                n1 = set(self.target.get_parents_with_ghosts(version))
2368
 
                n2 = set(self.source.get_parents(version))
2369
 
                # write a combined record to our history preserving the current 
2370
 
                # parents as first in the list
2371
 
                new_parents = self.target.get_parents_with_ghosts(version) + list(n2.difference(n1))
2372
 
                self.target.fix_parents(version, new_parents)
2373
2299
            return count
2374
2300
        finally:
2375
2301
            pb.finished()