def _compare(self, dir1, dir2):
        """ Compare contents of two directories """

        left = set()
        right = set()

        self._numdirs += 1

        excl_patterns = set(self._exclude).union(self._ignore)

        for cwd, dirs, files in os.walk(dir1):
            self._numdirs += len(dirs)
            for f in dirs + files:
                path = os.path.relpath(os.path.join(cwd, f), dir1)
                re_path = path.replace('\\', '/')
                if self._only:
                    for pattern in self._only:
                        if re.match(pattern, re_path):
                            # go to exclude and ignore filtering
                            break
                    else:
                        # next item, this one does not match any pattern
                        # in the _only list
                        continue

                add_path = False
                for pattern in self._include:
                    if re.match(pattern, re_path):
                        add_path = True
                        break
                else:
                    # path was not in includes
                    # test if it is in excludes
                    for pattern in excl_patterns:
                        if re.match(pattern, re_path):
                            # path is in excludes, do not add it
                            break
                    else:
                        # path was not in excludes
                        # it should be added
                        add_path = True

                if add_path:
                    left.add(path)
                    anc_dirs = re_path[:-1].split('/')
                    for i in range(1, len(anc_dirs)):
                        left.add('/'.join(anc_dirs[:i]))

        for cwd, dirs, files in os.walk(dir2):
            for f in dirs + files:
                path = os.path.relpath(os.path.join(cwd, f), dir2)
                re_path = path.replace('\\', '/')
                for pattern in self._ignore:
                    if re.match(pattern, re_path):
                        if f in dirs:
                            dirs.remove(f)
                        break
                else:
                    right.add(path)
                    # no need to add the parent dirs here,
                    # as there is no _only pattern detection
                    if f in dirs and path not in left:
                        self._numdirs += 1

        common = left.intersection(right)
        left.difference_update(common)
        right.difference_update(common)

        return DCMP(left, right, common)
Compare contents of two directories