Git子模块在TFS构建中失败

9
当我试图使用TFS与Git进行构建时,存在一个限制,即TFS的git提供程序尚不支持子模块。这有点烦人,但是我可以告诉TFS在编译之前运行批处理文件。我已经使用它来调用手动git脚本来更新我的“超级”项目中的所有子模块。

此批处理文件运行的命令非常简单:
git submodule update --init --recursive

在将子模块源迁移到TFS之前,这很好地运行,但是现在TFS构建失败了,因为上述git模块脚本不再起作用。

因此,在构建之前,TFS会将当前的Git源从Git拉到构建服务器上的文件夹中,我可以访问该文件夹。

如果我打开Git Bash并在该文件夹中运行以下命令:
git submodule init
git submodule update
我会收到以下错误,而我无法弄清楚它是什么。我尝试搜索此特定错误,通常指向在“超级项目” repo 推送之后推送子模块提交的问题。但是我可以验证所有子模块的提交和推送都是在完成“超级项目”提交和推送之前执行的。以下是TFS git命令的输出:
james@TFS /C/Builds/1/Technique Webs/MIS Console 5.2 Development/src (5.2development)
$ git submodule init

james@TFS /C/Builds/1/Technique Webs/MIS Console 5.2 Development/src (5.2development)
$ git submodule update
Username for 'http://tfs:8080': james
Password for 'http://james@TFS:8080': <password>
From http://TFS:8080/TFS/Technique/_git/Technique%20Library
 * branch            HEAD       -> FETCH_HEAD
fatal: reference is not a tree: 33106ea146d470159e327c1b2d623d14f522cdd4
Unable to checkout '33106ea146d470159e327c1b2d623d14f522cdd4' in submodule path 'calc-engine'

james@TFS /C/Builds/1/Technique Webs/MIS Console 5.2 Development/src (5.2development)
$

这看起来像是有人忘记推送子模块的更改。 - springy76
尽管看起来是这样,但不幸的是并非如此 - 请查看我的评论“...我可以验证所有子模块提交和推送都在‘超级项目’提交和推送之前完成”。还有其他想法吗? - abbottdev
你解决过这个问题吗?我也遇到了同样的错误。 - Quantumplation
2个回答

4
经过反复尝试,我解决了类似的问题:原来这是TFS预构建PowerShell脚本在没有用户配置文件的情况下运行的问题,因此GIT无法看到构建用户的凭据缓存设置(例如在C:\Users\theuser\.gitconfig中设置)。批处理脚本也会遇到同样的问题。
特别之处在于git submodule调用会完全挂起,并且会将GIT仓库置于非常奇怪的状态(如上面所述的not a tree错误)。
挂起是由于GIT提示要使用用户名和密码,但这是一个非交互式会话,因此一切都停滞不前。
通过使用wincred作为凭据缓存,我能够解决这个问题:
1. 以构建用户身份登录构建机器。 2. 通过命令行访问GIT服务器并输入所需的凭据。 3. 打开Windows凭据管理器并检查通用凭据部分中是否可见缓存凭据。 4. 在提升的命令提示符中,强制GIT默认使用wincred,即使它没有用户配置文件:git config --system credential.helper wincred 5. 重新从TFS运行构建:成功。

1
使用git-credential-winstore将 Build-runner 凭据放入构建服务器的缓存中。 - 2ooom
最近的Windows版git构建中,你甚至不需要安装git-credential-winstore,可以直接使用内置的wincred模块。 - Paul Annetts

0

原因是'Git Bash'不知道构建帐户的凭据,它应该每次交互式地提示它们。实际上,如果构建帐户可以访问所有子模块远程仓库,它只需要在凭据提示中提供空用户名和密码即可。这在Windows中并不容易,因为凭据管理器不接受空用户名。

解决方法之一是将子模块的URL更改为以下内容。 '@'符号与提供空用户名和密码相同。

[submodule "..."]
    path = ...
    url = http://@tfs:8080/...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接