~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/branch.py

  • Committer: mbp at sourcefrog
  • Date: 2005-03-23 06:25:55 UTC
  • Revision ID: mbp@sourcefrog.net-20050323062555-5489339018d0c043
- import a subset of elementtree for easier installation

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
from inventory import InventoryEntry, Inventory
29
29
from osutils import isdir, quotefn, isfile, uuid, sha_file, username, chomp, \
30
30
     format_date, compact_date, pumpfile, user_email, rand_bytes, splitpath, \
31
 
     joinpath, sha_string, file_kind, local_time_offset, appendpath
 
31
     joinpath, sha_string, file_kind, local_time_offset
32
32
from store import ImmutableStore
33
33
from revision import Revision
34
34
from errors import bailout
162
162
        self.controlfile('README', 'w').write(
163
163
            "This is a Bazaar-NG control directory.\n"
164
164
            "Do not change any files in this directory.")
165
 
        self.controlfile('branch-format', 'wb').write(BZR_BRANCH_FORMAT)
 
165
        self.controlfile('branch-format', 'w').write(BZR_BRANCH_FORMAT)
166
166
        for d in ('text-store', 'inventory-store', 'revision-store'):
167
167
            os.mkdir(self.controlfilename(d))
168
168
        for f in ('revision-history', 'merged-patches',
179
179
 
180
180
        In the future, we might need different in-memory Branch
181
181
        classes to support downlevel branches.  But not yet.
182
 
        """
183
 
        # This ignores newlines so that we can open branches created
184
 
        # on Windows from Linux and so on.  I think it might be better
185
 
        # to always make all internal files in unix format.
 
182
        """        
 
183
        # read in binary mode to detect newline wierdness.
186
184
        fmt = self.controlfile('branch-format', 'rb').read()
187
 
        fmt.replace('\r\n', '')
188
185
        if fmt != BZR_BRANCH_FORMAT:
189
186
            bailout('sorry, branch format %r not supported' % fmt,
190
187
                    ['use a different bzr version',
212
209
        tmpf = file(tmpfname, 'w')
213
210
        inv.write_xml(tmpf)
214
211
        tmpf.close()
215
 
        inv_fname = self.controlfilename('inventory')
216
 
        if sys.platform == 'win32':
217
 
            os.remove(inv_fname)
218
 
        os.rename(tmpfname, inv_fname)
 
212
        os.rename(tmpfname, self.controlfilename('inventory'))
219
213
        mutter('wrote working inventory')
220
214
 
221
215
 
486
480
                            state = 'A'
487
481
                        elif (old_ie.name == entry.name
488
482
                              and old_ie.parent_id == entry.parent_id):
 
483
                            state = 'R'
 
484
                        else:
489
485
                            state = 'M'
490
 
                        else:
491
 
                            state = 'R'
492
486
 
493
487
                        show_status(state, entry.kind, quotefn(path))
494
488
 
548
542
        mutter("committing patch r%d" % (self.revno() + 1))
549
543
 
550
544
        mutter("append to revision-history")
551
 
        f = self.controlfile('revision-history', 'at')
552
 
        f.write(rev_id + '\n')
553
 
        f.close()
 
545
        self.controlfile('revision-history', 'at').write(rev_id + '\n')
554
546
 
555
 
        if verbose:
556
 
            note("commited r%d" % self.revno())
 
547
        mutter("done!")
557
548
 
558
549
 
559
550
    def get_revision(self, revision_id):
702
693
            precursor = p
703
694
 
704
695
 
705
 
    def rename_one(self, from_rel, to_rel):
706
 
        tree = self.working_tree()
707
 
        inv = tree.inventory
708
 
        if not tree.has_filename(from_rel):
709
 
            bailout("can't rename: old working file %r does not exist" % from_rel)
710
 
        if tree.has_filename(to_rel):
711
 
            bailout("can't rename: new working file %r already exists" % to_rel)
712
 
            
713
 
        file_id = inv.path2id(from_rel)
714
 
        if file_id == None:
715
 
            bailout("can't rename: old name %r is not versioned" % from_rel)
716
 
 
717
 
        if inv.path2id(to_rel):
718
 
            bailout("can't rename: new name %r is already versioned" % to_rel)
719
 
 
720
 
        to_dir, to_tail = os.path.split(to_rel)
721
 
        to_dir_id = inv.path2id(to_dir)
722
 
        if to_dir_id == None and to_dir != '':
723
 
            bailout("can't determine destination directory id for %r" % to_dir)
724
 
 
725
 
        mutter("rename_one:")
726
 
        mutter("  file_id    {%s}" % file_id)
727
 
        mutter("  from_rel   %r" % from_rel)
728
 
        mutter("  to_rel     %r" % to_rel)
729
 
        mutter("  to_dir     %r" % to_dir)
730
 
        mutter("  to_dir_id  {%s}" % to_dir_id)
731
 
            
732
 
        inv.rename(file_id, to_dir_id, to_tail)
733
 
        os.rename(self.abspath(from_rel), self.abspath(to_rel))
734
 
 
735
 
        self._write_inventory(inv)
736
 
            
737
 
 
738
 
 
739
 
    def rename(self, from_paths, to_name):
740
 
        """Rename files.
741
 
 
742
 
        If to_name exists and is a directory, the files are moved into
743
 
        it, keeping their old names.  If it is a directory, 
744
 
 
745
 
        Note that to_name is only the last component of the new name;
746
 
        this doesn't change the directory.
747
 
        """
748
 
        ## TODO: Option to move IDs only
749
 
        assert not isinstance(from_paths, basestring)
750
 
        tree = self.working_tree()
751
 
        inv = tree.inventory
752
 
        dest_dir = isdir(self.abspath(to_name))
753
 
        if dest_dir:
754
 
            # TODO: Wind back properly if some can't be moved?
755
 
            dest_dir_id = inv.path2id(to_name)
756
 
            if not dest_dir_id and to_name != '':
757
 
                bailout("destination %r is not a versioned directory" % to_name)
758
 
            for f in from_paths:
759
 
                name_tail = splitpath(f)[-1]
760
 
                dest_path = appendpath(to_name, name_tail)
761
 
                print "%s => %s" % (f, dest_path)
762
 
                inv.rename(inv.path2id(f), dest_dir_id, name_tail)
763
 
                os.rename(self.abspath(f), self.abspath(dest_path))
764
 
            self._write_inventory(inv)
765
 
        else:
766
 
            if len(from_paths) != 1:
767
 
                bailout("when moving multiple files, destination must be a directory")
768
 
            bailout("rename to non-directory %r not implemented sorry" % to_name)
769
 
 
770
 
 
771
696
 
772
697
    def show_status(branch, show_all=False):
773
698
        """Display single-line status for non-ignored working files.
839
764
    >>> isdir(bd)
840
765
    False
841
766
    """
842
 
    def __init__(self, files=[], dirs=[]):
 
767
    def __init__(self, files = []):
843
768
        """Make a test branch.
844
769
 
845
770
        This creates a temporary directory and runs init-tree in it.
847
772
        If any files are listed, they are created in the working copy.
848
773
        """
849
774
        Branch.__init__(self, tempfile.mkdtemp(), init=True)
850
 
        for d in dirs:
851
 
            os.mkdir(self.abspath(d))
852
 
            
853
775
        for f in files:
854
776
            file(os.path.join(self.base, f), 'w').write('content of %s' % f)
855
777
 
856
778
 
857
779
    def __del__(self):
858
780
        """Destroy the test branch, removing the scratch directory."""
859
 
        try:
860
 
            shutil.rmtree(self.base)
861
 
        except OSError:
862
 
            # Work around for shutil.rmtree failing on Windows when
863
 
            # readonly files are encountered
864
 
            for root, dirs, files in os.walk(self.base, topdown=False):
865
 
                for name in files:
866
 
                    os.chmod(os.path.join(root, name), 0700)
867
 
            shutil.rmtree(self.base)
 
781
        shutil.rmtree(self.base)
868
782
 
869
783
    
870
784