Exemple #1
0
 def conflicts(self):
     conflicts = _mod_conflicts.ConflictList()
     for conflicted in self._iter_conflicts():
         text = True
         try:
             if osutils.file_kind(self.abspath(conflicted)) != "file":
                 text = False
         except errors.NoSuchFile:
             text = False
         if text is True:
             for suffix in ('.THIS', '.OTHER'):
                 try:
                     kind = osutils.file_kind(
                         self.abspath(conflicted + suffix))
                     if kind != "file":
                         text = False
                 except errors.NoSuchFile:
                     text = False
                 if text == False:
                     break
         ctype = {True: 'text conflict', False: 'contents conflict'}[text]
         conflicts.append(
             _mod_conflicts.Conflict.factory(
                 ctype, path=conflicted, file_id=self.path2id(conflicted)))
     return conflicts
Exemple #2
0
 def test_merge_kind_change(self):
     tree_a = self.make_branch_and_tree('tree_a')
     self.build_tree_contents([('tree_a/file', 'content_1')])
     tree_a.add('file', 'file-id')
     tree_a.commit('added file')
     tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
     os.unlink('tree_a/file')
     self.build_tree(['tree_a/file/'])
     tree_a.commit('changed file to directory')
     self.run_bzr('merge ../tree_a', working_dir='tree_b')
     self.assertEqual('directory', osutils.file_kind('tree_b/file'))
     tree_b.revert()
     self.assertEqual('file', osutils.file_kind('tree_b/file'))
     self.build_tree_contents([('tree_b/file', 'content_2')])
     tree_b.commit('content change')
     self.run_bzr('merge ../tree_a', retcode=1, working_dir='tree_b')
     self.assertEqual(tree_b.conflicts(),
                      [conflicts.ContentsConflict('file',
                                                  file_id='file-id')])
Exemple #3
0
 def test_merge_kind_change(self):
     tree_a = self.make_branch_and_tree('tree_a')
     self.build_tree_contents([('tree_a/file', 'content_1')])
     tree_a.add('file', 'file-id')
     tree_a.commit('added file')
     tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
     os.unlink('tree_a/file')
     self.build_tree(['tree_a/file/'])
     tree_a.commit('changed file to directory')
     os.chdir('tree_b')
     self.run_bzr('merge ../tree_a')
     self.assertEqual('directory', file_kind('file'))
     tree_b.revert()
     self.assertEqual('file', file_kind('file'))
     self.build_tree_contents([('file', 'content_2')])
     tree_b.commit('content change')
     self.run_bzr('merge ../tree_a', retcode=1)
     self.assertEqual(tree_b.conflicts(),
                      [ContentsConflict('file', file_id='file-id')])
Exemple #4
0
 def load(self):
     kind = osutils.file_kind(self.filename)
     text = ''
     if kind == 'file':
         f = open(self.filename, 'rb')
         try:
             text = f.read()
         finally:
             f.close()
     elif kind == 'symlink':
         text = os.readlink(self.filename)
     self.text = text
     self._create_and_show_browser(self.filename, text, kind)
 def conflicts(self):
     conflicts = _mod_conflicts.ConflictList()
     for conflicted in self._iter_conflicts():
         text = True
         try:
             if osutils.file_kind(self.abspath(conflicted)) != "file":
                 text = False
         except errors.NoSuchFile:
             text = False
         if text is True:
             for suffix in ('.THIS', '.OTHER'):
                 try:
                     kind = osutils.file_kind(self.abspath(conflicted+suffix))
                     if kind != "file":
                         text = False
                 except errors.NoSuchFile:
                     text = False
                 if text == False:
                     break
         ctype = {True: 'text conflict', False: 'contents conflict'}[text]
         conflicts.append(_mod_conflicts.Conflict.factory(ctype,
                          path=conflicted,
                          file_id=self.path2id(conflicted)))
     return conflicts
Exemple #6
0
    def smart_add(self, file_list, recurse=True, action=None, save=True):
        """Version file_list, optionally recursing into directories.

        This is designed more towards DWIM for humans than API clarity.
        For the specific behaviour see the help for cmd_add().

        :param action: A reporter to be called with the inventory, parent_ie,
            path and kind of the path being added. It may return a file_id if 
            a specific one should be used.
        :param save: Save the inventory after completing the adds. If False
            this provides dry-run functionality by doing the add and not saving
            the inventory.
        :return: A tuple - files_added, ignored_files. files_added is the count
            of added files, and ignored_files is a dict mapping files that were
            ignored to the rule that caused them to be ignored.
        """
        # not in an inner loop; and we want to remove direct use of this,
        # so here as a reminder for now. RBC 20070703
        from bzrlib.inventory import InventoryEntry
        if action is None:
            action = add.AddAction()
        
        if not file_list:
            # no paths supplied: add the entire tree.
            file_list = [u'.']
        # mutter("smart add of %r")
        inv = self.inventory
        added = []
        ignored = {}
        dirs_to_add = []
        user_dirs = set()

        # validate user file paths and convert all paths to tree 
        # relative : it's cheaper to make a tree relative path an abspath
        # than to convert an abspath to tree relative.
        for filepath in file_list:
            rf = _FastPath(self.relpath(filepath))
            # validate user parameters. Our recursive code avoids adding new files
            # that need such validation 
            if self.is_control_filename(rf.raw_path):
                raise errors.ForbiddenControlFileError(filename=rf.raw_path)
            
            abspath = self.abspath(rf.raw_path)
            kind = osutils.file_kind(abspath)
            if kind == 'directory':
                # schedule the dir for scanning
                user_dirs.add(rf)
            else:
                if not InventoryEntry.versionable_kind(kind):
                    raise errors.BadFileKindError(filename=abspath, kind=kind)
            # ensure the named path is added, so that ignore rules in the later directory
            # walk dont skip it.
            # we dont have a parent ie known yet.: use the relatively slower inventory 
            # probing method
            versioned = inv.has_filename(rf.raw_path)
            if versioned:
                continue
            added.extend(_add_one_and_parent(self, inv, None, rf, kind, action))

        if not recurse:
            # no need to walk any directories at all.
            if len(added) > 0 and save:
                self._write_inventory(inv)
            return added, ignored

        # only walk the minimal parents needed: we have user_dirs to override
        # ignores.
        prev_dir = None

        is_inside = osutils.is_inside_or_parent_of_any
        for path in sorted(user_dirs):
            if (prev_dir is None or not is_inside([prev_dir], path.raw_path)):
                dirs_to_add.append((path, None))
            prev_dir = path.raw_path

        # dirs_to_add is initialised to a list of directories, but as we scan
        # directories we append files to it.
        # XXX: We should determine kind of files when we scan them rather than
        # adding to this list. RBC 20070703
        for directory, parent_ie in dirs_to_add:
            # directory is tree-relative
            abspath = self.abspath(directory.raw_path)

            # get the contents of this directory.

            # find the kind of the path being added.
            kind = osutils.file_kind(abspath)

            if not InventoryEntry.versionable_kind(kind):
                warning("skipping %s (can't add file of kind '%s')", abspath, kind)
                continue

            if parent_ie is not None:
                versioned = directory.base_path in parent_ie.children
            else:
                # without the parent ie, use the relatively slower inventory 
                # probing method
                versioned = inv.has_filename(directory.raw_path)

            if kind == 'directory':
                try:
                    sub_branch = bzrdir.BzrDir.open(abspath)
                    sub_tree = True
                except errors.NotBranchError:
                    sub_tree = False
                except errors.UnsupportedFormatError:
                    sub_tree = True
            else:
                sub_tree = False

            if directory.raw_path == '':
                # mutter("tree root doesn't need to be added")
                sub_tree = False
            elif versioned:
                pass
                # mutter("%r is already versioned", abspath)
            elif sub_tree:
                # XXX: This is wrong; people *might* reasonably be trying to add
                # subtrees as subtrees.  This should probably only be done in formats 
                # which can represent subtrees, and even then perhaps only when
                # the user asked to add subtrees.  At the moment you can add them
                # specially through 'join --reference', which is perhaps
                # reasonable: adding a new reference is a special operation and
                # can have a special behaviour.  mbp 20070306
                mutter("%r is a nested bzr tree", abspath)
            else:
                _add_one(self, inv, parent_ie, directory, kind, action)
                added.append(directory.raw_path)

            if kind == 'directory' and not sub_tree:
                if parent_ie is not None:
                    # must be present:
                    this_ie = parent_ie.children[directory.base_path]
                else:
                    # without the parent ie, use the relatively slower inventory 
                    # probing method
                    this_id = inv.path2id(directory.raw_path)
                    if this_id is None:
                        this_ie = None
                    else:
                        this_ie = inv[this_id]

                for subf in sorted(os.listdir(abspath)):
                    # here we could use TreeDirectory rather than 
                    # string concatenation.
                    subp = osutils.pathjoin(directory.raw_path, subf)
                    # TODO: is_control_filename is very slow. Make it faster. 
                    # TreeDirectory.is_control_filename could also make this 
                    # faster - its impossible for a non root dir to have a 
                    # control file.
                    if self.is_control_filename(subp):
                        mutter("skip control directory %r", subp)
                    elif subf in this_ie.children:
                        # recurse into this already versioned subdir.
                        dirs_to_add.append((_FastPath(subp, subf), this_ie))
                    else:
                        # user selection overrides ignoes
                        # ignore while selecting files - if we globbed in the
                        # outer loop we would ignore user files.
                        ignore_glob = self.is_ignored(subp)
                        if ignore_glob is not None:
                            # mutter("skip ignored sub-file %r", subp)
                            ignored.setdefault(ignore_glob, []).append(subp)
                        else:
                            #mutter("queue to add sub-file %r", subp)
                            dirs_to_add.append((_FastPath(subp, subf), this_ie))

        if len(added) > 0:
            if save:
                self._write_inventory(inv)
            else:
                self.read_working_inventory()
        return added, ignored
Exemple #7
0
    def smart_add(self, file_list, recurse=True, action=None, save=True):
        """Version file_list, optionally recursing into directories.

        This is designed more towards DWIM for humans than API clarity.
        For the specific behaviour see the help for cmd_add().

        :param action: A reporter to be called with the inventory, parent_ie,
            path and kind of the path being added. It may return a file_id if 
            a specific one should be used.
        :param save: Save the inventory after completing the adds. If False
            this provides dry-run functionality by doing the add and not saving
            the inventory.
        :return: A tuple - files_added, ignored_files. files_added is the count
            of added files, and ignored_files is a dict mapping files that were
            ignored to the rule that caused them to be ignored.
        """
        # not in an inner loop; and we want to remove direct use of this,
        # so here as a reminder for now. RBC 20070703
        from bzrlib.inventory import InventoryEntry
        if action is None:
            action = add.AddAction()

        if not file_list:
            # no paths supplied: add the entire tree.
            file_list = [u'.']
        # mutter("smart add of %r")
        inv = self.inventory
        added = []
        ignored = {}
        dirs_to_add = []
        user_dirs = set()

        # validate user file paths and convert all paths to tree
        # relative : it's cheaper to make a tree relative path an abspath
        # than to convert an abspath to tree relative.
        for filepath in file_list:
            rf = _FastPath(self.relpath(filepath))
            # validate user parameters. Our recursive code avoids adding new files
            # that need such validation
            if self.is_control_filename(rf.raw_path):
                raise errors.ForbiddenControlFileError(filename=rf.raw_path)

            abspath = self.abspath(rf.raw_path)
            kind = osutils.file_kind(abspath)
            if kind == 'directory':
                # schedule the dir for scanning
                user_dirs.add(rf)
            else:
                if not InventoryEntry.versionable_kind(kind):
                    raise errors.BadFileKindError(filename=abspath, kind=kind)
            # ensure the named path is added, so that ignore rules in the later directory
            # walk dont skip it.
            # we dont have a parent ie known yet.: use the relatively slower inventory
            # probing method
            versioned = inv.has_filename(rf.raw_path)
            if versioned:
                continue
            added.extend(_add_one_and_parent(self, inv, None, rf, kind,
                                             action))

        if not recurse:
            # no need to walk any directories at all.
            if len(added) > 0 and save:
                self._write_inventory(inv)
            return added, ignored

        # only walk the minimal parents needed: we have user_dirs to override
        # ignores.
        prev_dir = None

        is_inside = osutils.is_inside_or_parent_of_any
        for path in sorted(user_dirs):
            if (prev_dir is None or not is_inside([prev_dir], path.raw_path)):
                dirs_to_add.append((path, None))
            prev_dir = path.raw_path

        # dirs_to_add is initialised to a list of directories, but as we scan
        # directories we append files to it.
        # XXX: We should determine kind of files when we scan them rather than
        # adding to this list. RBC 20070703
        for directory, parent_ie in dirs_to_add:
            # directory is tree-relative
            abspath = self.abspath(directory.raw_path)

            # get the contents of this directory.

            # find the kind of the path being added.
            kind = osutils.file_kind(abspath)

            if not InventoryEntry.versionable_kind(kind):
                warning("skipping %s (can't add file of kind '%s')", abspath,
                        kind)
                continue

            if parent_ie is not None:
                versioned = directory.base_path in parent_ie.children
            else:
                # without the parent ie, use the relatively slower inventory
                # probing method
                versioned = inv.has_filename(directory.raw_path)

            if kind == 'directory':
                try:
                    sub_branch = bzrdir.BzrDir.open(abspath)
                    sub_tree = True
                except errors.NotBranchError:
                    sub_tree = False
                except errors.UnsupportedFormatError:
                    sub_tree = True
            else:
                sub_tree = False

            if directory.raw_path == '':
                # mutter("tree root doesn't need to be added")
                sub_tree = False
            elif versioned:
                pass
                # mutter("%r is already versioned", abspath)
            elif sub_tree:
                # XXX: This is wrong; people *might* reasonably be trying to add
                # subtrees as subtrees.  This should probably only be done in formats
                # which can represent subtrees, and even then perhaps only when
                # the user asked to add subtrees.  At the moment you can add them
                # specially through 'join --reference', which is perhaps
                # reasonable: adding a new reference is a special operation and
                # can have a special behaviour.  mbp 20070306
                mutter("%r is a nested bzr tree", abspath)
            else:
                _add_one(self, inv, parent_ie, directory, kind, action)
                added.append(directory.raw_path)

            if kind == 'directory' and not sub_tree:
                if parent_ie is not None:
                    # must be present:
                    this_ie = parent_ie.children[directory.base_path]
                else:
                    # without the parent ie, use the relatively slower inventory
                    # probing method
                    this_id = inv.path2id(directory.raw_path)
                    if this_id is None:
                        this_ie = None
                    else:
                        this_ie = inv[this_id]

                for subf in sorted(os.listdir(abspath)):
                    # here we could use TreeDirectory rather than
                    # string concatenation.
                    subp = osutils.pathjoin(directory.raw_path, subf)
                    # TODO: is_control_filename is very slow. Make it faster.
                    # TreeDirectory.is_control_filename could also make this
                    # faster - its impossible for a non root dir to have a
                    # control file.
                    if self.is_control_filename(subp):
                        mutter("skip control directory %r", subp)
                    elif subf in this_ie.children:
                        # recurse into this already versioned subdir.
                        dirs_to_add.append((_FastPath(subp, subf), this_ie))
                    else:
                        # user selection overrides ignoes
                        # ignore while selecting files - if we globbed in the
                        # outer loop we would ignore user files.
                        ignore_glob = self.is_ignored(subp)
                        if ignore_glob is not None:
                            # mutter("skip ignored sub-file %r", subp)
                            ignored.setdefault(ignore_glob, []).append(subp)
                        else:
                            #mutter("queue to add sub-file %r", subp)
                            dirs_to_add.append((_FastPath(subp,
                                                          subf), this_ie))

        if len(added) > 0:
            if save:
                self._write_inventory(inv)
            else:
                self.read_working_inventory()
        return added, ignored