12

好的,这是场景:一个开发团队希望确保所有新代码都符合定义的编码标准,并且在接受提交之前所有单元测试都通过。这是诀窍,所有测试都需要在专用测试机器上运行,我们无权修改 git 服务器,因此必须在每台开发机器上使用本地提交挂钩来完成。

虽然规格非常严格(例如,我们不会切换到 windows 或 subversion),但这是一个现实世界的问题,因此如果您有一个几乎适合的解决方案,那么就有一定的灵活性。

  • 我们正在使用 Git 和 *nix。
  • 更新后的代码需要发送到另一台服务器来运行测试套件。
  • 需要提供修改文件的列表以确保它们符合编码标准。
  • 它是一个相当大的代码库,因此我们应该发送最少的必要信息以确保代码库的相同副本。
  • 如果测试失败,则需要显示一条带有错误的消息,并且应该阻止提交。
  • --no-verify假设我们信任我们的开发团队,并且允许使用选项绕过测试是可以的。

问题:让测试服务器与本地环境同步以运行测试的最佳方法是什么?某种哈希到哈希与新提交的 git 补丁匹配?完全跳过 Git,只做一个 rsync?完全是别的东西吗?

2013 年8 月 7 日更新:我什至提到了远程仓库,这让我自责。关键不是阻止代码被推送到共享/远程仓库,而是防止本地提交甚至发生。在这种情况下,这是否被认为是最佳实践并不是真正的重点,因为这是特定于一个小型开发团队的,他们都想要这个确切的功能。问题是关于实现目标的最佳方式。

4

6 回答 6

12

简短的回答:


长答案:

由于一些奇怪的本地挂钩而无法进行提交对我来说似乎很奇怪:您必须将提交(即保存您的更改)与发布此提交分开。

虽然在pre-receive您提到的执行您的规则的 git 服务器上安装一个钩子是完全合理的,但对于您的开发人员的存储库来说,这将是戏剧性的:每次他们想要保存他们的工作时,尝试新的东西或其他什么,他们首先会拥有在提交之前完善他们的代码。

这会适得其反:人们会感觉回到了糟糕的过去,那时他们必须向 repo 提交任何东西每个人都可以看到他们的错误、糟糕的编码风格等等。您将失去 DVCS 为您提供的自由:廉价的分支、本地历史,同时维护生产代码的中央存储库。

在进行本地提交时不要强制执行任何操作。

于 2013-08-06T14:44:58.610 回答
12

本地提交挂钩绝对不是您想要的。

您要求“我们无权修改 git 服务器,因此必须使用每台开发机器上的本地提交挂钩来完成”是完全错误的。您始终可以设置另一个存储库,它是您可以完全控制的“测试远程”(然后它将与您无法控制的 git 服务器同步)。

设置此远程测试后,您可以添加挂钩以在任何推送上运行测试。键入git push test-remote my-branch以获得测试结果的工作非常少。

与 Git 的持续集成

还可以查看 Jenkins、gitlab 等...


2013 年 8 月 7 日之后更新:

所以你真的想在远程服务器上做一些“测试”来防止提交。如果要根据提交本身的内容进行阻止,请使用pre-commit钩子。有关如何获取已更改文件的列表,请参阅此问题。 一旦你有了这些更改的文件,你可以使用scp或将它们发送到远程服务器,rsync并使用ssh.

如果您需要检查提交消息,请使用commit-msg钩子。

这是一个很好的钩子教程:http: //git-scm.com/book/en/Customizing-Git-Git-Hooks

它还提到了为什么它可能是一个坏主意的一些原因。

它们通常用于强制执行某些策略,但重要的是要注意这些脚本不会在克隆期间传输。您可以在服务器端强制执行策略以拒绝不符合某些策略的提交推送,但在客户端使用这些脚本完全取决于开发人员。因此,这些是帮助开发人员的脚本,它们必须由它们设置和维护,尽管它们可以随时被它们覆盖或修改。

于 2013-08-03T05:17:08.337 回答
3

我认为我见过的最好的方法是 git+gerrit+jenkins。gerrit 引入了变更集的概念。jenkins gerrit 插件可以构建每个已发布的变更集(运行您想要的任何类型的测试)并将它们标记为“已验证”,然后可以将已验证的变更集合并到主分支中。如果变更集构建失败,提交者会收到一封通知电子邮件,然后他可以修改提交并更新变更集。

于 2013-08-08T20:30:16.963 回答
2

添加一个自定义 git 命令:

  1. 临时做提交
  2. 将其推送到远程服务器
  3. 运行测试(使用 CI 服务器、post-receive钩子或ssh
  4. 如果测试失败,则恢复提交

创建一个名为的可执行文件git-test-n-commit并将其放在您的路径中:

#!/bin/bash
echo "Committing results..."
git commit "$@"
echo "Pushing to remote testing server..."
git push remote-server-git-url remote-branch -f
echo "Running tests"
ssh remote-server 'cd my_repo; run-my-tests' || 
   (echo "Tests failed, undoing commit" && git reset HEAD^)

然后git commit ARGS,开发人员可以调用而不是调用git test-n-commit ARGS。如果测试通过,代码将保持提交。如果测试失败,就好像它从未提交过一样。

于 2013-09-13T06:31:20.123 回答
1

按照其他人的建议设置中间服务器后,设置您的pre-receive连接以在传入提交上运行脚本并将其规范化为您的编码标准。编码标准通常由计算机可执行的规则定义。当一个简单的 bash 脚本或任何可以为他们做的事情时,不要让你的开发人员到处调整空格。如果您有一个脚本来执行此操作,为什么要让开发人员手动运行它,因为它可以在每个push中间存储库上自动运行。

于 2013-08-06T16:00:22.843 回答
0

编写一个 Makefile:

  1. 将当前文件复制到测试服务器。

  2. 查找单元测试的输出。

2.1。如果没有异常,运行 'git commit'

2.2 如果有异常,回显错误。

使用 Makefiles 进行编译和提交是天赐之物。我可以在提交之前自动执行复杂的格式化和文件清理。

编辑:

当然,Makefile 不是您唯一可以做的事情。Ant/Bash/其他脚本语言可以为你做到这一点。

于 2013-08-08T20:37:42.293 回答