我正在编写一个模块,将一个系统与git
集成在一起。我正在编写测试并希望在测试目录中包含测试存储库,因此我可以在其上运行unittests。
模块和项目结构如下所示:
myproject/
mymodule/
some_dir/
tests/
__init__.py
testrepo/
/.git
test_some.py
/.git
现在,在我开发的过程中,它正在发挥作用。我可以使用testrepo
运行测试。虽然我注意到,当我提交时,git
开始自动将testrepo
视为子项目。所以基本上它不会跟踪发生的所有变化。如果实际代码发生更改,则会将其识别为子项目/子模块更改。但是,如果我说添加新分支,则无法识别这些更改(除非我会检查它等)。
所以我想知道将testrepo
用于单元测试的最佳方法是什么。我希望它在源代码控制中,因此整个结构将完整无缺。
如果从how can I add git submodule into git repo as normal directory?正确理解,那么将子git存储库视为普通存储库是不可能的(只能通过某种方式来回攻击git名称)。
那么我如何才能保留子存储库中的所有更改,所以我需要提取myproject
并获取testrepo
所有分支等?
或者我只能将它用作真正的子模块,并且需要在克隆myproject
之后对其进行初始化?
更新
如果我使用testrepo
作为真正的子模块,那么我的测试就会停止工作,因为它不再被认为是正常的git
回购。
答案 0 :(得分:0)
所以在repo中尝试子模块和真正的git repo之后,我选择使用简单的repo设置并在测试之间拆除。
我敢打赌,这不是一个非常理想的解决方案,但是现在我看不到更好的解决方案(可能会更快地将git隐藏为普通目录,并且在运行测试时,将其更改为被识别为git repo并且在测试之后,再次隐藏它:虽然有点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')