git错误:挂钩拒绝更新

tech2022-09-06  99

git错误:挂钩拒绝更新

If you’ve been using Git for more than a short length of time, you’ll hopefully have heard of Git hooks. If not, Git hooks, as Andrew Udvare introduced here on SitePoint back in August of last year, are scripts which run, based on certain events in the Git lifecycle, both on the client and on the server.

如果您使用Git的时间不短,那么希望您会听说过Git钩子。 如果不是这样, 正如Andrew Udvare在去年8月在SitePoint上介绍的那样 ,Git钩子是基于Git生命周期中某些事件在客户端和服务器上运行的脚本。

There are hooks for pre- and post-commit, pre- and post-update, pre-push, pre-rebase, and so on. The sample hooks are written in Bash, one of the Linux shell languages. But they can be written in almost any language you’re comfortable or proficient with.

有用于提交前和提交后,更新前和更新后,推送前,重置前等等的钩子。 示例挂钩是用Bash(Linux外壳语言之一)编写的。 但是几乎可以使用任何您熟悉或精通的语言来编写它们。

As Tim Boronczyk pointed out in September 2013, there are a wide range of meaningful purposes which hooks can be put to. These include linting, spell-checking commit messages, checking patches against accepted coding standards, running composer, and so on.

正如Tim Boronczyk在2013年9月指出的那样 ,有很多有意义的目的可以被使用。 其中包括整理,对提交消息进行拼写检查,根据公认的编码标准检查补丁程序,运行作曲家等等。

Now, PHP’s a great language, don’t get me wrong, but it’s not necessarily the best language for shell scripting. Admittedly, it’s gotten a lot better than it once was. But compared to languages such as Bash, Python, and Ruby, it hasn’t been quite as suitable for creating Git hooks; that is, until now.

现在,PHP是一种很棒的语言,请不要误会我,但是它不一定是Shell脚本编写的最佳语言。 不可否认,它已经比以前好了很多。 但是与Bash,Python和Ruby之类的语言相比,它不太适合创建Git钩子。 也就是说,直到现在。

Thanks to Static Review, by Samuel Parkinson, you can now write Git hooks with native PHP, optionally building on the existing core classes. In today’s post, I’m going to give you a tour of what’s on offer, finishing up by writing a custom class to check for any lingering calls to var_dump().

感谢Samuel Parkinson撰写的Static Review ,现在您可以使用本机PHP编写Git钩子,可以选择在现有的核心类上构建。 在今天的帖子中,我将向您介绍所提供的功能,最后通过编写一个自定义类来检查是否有对var_dump()所有持久调用。

安装库 (Installing the Library)

Like most, if not all modern PHP libraries and packages, StaticReview is installable via Composer. To install it in your project, run composer require sjparkinson/static-review in the root of your project. With that, let’s get going.

与大多数(如果不是全部)现代PHP库和软件包一样,StaticReview可通过Composer安装。 要将其安装在项目中,请在项目的根目录中运行composer require sjparkinson/static-review 。 这样,让我们​​开始吧。

一个有效的例子 (A Working Example)

Like any code, the best way to understand it is to step through a real example, such as the one below, taken from the StaticReview project repository.

像任何代码一样,理解它的最好方法是逐步阅读一个真实的示例,例如下面的示例,该示例取自StaticReview项目存储库。

Firstly, like all shell scripts, it defines what will run the script. In this case, it’s PHP. After that, the Composer autoload script is included, so that the script has access to all the required classes, as well as a warning, should the autoload script not be available.

首先,像所有shell脚本一样,它定义将运行脚本的内容。 在这种情况下,它是PHP。 此后,将包括Composer自动加载脚本,以便在自动加载脚本不可用时该脚本可以访问所有必需的类以及警告。

#!/usr/bin/env php <?php $included = include file_exists(__DIR__ . '/../vendor/autoload.php') ? __DIR__ . '/../vendor/autoload.php' : __DIR__ . '/../../../autoload.php'; if (! $included) { echo 'You must set up the project dependencies, run the following commands:' . PHP_EOL . 'curl -sS https://getcomposer.org/installer | php' . PHP_EOL . 'php composer.phar install' . PHP_EOL; exit(1); }

Next, as with most modern PHP scripts, all of the required classes are imported, and three variables are initialized. These are: a Reporter, a CLImate, and a GitVersionControl object. The Reporter object provides information about the hook, whether the hook succeeded or failed. The CLImate object makes outputting colored text and text formats simple. And the GitVersionControl object simplifies interactions with Git.

接下来,与大多数现代PHP脚本一样,所有必需的类都将被导入,并初始化三个变量。 它们是: Reporter , CLImate和GitVersionControl对象。 Reporter对象提供有关挂钩的信息,无论挂钩成功还是失败。 CLImate对象使输出彩色文本和文本格式变得简单。 GitVersionControl对象简化了与Git的交互。

// Reference the required classes and the reviews you want to use. use League\CLImate\CLImate; use StaticReview\Reporter\Reporter; use StaticReview\Review\Composer\ComposerLintReview; use StaticReview\Review\General\LineEndingsReview; use StaticReview\Review\General\NoCommitTagReview; use StaticReview\Review\PHP\PhpLeadingLineReview; use StaticReview\Review\PHP\PhpLintReview; use StaticReview\StaticReview; use StaticReview\VersionControl\GitVersionControl; $reporter = new Reporter(); $climate = new CLImate(); $Git = new GitVersionControl();

Next, it creates a new StaticReview object, and passes in the types of reviews to run in the hook. In the case below, it adds five. These reviews:

接下来,它创建一个新的StaticReview对象,并传入要在挂钩中运行的评论类型。 在以下情况下,它增加了五个。 这些评论:

Checks if the file contains any CRLF line endings

检查文件是否包含任何CRLF行结尾 Checks if the set file starts with the correct character sequence

检查设置文件是否以正确的字符序列开头

Checks if the file contains NOCOMMIT.

检查文件是否包含NOCOMMIT 。

Checks PHP files using the built-in PHP linter, php -l.

使用内置PHP linter php -l检查PHP文件。

Checks if the composer.json file is valid.

检查composer.json文件是否有效。

Then, it tells the review to check any staged files.

然后,它告诉审阅检查所有暂存文件。

$review = new StaticReview($reporter); // Add any reviews to the StaticReview instance, supports a fluent interface. $review->addReview(new LineEndingsReview()) ->addReview(new PhpLeadingLineReview()) ->addReview(new NoCommitTagReview()) ->addReview(new PhpLintReview()) ->addReview(new ComposerLintReview()); // Review the staged files. $review->review($Git->getStagedFiles());

Similar to other forms of validation, if issues are reported by any of the review classes, each issue is printed out to the terminal, in red, preceded by an ✘, and the commit does not complete. However, if there are no problems, then a success message, ✔ Looking good. Have you tested everything?, is printed out, and the commit is allowed to complete.

与其他形式的验证类似,如果任何审核类都报告了问题,则将每个问题以红色打印到终端,并以✘ ,并且提交不会完成。 但是,如果没有问题,则显示一条成功消息, ✔ Looking good. Have you tested everything? ✔ Looking good. Have you tested everything? ,将被打印出来,并允许提交完成。

// Check if any matching issues were found. if ($reporter->hasIssues()) { $climate->out('')->out(''); foreach ($reporter->getIssues() as $issue) { $climate->red($issue); } $climate->out('')->red('✘ Please fix the errors above.'); exit(1); } else { $climate->out('')->green('✔ Looking good.')->white('Have you tested everything?'); exit(0); }

So far, nothing you’d be unfamiliar with, if you’ve worked with Git hooks before. But how, specifically, does a review class operate? Every Review class extends AbstractReview, which implements ReviewInterface. This interface requires two methods to be implemented: canReview(), and review().

到目前为止,如果您以前使用过Git钩子,那么您将不会陌生。 但是,复习班具体如何运作? 每个Review类都扩展了AbstractReview ,该类实现了ReviewInterface 。 此接口需要实现两种方法: canReview()和review() 。

canReview, as the name implies, determines if a review can be run, and review does the actual review. Take ComposerLintReview.php as an example, which you can see below. canReview() checks if the file being reviewed is called composer.json. If so, review() can be called.

canReview , canReview决定是否可以运行review ,然后review执行实际的审阅。 以ComposerLintReview.php为例,您可以在下面看到。 canReview()检查正在检查的文件是否称为composer.json 。 如果是这样,可以调用review() 。

This then creates a command which invokes Composer’s validate functionality on composer.json, and passes that to the getProcess method, implemented in AbstractReview, running the process. If the process is not successful, an error message is created, and set on the Reporter object, by passing it to a call to Reporter’s error() method, as well as the file which was reviewed.

然后,这将创建一个命令,该命令在composer.json上调用Composer的validate功能,并将其传递给在AbstractReview实现的getProcess方法,从而运行该过程。 如果该过程不成功,则会通过将错误消息传递给对Reporter的error()方法以及审阅的文件的调用来创建并在Reporter对象上设置错误消息。

public function canReview(FileInterface $file) { // only if the filename is "composer.json" return ($file->getFileName() === 'composer.json'); } public function review(ReporterInterface $reporter, FileInterface $file) { $cmd = sprintf('composer validate %s', $file->getFullPath()); $process = $this->getProcess($cmd); $process->run(); if (! $process->isSuccessful()) { $message = 'The composer configuration is not valid'; $reporter->error($message, $this, $file); } }

In a nutshell, that’s all that’s required to create a Git hook to validate files on one of the events in the Git lifecycle.

简而言之,这就是创建Git钩子来验证Git生命周期中一个事件上的文件所需要的。

自定义评论 (A Custom Review)

If you browse under vendor/sjparkinson/static-review/src/Review/, you’ll see there are quite a number of pre-packaged Review classes available. They cover Composer, PHP, and general purpose reviews. But what if we want to create one ourselves, one to suit our specific use case?

如果在vendor/sjparkinson/static-review/src/Review/ ,您会看到有很多预包装的Review类可用。 它们涵盖了Composer,PHP和通用评论。 但是,如果我们想自己创造一个适合我们特定用例的东西怎么办?

What if we’re concerned that we might leave var_dump statements in our code? We wouldn’t, right? But hey, never hurts to be sure, as old habits can sometimes die hard. So what would a custom review look like? Let’s work through one and find out.

如果我们担心可能将var_dump语句保留在代码中怎么办? 我们不会吧? 但是,请放心,永远不会有伤害,因为旧习惯有时可能会死去。 那么自定义评论会是什么样子? 让我们完成一个并找出答案。

First, we’ll create a new directory structure to store our PSR-4 compliant code. Use the following command in the project’s root directory.

首先,我们将创建一个新的目录结构来存储我们符合PSR-4的代码。 在项目的根目录中使用以下命令。

mkdir -p src/SitePoint/StaticReview/PHP

Then, in composer.json, add the following to the existing configuration, and run composer dumpautoload:

然后,在composer.json ,将以下内容添加到现有配置中,然后运行composer dumpautoload :

"autoload": { "psr-4": { "SitePoint\\": "src/SitePoint/" } }

This will update Composer’s autoloader to also autoload our new namespace. With that done, create a new class, called VarDumpReview.php in src/SitePoint/StaticReview/PHP. In it, add the following code:

这将更新Composer的自动加载器,也可以自动加载我们的新名称空间。 完成后,在src/SitePoint/StaticReview/PHP创建一个名为VarDumpReview.php的新类。 在其中添加以下代码:

<?php namespace SitePoint\StaticReview\PHP; use StaticReview\File\FileInterface; use StaticReview\Reporter\ReporterInterface; use StaticReview\Review\AbstractReview; class VarDumpReview extends AbstractReview { public function canReview(FileInterface $file) { $extension = $file->getExtension(); return ($extension === 'php' || $extension === 'phtml'); } public function review(ReporterInterface $reporter, FileInterface $file) { $cmd = sprintf('grep --fixed-strings --ignore-case --quiet "var_dump" %s', $file->getFullPath()); $process = $this->getProcess($cmd); $process->run(); if ($process->isSuccessful()) { $message = 'A call to `var_dump()` was found'; $reporter->error($message, $this, $file); } } }

Based off of PhpLintReview.php and ComposerLintReview.php, canReview checks if, based on the extension, the file being checked is a PHP file. If so, review then uses grep to scan the file for any references to var_dump.

基于PhpLintReview.php和ComposerLintReview.php , canReview根据扩展名检查所检查的文件是否为PHP文件。 如果是这样,则review然后使用grep扫描文件以查找对var_dump任何引用。

If any are found, an error is registered, which tells the user that a call to var_dump was found, and the commit fails. If you were to run it, you could expect output as in the screenshot below.

如果找到任何错误,则会注册一个错误,告诉用户已找到对var_dump的调用,并且提交失败。 如果要运行它,则可以预期输出,如下面的屏幕截图所示。

创建挂钩 (Creating the Hook)

There’s just one last step to go, which is to create a Git hook from our hook class. In a new directory Hooks in my project root, I’ve copied the hook code we worked through at the beginning of the article, making one small change.

最后只有一步,就是从我们的钩子类中创建一个Git钩子。 在项目根目录下的新目录Hooks中,我复制了本文开头处理过的钩子代码,做了一个小改动。

I added our new Review file to the list of Reviews, as follows:

我将新的Review文件添加到Reviews列表中,如下所示:

$review->addReview(new LineEndingsReview()) ->addReview(new PhpLeadingLineReview()) ->addReview(new NoCommitTagReview()) ->addReview(new PhpLintReview()) ->addReview(new ComposerLintReview()) ->addReview(new VarDumpReview());

With that done, create a pre-commit hook, by running the following command.

完成此操作后,通过运行以下命令来创建预提交挂钩。

./vendor/bin/static-review.php hook:install hooks/example-pre-commit.php .Git/hooks/pre-commit

And with that, if you look in .git/hooks, you’ll now see a symlink created from pre-commit, to our new hooks file. To test the hook, make a call to var_dump() in any PHP file, stage the file, and attempt to commit it.

这样一来,如果您查看.git/hooks ,现在您将看到一个从预提交创建的符号链接到我们的新钩子文件。 要测试该挂钩,请在任何PHP文件中调用var_dump() , var_dump()该文件,然后尝试提交它。

You shouldn’t even be allowed to create a commit message before the error message shows. If you then update the file to remove the call to var_dump(), you should see a success message, before being able to add a commit message as in the image below.

在显示错误消息之前,甚至不应允许您创建提交消息。 如果随后更新文件以删除对var_dump()的调用,则在添加如下图所示的提交消息之前,应该会看到一条成功消息。

结语 (Wrapping Up)

And that’s all it takes to create simple or powerful Git hooks, using one of the most versatile languages around, PHP. I only came across Static Review thanks to the ever vigilant Bruno Skvorc. But I’m really thankful he suggested checking it out.

这就是使用最通用的语言之一PHP创建简单或功能强大的Git挂钩所需要的全部。 由于一直保持警惕,Bruno Skvorc才让我遇到了Static Review。 但我真的很感谢他建议检查一下。

With it, I can now do one more, ever important development task, using my favorite software development language – PHP. Are you already using Static Review? If so, share your experience in the comments. I’m keen to know how people more experienced than myself are using it.

有了它,我现在可以使用我最喜欢的软件开发语言PHP来完成一项更重要的开发任务。 您已经在使用静态审查了吗? 如果是这样,请在评论中分享您的经验。 我很想知道比我自己更有经验的人们在使用它。

翻译自: https://www.sitepoint.com/writing-php-git-hooks-with-static-review/

git错误:挂钩拒绝更新

相关资源:jdk-8u281-windows-x64.exe
最新回复(0)