Skip to content

Commit 7e06ff3

Browse files
committed
Клиентские хуки
1 parent 484d931 commit 7e06ff3

File tree

1 file changed

+43
-41
lines changed

1 file changed

+43
-41
lines changed

book/08-customizing-git/sections/policy.asc

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -279,19 +279,19 @@ error: failed to push some refs to 'git@gitserver:project.git'
279279

280280
С момента как скрипт `update` существует и исполняем, ваш репозиторий не будет содержать коммиты с сообщением, неудовлетворяющем установленному шаблону, а доступ ваших пользователей будет ограничен.
281281

282-
==== Client-Side Hooks
282+
==== Клиентские хуки
283283

284-
The downside to this approach is the whining that will inevitably result when your users' commit pushes are rejected.
285-
Having their carefully crafted work rejected at the last minute can be extremely frustrating and confusing; and furthermore, they will have to edit their history to correct it, which isn't always for the faint of heart.
284+
Недостатком этого подхода является неизбежное нытьё ваших пользователей, к которому приводит отклонение отправки коммитов.
285+
Получение отказа в последний момент при отправке тщательно продуманной работы может сильно расстроить и вызвать непонимание; кроме этого, придётся ещё актуализировать историю, что не всегда для слабонервных.
286286

287-
The answer to this dilemma is to provide some client-side hooks that users can run to notify them when they're doing something that the server is likely to reject.
288-
That way, they can correct any problems before committing and before those issues become more difficult to fix.
289-
Because hooks aren't transferred with a clone of a project, you must distribute these scripts some other way and then have your users copy them to their `.git/hooks` directory and make them executable.
290-
You can distribute these hooks within the project or in a separate project, but Git won't set them up automatically.
287+
Решением в данной ситуации является предоставление клиентских хуков, которые пользователи могут использовать для получения уведомлений, когда они делают то, что сервер скорее всего отклонит.
288+
Таким образом они могут исправить любые проблемы до создания коммита и до того, как исправление проблемы станет гораздо сложнее.
289+
Так как хуки не копируются при клонировании репозитория, вам следует распространять их каким-то другим способом, а ваши пользователи должны будут их скопировать в директорию `.git/hooks` и сделать исполняемыми.
290+
Вы можете хранить эти хуки внутри проекта или в отдельном проекте -- в любом случае Git не установит их автоматически.
291291

292-
To begin, you should check your commit message just before each commit is recorded, so you know the server won't reject your changes due to badly formatted commit messages.
293-
To do this, you can add the `commit-msg` hook.
294-
If you have it read the message from the file passed as the first argument and compare that to the pattern, you can force Git to abort the commit if there is no match:
292+
Для начала, необходимо проверять сообщение коммита непосредственно перед его созданием, так вы будете уверены, что сервер не отклонит ваши изменения из-за плохо оформленных сообщений.
293+
Это реализуется созданием `commit-msg` хука.
294+
Если читать файл, переданный в качестве первого аргумента, и сравнивать его содержимое с заданным шаблоном, то можно заставить Git отменять создание коммита в случае отсутствия совпадения:
295295

296296
[source,ruby]
297297
----
@@ -307,32 +307,32 @@ if !$regex.match(message)
307307
end
308308
----
309309

310-
If that script is in place (in `.git/hooks/commit-msg`) and executable, and you commit with a message that isn't properly formatted, you see this:
310+
Если скрипт на месте (`.git/hooks/commit-msg`) и исполняем, а вы создаёте коммит с плохо оформленным сообщением, то увидите следующее:
311311

312312
[source,console]
313313
----
314-
$ git commit -am 'test'
314+
$ git commit -am 'Test'
315315
[POLICY] Your message is not formatted correctly
316316
----
317317

318-
No commit was completed in that instance.
319-
However, if your message contains the proper pattern, Git allows you to commit:
318+
В этом случае коммит создан не будет.
319+
Однако, если ваше сообщение соответствует заданному шаблону, то коммит будет создан:
320320

321321
[source,console]
322322
----
323-
$ git commit -am 'test [ref: 132]'
324-
[master e05c914] test [ref: 132]
323+
$ git commit -am 'Test [ref: 132]'
324+
[master e05c914] Test [ref: 132]
325325
1 file changed, 1 insertions(+), 0 deletions(-)
326326
----
327327

328-
Next, you want to make sure you aren't modifying files that are outside your ACL scope.
329-
If your project's `.git` directory contains a copy of the ACL file you used previously, then the following `pre-commit` script will enforce those constraints for you:
328+
Далее, следует убедиться, что внесенные изменения соответствуют вашим правам доступа.
329+
Если в директории `.git` содержится файл списка контроля доступа, который использовался ранее, то следующий `pre-commit` скрипт поможет вам реализовать такую проверку:
330330

331331
[source,ruby]
332332
----
333333
#!/usr/bin/env ruby
334334
335-
$user = ENV['USER']
335+
$user = ENV['USER']
336336
337337
# [ insert acl_access_data method from above ]
338338
@@ -358,50 +358,50 @@ end
358358
check_directory_perms
359359
----
360360

361-
This is roughly the same script as the server-side part, but with two important differences.
362-
First, the ACL file is in a different place, because this script runs from your working directory, not from your `.git` directory.
363-
You have to change the path to the ACL file from this
361+
Этот скрипт практически такой же как и серверный, за исключением двух важных отличий.
362+
Во первых, файл списка контроля доступа находится в другом месте, так как скрипт запускается из рабочей директории, а не из директории `.git`.
363+
Поэтому необходимо изменить путь к файлу с:
364364

365365
[source,ruby]
366366
----
367367
access = get_acl_access_data('acl')
368368
----
369369

370-
to this:
370+
на следующий:
371371

372372
[source,ruby]
373373
----
374374
access = get_acl_access_data('.git/acl')
375375
----
376376

377-
The other important difference is the way you get a listing of the files that have been changed.
378-
Because the server-side method looks at the log of commits, and, at this point, the commit hasn't been recorded yet, you must get your file listing from the staging area instead.
379-
Instead of
377+
Второе отличие состоит в способе получения списка изменённых файлов.
378+
Если на сервере метод извлекает его из истории коммитов, то в данный момент на стороне клиента коммит ещё не создан, поэтому извлекать этот список необходимо из индекса.
379+
Вместо
380380

381381
[source,ruby]
382382
----
383383
files_modified = `git log -1 --name-only --pretty=format:'' #{ref}`
384384
----
385385

386-
you have to use
386+
следует использовать:
387387

388388
[source,ruby]
389389
----
390390
files_modified = `git diff-index --cached --name-only HEAD`
391391
----
392392

393-
But those are the only two differences -- otherwise, the script works the same way.
394-
One caveat is that it expects you to be running locally as the same user you push as to the remote machine.
395-
If that is different, you must set the `$user` variable manually.
393+
Вот и все отличия -- в остальном скрипт работает одинаково.
394+
Так же предполагается, что локально скрипт будет запускаться от имени того же пользователя, что и на удалённом сервере.
395+
Если имя вашего локального пользователя не совпадает с именем пользователя на сервере, то следует задать значение переменной `$user` вручную.
396396

397-
One other thing we can do here is make sure the user doesn't push non-fast-forwarded references.
398-
To get a reference that isn't a fast-forward, you either have to rebase past a commit you've already pushed up or try pushing a different local branch up to the same remote branch.
397+
Ещё одна вещь, которую можно здесь сделать, это убедиться, что пользователь не отправляет ветки, которые не могут быть обновлены простым смещением вперёд.
398+
Чтобы создать такую ситуацию, вам нужно либо перебазировать уже отправленный коммит, либо попытаться отправить другую локальную ветку в ту же удалённую.
399399

400-
Presumably, the server is already configured with `receive.denyDeletes` and `receive.denyNonFastForwards` to enforce this policy, so the only accidental thing you can try to catch is rebasing commits that have already been pushed.
400+
Предположим, что на сервере уже включены опции `receive.denyDeletes` и `receive.denyNonFastForwards` для обеспечения политики, поэтому воспроизвести ситуацию можно только перебазировав отправленные коммиты.
401401

402-
Here is an example pre-rebase script that checks for that.
403-
It gets a list of all the commits you're about to rewrite and checks whether they exist in any of your remote references.
404-
If it sees one that is reachable from one of your remote references, it aborts the rebase.
402+
Ниже представлен скрипт `pre-rebase`, который выполняет такую проверку.
403+
Он получает список коммитов, которые вы собираетесь перезаписать, и проверяет их наличие в удаленных ветках.
404+
Если хотя бы один из этих коммитов будет доступен из какой-либо удалённой ветки, то процесс перебазирования прерывается.
405405

406406
[source,ruby]
407407
----
@@ -427,15 +427,17 @@ target_shas.each do |sha|
427427
end
428428
end
429429
----
430-
This script uses a syntax that wasn't covered in the Revision Selection section of Chapter 6. You get a list of commits that have already been pushed up by running this:
430+
431+
Скрипт использует синтаксис, который не был рассмотрен в разделе <<ch07-git-tools#r_revision_selection>>.
432+
Получить список коммитов, которые уже были отправлены, можно с помощью команды:
431433

432434
[source,ruby]
433435
----
434436
`git rev-list ^#{sha}^@ refs/remotes/#{remote_ref}`
435437
----
436438

437-
The `SHA^@` syntax resolves to all the parents of that commit.
438-
You're looking for any commit that is reachable from the last commit on the remote and that isn't reachable from any parent of any of the SHA-1s you're trying to push up -- meaning it's a fast-forward.
439+
Синтаксис `SHA^@` позволяет получить список всех родителей коммита.
440+
Вы ищите любой коммит, который доступен относительно последнего коммита на удалённом сервере, но недоступен относительно любого родителя отправляемых SHA-1, что определяет простое смещение вперёд.
439441

440-
The main drawback to this approach is that it can be very slow and is often unnecessary -- if you don't try to force the push with `-f`, the server will warn you and not accept the push.
441-
However, it's an interesting exercise and can in theory help you avoid a rebase that you might later have to go back and fix.
442+
Основной недостаток этого подхода в том, что он может быть очень медленным и не всегда необходим -- если вы не форсируете отправку опцией `-f`, то сервер отклонит её с соответствующим предупреждением.
443+
Тем не менее, это интересная задача, которая теоретически может вам помочь избежать перебазирования, которое в будущем, возможно, придётся исправлять.

0 commit comments

Comments
 (0)