git - 将子 git 存储库视为单元测试的普通存储库?

git - treat sub git repository as normal repository for unittests?

我正在编写一个将一个系统与 git 集成的模块。我正在编写测试并希望在测试目录中有测试存储库,这样我就可以 运行 对其进行单元测试。

模块和项目结构如下所示:

myproject/
  mymodule/
    some_dir/
    tests/
      __init__.py
      testrepo/
        /.git
      test_some.py
  /.git

现在,当我在开发时,它正在运行。我可以 运行 使用 testrepo 进行测试。虽然我注意到,当我提交时,git 开始自动将 testrepo 视为子项目。所以基本上它不会跟踪发生的所有更改。如果实际代码更改,则它会识别为 subproject/submodule 更改。但是,如果我说添加新分支,则无法识别这些更改(除非我检查它等)。

所以我想知道使用 testrepo 进行单元测试的最佳方法是什么。我希望它在源代码管理中,所以整个结构在单元测试中是完整的。

如果从 中理解正确,那么将子 git 存储库视为普通存储库是不可能的(仅通过来回修改 git 名称)。

那么我如何保留子存储库中的所有更改,所以我只需要拉取 myproject 并获得 testrepo 以及所有分支等?

或者我只能把它当作真正的子模块使用,克隆后需要初始化它myproject?

更新

如果我使用 testrepo 作为真正的子模块,那么我的测试将停止工作,因为它不再被识别为正常的 git 回购。

所以在尝试了子模块和真正的 git 回购之后,我开始使用简单的回购设置并在测试之间拆除。

我敢打赌这不是最佳解决方案,但目前我还没有看到更好的解决方案(更快的方法可能是以某种方式将 git 隐藏为普通目录,并在 运行 测试时更改它被识别为 git 回购并在测试后再次隐藏它:虽然有点 hacky)。

如果谁有更好的想法,请写下来作为答案。

我的实施示例(使用 setUpClass 构建并使用 tearDownClass 删除):

# -*- coding: utf-8 -*-
import os
import sh
import shutil


class cd:
    """Context manager for changing the current working directory"""
    def __init__(self, newPath):
        self.newPath = os.path.expanduser(newPath)

    def __enter__(self):
        self.savedPath = os.getcwd()
        os.chdir(self.newPath)

    def __exit__(self, etype, value, traceback):
        os.chdir(self.savedPath)


def build_test_repo(dir_path):
    """Build testrepo for unittests."""
    def git_add_file(g, txt):
        """create, add and commit dummy file."""
        with open('%s.txt' % txt, 'w') as f:
            f.write('%s content' % txt)
        # add and commit
        g.add('%s.txt' % txt)
        g.commit('-m', '[ADD] %s.txt' % txt)

    path = "%s/%s" % (dir_path, 'testrepo')
    os.makedirs(path)
    # change dir to initialize repo. We use context manager, so after
    # setting up repo, we would get back to previous working directory.
    with cd(path):
        # git from shell
        g = sh.git
        g.init()
        git_add_file(g, 't0')
        # create f1 branch
        g.checkout('-b', 'f1')
        # add and commit for f1
        git_add_file(g, 't1')
        # create f2 branch from master
        g.checkout('master')
        g.checkout('-b', 'f2')
        git_add_file(g, 't2')
        # create copy of master without any difference.
        g.checkout('master')
        g.checkout('-b', 'master_copy')