无法使用 gitpython 创建/添加新分支到 git 存储库

Can't create / add a new branch to a git repo with gitpython

我一直在研究一些 Python 脚本,这些脚本利用 gitpython 库根据我们的 redmine 实例中的问题自动创建本地分支。首先,我正在尝试创建一些本地存储库来模拟系统,因为我希望它能正常工作,但我遇到了第一个障碍。

这是我的测试用例的设置,它应该创建一个 'remote' 存储库,然后克隆它以创建一个本地存储库,最后创建一个本地功能分支:

def setUp(self):
    # Create a remote git repo to simulate the one gitlab maintains
    baseDir = os.path.join('C:\', 'test-repos')
    if os.path.exists(baseDir):
        shutil.rmtree(baseDir)

    gitlabRepoLocation = os.path.join(baseDir, 'gitlab')
    gitlabRepo = git.Repo.init(gitlabRepoLocation)

    # Clone to a local repo
    localRepoLocation = os.path.join(baseDir, 'local')
    localRepo = git.Repo.clone_from("file://"+gitlabRepoLocation, localRepoLocation)
    localRepo.create_head('some-feature') # <-- This fails

但是当我 运行 它时,我得到:

Traceback (most recent call last):
  File "C:\Projects\PyTools\Gitted\test_Helpers.py", line 70, in setUp
    gitlabRepo.create_head('some-feature')
  File "C:\Python34\lib\site-packages\git\repo\base.py", line 330, in create_head
    return Head.create(self, path, commit, force, logmsg)
  File "C:\Python34\lib\site-packages\git\refs\symbolic.py", line 527, in create
    return cls._create(repo, path, cls._resolve_ref_on_create, reference, force, logmsg)
  File "C:\Python34\lib\site-packages\git\refs\symbolic.py", line 479, in _create
    target = repo.rev_parse(str(reference))
  File "C:\Python34\lib\site-packages\git\repo\fun.py", line 311, in rev_parse
    obj = name_to_object(repo, rev)
  File "C:\Python34\lib\site-packages\git\repo\fun.py", line 124, in name_to_object
    raise BadName(name)
gitdb.exc.BadName: Ref 'HEAD' did not resolve to an object

事实证明@torek 是正确的。添加并提交一个空文件解决了这个问题:

    filename = 'readme.txt'
    open(filename, 'wb').close()
    gitlabRepo.index.add([filename])
    gitlabRepo.index.commit("Adding "+filename+ "to repo")

我同意 torek 的观点,这似乎是 gitpython 中的一个错误。 Jon 的解决方案会起作用,但它会在 git 存储库中留下不需要的垃圾。

我个人最终通过使用 git 命令行工具创建分支解决了这个问题。

command = ['git','branch','-f','workingbranch',parenttagname]                 
print(command, flush=True)
if (subprocess.call(command) != 0): exit(1)
branch = repo.heads.workingbranch

看起来这是设计使然,因为当您克隆一个空的 repo 时没有提交,因此没有 HEAD 引用,所以为了创建对提交的引用。你需要先提交一些东西。使用 git 命令行时,您会 运行 遇到类似的问题。

mkdir empty_repo
cd empty_repo
git --init
git checkout master

以上代码行会出现错误error: pathspec 'master' did not match any file(s) known to git.这是因为没有提交引用可用于创建新的 HEAD。

但是添加并提交一组文件后,您将生成第一个 md5 引用和第一个 HEAD 对象。

所以这个问题可以通过改变你处理 repo 的顺序来解决。

  1. 创建空存储库或将其克隆到本地位置。
  2. 断言克隆的回购确实是新的和空的。 (如果没有,您可以根据需要生成尽可能多的新 HEAD 引用)
  3. 由于它是空的,您可以添加和提交您想要的任何文件。
  4. 从第一次提交创建一个新的 HEAD。