~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/workingtree.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2009-11-17 03:20:35 UTC
  • mfrom: (4792.4.3 456036)
  • Revision ID: pqm@pqm.ubuntu.com-20091117032035-s3sgtlixj1lrminn
(Gordon Tyler) Fix IndexError during 'bzr ignore /' (#456036)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005-2010 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
65
65
    merge,
66
66
    revision as _mod_revision,
67
67
    revisiontree,
 
68
    textui,
68
69
    trace,
69
70
    transform,
70
71
    ui,
543
544
        else:
544
545
            parents = [last_rev]
545
546
        try:
546
 
            merges_bytes = self._transport.get_bytes('pending-merges')
 
547
            merges_file = self._transport.get('pending-merges')
547
548
        except errors.NoSuchFile:
548
549
            pass
549
550
        else:
550
 
            for l in osutils.split_lines(merges_bytes):
 
551
            for l in merges_file.readlines():
551
552
                revision_id = l.rstrip('\n')
552
553
                parents.append(revision_id)
553
554
        return parents
1627
1628
                                this_tree=self,
1628
1629
                                pb=pb,
1629
1630
                                change_reporter=change_reporter)
1630
 
                    basis_root_id = basis_tree.get_root_id()
1631
 
                    new_root_id = new_basis_tree.get_root_id()
1632
 
                    if basis_root_id != new_root_id:
1633
 
                        self.set_root_id(new_root_id)
 
1631
                    if (basis_tree.inventory.root is None and
 
1632
                        new_basis_tree.inventory.root is not None):
 
1633
                        self.set_root_id(new_basis_tree.get_root_id())
1634
1634
                finally:
1635
1635
                    pb.finished()
1636
1636
                    basis_tree.unlock()
1845
1845
    def _reset_data(self):
1846
1846
        """Reset transient data that cannot be revalidated."""
1847
1847
        self._inventory_is_modified = False
1848
 
        f = self._transport.get('inventory')
1849
 
        try:
1850
 
            result = self._deserialize(f)
1851
 
        finally:
1852
 
            f.close()
 
1848
        result = self._deserialize(self._transport.get('inventory'))
1853
1849
        self._set_inventory(result, dirty=False)
1854
1850
 
1855
1851
    @needs_tree_write_lock
1931
1927
        # binary.
1932
1928
        if self._inventory_is_modified:
1933
1929
            raise errors.InventoryModified(self)
1934
 
        f = self._transport.get('inventory')
1935
 
        try:
1936
 
            result = self._deserialize(f)
1937
 
        finally:
1938
 
            f.close()
 
1930
        result = self._deserialize(self._transport.get('inventory'))
1939
1931
        self._set_inventory(result, dirty=False)
1940
1932
        return result
1941
1933
 
1956
1948
 
1957
1949
        new_files=set()
1958
1950
        unknown_nested_files=set()
1959
 
        if to_file is None:
1960
 
            to_file = sys.stdout
1961
1951
 
1962
1952
        def recurse_directory_to_add_files(directory):
1963
1953
            # Recurse directory and add all files
2033
2023
                        new_status = 'I'
2034
2024
                    else:
2035
2025
                        new_status = '?'
2036
 
                    # XXX: Really should be a more abstract reporter interface
2037
 
                    kind_ch = osutils.kind_marker(self.kind(fid))
2038
 
                    to_file.write(new_status + '       ' + f + kind_ch + '\n')
 
2026
                    textui.show_status(new_status, self.kind(fid), f,
 
2027
                                       to_file=to_file)
2039
2028
                # Unversion file
2040
2029
                inv_delta.append((f, None, fid, None))
2041
2030
                message = "removed %s" % (f,)
2192
2181
        """
2193
2182
        raise NotImplementedError(self.unlock)
2194
2183
 
2195
 
    _marker = object()
2196
 
 
2197
 
    def update(self, change_reporter=None, possible_transports=None,
2198
 
               revision=None, old_tip=_marker):
 
2184
    def update(self, change_reporter=None, possible_transports=None):
2199
2185
        """Update a working tree along its branch.
2200
2186
 
2201
2187
        This will update the branch if its bound too, which means we have
2219
2205
        - Merge current state -> basis tree of the master w.r.t. the old tree
2220
2206
          basis.
2221
2207
        - Do a 'normal' merge of the old branch basis if it is relevant.
2222
 
 
2223
 
        :param revision: The target revision to update to. Must be in the
2224
 
            revision history.
2225
 
        :param old_tip: If branch.update() has already been run, the value it
2226
 
            returned (old tip of the branch or None). _marker is used
2227
 
            otherwise.
2228
2208
        """
2229
2209
        if self.branch.get_bound_location() is not None:
2230
2210
            self.lock_write()
2231
 
            update_branch = (old_tip is self._marker)
 
2211
            update_branch = True
2232
2212
        else:
2233
2213
            self.lock_tree_write()
2234
2214
            update_branch = False
2236
2216
            if update_branch:
2237
2217
                old_tip = self.branch.update(possible_transports)
2238
2218
            else:
2239
 
                if old_tip is self._marker:
2240
 
                    old_tip = None
2241
 
            return self._update_tree(old_tip, change_reporter, revision)
 
2219
                old_tip = None
 
2220
            return self._update_tree(old_tip, change_reporter)
2242
2221
        finally:
2243
2222
            self.unlock()
2244
2223
 
2245
2224
    @needs_tree_write_lock
2246
 
    def _update_tree(self, old_tip=None, change_reporter=None, revision=None):
 
2225
    def _update_tree(self, old_tip=None, change_reporter=None):
2247
2226
        """Update a tree to the master branch.
2248
2227
 
2249
2228
        :param old_tip: if supplied, the previous tip revision the branch,
2264
2243
            last_rev = self.get_parent_ids()[0]
2265
2244
        except IndexError:
2266
2245
            last_rev = _mod_revision.NULL_REVISION
2267
 
        if revision is None:
2268
 
            revision = self.branch.last_revision()
2269
 
        else:
2270
 
            if revision not in self.branch.revision_history():
2271
 
                raise errors.NoSuchRevision(self.branch, revision)
2272
 
        if last_rev != _mod_revision.ensure_null(revision):
2273
 
            # merge tree state up to specified revision.
 
2246
        if last_rev != _mod_revision.ensure_null(self.branch.last_revision()):
 
2247
            # merge tree state up to new branch tip.
2274
2248
            basis = self.basis_tree()
2275
2249
            basis.lock_read()
2276
2250
            try:
2277
 
                to_tree = self.branch.repository.revision_tree(revision)
2278
 
                to_root_id = to_tree.get_root_id()
2279
 
                if (basis.inventory.root is None
2280
 
                    or basis.inventory.root.file_id != to_root_id):
2281
 
                    self.set_root_id(to_root_id)
 
2251
                to_tree = self.branch.basis_tree()
 
2252
                if basis.inventory.root is None:
 
2253
                    self.set_root_id(to_tree.get_root_id())
2282
2254
                    self.flush()
2283
2255
                result += merge.merge_inner(
2284
2256
                                      self.branch,
2286
2258
                                      basis,
2287
2259
                                      this_tree=self,
2288
2260
                                      change_reporter=change_reporter)
2289
 
                self.set_last_revision(revision)
2290
2261
            finally:
2291
2262
                basis.unlock()
2292
2263
            # TODO - dedup parents list with things merged by pull ?
2293
2264
            # reuse the tree we've updated to to set the basis:
2294
 
            parent_trees = [(revision, to_tree)]
 
2265
            parent_trees = [(self.branch.last_revision(), to_tree)]
2295
2266
            merges = self.get_parent_ids()[1:]
2296
2267
            # Ideally we ask the tree for the trees here, that way the working
2297
2268
            # tree can decide whether to give us the entire tree or give us a
2327
2298
            #       should be able to remove this extra flush.
2328
2299
            self.flush()
2329
2300
            graph = self.branch.repository.get_graph()
2330
 
            base_rev_id = graph.find_unique_lca(revision, old_tip)
 
2301
            base_rev_id = graph.find_unique_lca(self.branch.last_revision(),
 
2302
                                                old_tip)
2331
2303
            base_tree = self.branch.repository.revision_tree(base_rev_id)
2332
2304
            other_tree = self.branch.repository.revision_tree(old_tip)
2333
2305
            result += merge.merge_inner(
2612
2584
        """
2613
2585
        return
2614
2586
 
 
2587
    @needs_read_lock
2615
2588
    def _get_rules_searcher(self, default_searcher):
2616
2589
        """See Tree._get_rules_searcher."""
2617
2590
        if self._rules_searcher is None:
2796
2769
        """Return the format for the working tree object in a_bzrdir."""
2797
2770
        try:
2798
2771
            transport = a_bzrdir.get_workingtree_transport(None)
2799
 
            format_string = transport.get_bytes("format")
 
2772
            format_string = transport.get("format").read()
2800
2773
            return klass._formats[format_string]
2801
2774
        except errors.NoSuchFile:
2802
2775
            raise errors.NoWorkingTree(base=transport.base)