@classmethod
    def add(cls, repo, name, path, url=None, branch=None, no_checkout=False):
        """Add a new submodule to the given repository. This will alter the index
        as well as the .gitmodules file, but will not create a new commit.
        If the submodule already exists, no matter if the configuration differs
        from the one provided, the existing submodule will be returned.

        :param repo: Repository instance which should receive the submodule
        :param name: The name/identifier for the submodule
        :param path: repository-relative or absolute path at which the submodule
            should be located
            It will be created as required during the repository initialization.
        :param url: git-clone compatible URL, see git-clone reference for more information
            If None, the repository is assumed to exist, and the url of the first
            remote is taken instead. This is useful if you want to make an existing
            repository a submodule of anotherone.
        :param branch: name of branch at which the submodule should (later) be checked out.
            The given branch must exist in the remote repository, and will be checked
            out locally as a tracking branch.
            It will only be written into the configuration if it not None, which is
            when the checked out branch will be the one the remote HEAD pointed to.
            The result you get in these situation is somewhat fuzzy, and it is recommended
            to specify at least 'master' here.
            Examples are 'master' or 'feature/new'
        :param no_checkout: if True, and if the repository has to be cloned manually,
            no checkout will be performed
        :return: The newly created submodule instance
        :note: works atomically, such that no change will be done if the repository
            update fails for instance"""
        if repo.bare:
            raise InvalidGitRepositoryError("Cannot add submodules to bare repositories")
        # END handle bare repos

        path = cls._to_relative_path(repo, path)

        # assure we never put backslashes into the url, as some operating systems
        # like it ...
        if url is not None:
            url = to_native_path_linux(url)
        # END assure url correctness

        # INSTANTIATE INTERMEDIATE SM
        sm = cls(repo, cls.NULL_BIN_SHA, cls.k_default_mode, path, name, url='invalid-temporary')
        if sm.exists():
            # reretrieve submodule from tree
            try:
                return repo.head.commit.tree[path]
            except __HOLE__:
                # could only be in index
                index = repo.index
                entry = index.entries[index.entry_key(path, 0)]
                sm.binsha = entry.binsha
                return sm
            # END handle exceptions
        # END handle existing

        # fake-repo - we only need the functionality on the branch instance
        br = git.Head(repo, git.Head.to_full_path(str(branch) or cls.k_head_default))
        has_module = sm.module_exists()
        branch_is_default = branch is None
        if has_module and url is not None:
            if url not in [r.url for r in sm.module().remotes]:
                raise ValueError(
                    "Specified URL '%s' does not match any remote url of the repository at '%s'" % (url, sm.abspath))
            # END check url
        # END verify urls match

        mrepo = None
        if url is None:
            if not has_module:
                raise ValueError("A URL was not given and existing repository did not exsit at %s" % path)
            # END check url
            mrepo = sm.module()
            urls = [r.url for r in mrepo.remotes]
            if not urls:
                raise ValueError("Didn't find any remote url in repository at %s" % sm.abspath)
            # END verify we have url
            url = urls[0]
        else:
            # clone new repo
            kwargs = {'n': no_checkout}
            if not branch_is_default:
                kwargs['b'] = br.name
            # END setup checkout-branch

            # _clone_repo(cls, repo, url, path, name, **kwargs):
            mrepo = cls._clone_repo(repo, url, path, name, **kwargs)
        # END verify url

        # It's important to add the URL to the parent config, to let `git submodule` know.
        # otherwise there is a '-' character in front of the submodule listing
        #  a38efa84daef914e4de58d1905a500d8d14aaf45 mymodule (v0.9.0-1-ga38efa8)
        # -a38efa84daef914e4de58d1905a500d8d14aaf45 submodules/intermediate/one
        writer = sm.repo.config_writer()
        writer.set_value(sm_section(name), 'url', url)
        writer.release()

        # update configuration and index
        index = sm.repo.index
        writer = sm.config_writer(index=index, write=False)
        writer.set_value('url', url)
        writer.set_value('path', path)

        sm._url = url
        if not branch_is_default:
            # store full path
            writer.set_value(cls.k_head_option, br.path)
            sm._branch_path = br.path
        # END handle path
        writer.release()
        del(writer)

        # we deliberatly assume that our head matches our index !
        sm.binsha = mrepo.head.commit.binsha
        index.add([sm], write=True)

        return sm
dataset/ETHPy150Open gitpython-developers/GitPython/git/objects/submodule/base.py/Submodule.add