반응형

Git hook

Hook은 특정 이벤트, 함수가 호출되기 전/후에 실행되는 스크립트/명령을 말합니다.
Git은 다른 버전 관리 시스템처럼 어떤 이벤트가 발생할 때 자동으로 특정 스크립트를 실행하도록 할 수 있습니다.
이 훅은 클라이언트 훅(commit or merge 시 발생)과 서버 훅(push 시 발생) 두가지가 있습니다.

I. 자주 사용되는 hooks

1. 클라이언트 훅

pre-commit

커밋할 때 가장 먼저 호출되는 훅으로 커밋 메시지를 작성하기 전에 호출됩니다. 즉 git commit "something" 시 즉시 발생하는 hook 입니다.
보통 commit 하기 전에 파일의 코드 스타일 체크, 파일 검사 등을 위해 사용하는 경우가 많습니다.
git commit --no-verify 를 이용해 commit하면 이 hook을 무시할 수 있습니다.

prepare-commit-msg

commit msg 가 자동으로 생성되는 commit 의 경우 사용하면 좋은 hook으로 별도의 commit 템플릿이 있는 경우나 merge/squash commit 을 날릴때 유용하게 사용됩니다.

2. 서버 훅

pre-receive/update

push가 발생하면 실행되는 hook으로 Fast-forward Push가 아니면 거절하거나, 브랜치 Push 권한을 제어하려는 경우 사용을 권장하는 hook인데 쉽게 말해 repo 관리자 외에 다른 인원이 신규 브랜치를 push 하지 못하도록 할 때 사용하는 hook입니다. (다른 인원은 파일의 수정사항만 push 가능)
다수의 브랜치가 push될 때 pre-receive는 특정 브랜치만 적용되고, update는 모든 브랜치에 대해 실행됩니다.

II. hook 경로 및 sample

스크린샷 2020-10-24 오후 2 42 36

터미널을 열고 아무 git repo/.git 에 들어가면 git에서 지원하는 모든 hook의 sample이 이미 만들어져있습니다. 뒤에 .sample만 제거해도 pre-commit hook 이 활성화됩니다.

# pre-commit.sample 

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

if git rev-parse --verify HEAD >/dev/null 2>&1
then
    against=HEAD
else
    # Initial commit: diff against an empty tree object
    against=$(git hash-object -t tree /dev/null)
fi

# If you want to allow non-ASCII filenames set this variable to true.
allownonascii=$(git config --bool hooks.allownonascii)

# Redirect output to stderr.
exec 1>&2

# Cross platform projects tend to avoid non-ASCII filenames; prevent
# them from being added to the repository. We exploit the fact that the
# printable range starts at the space character and ends with tilde.
if [ "$allownonascii" != "true" ] &&
    # Note that the use of brackets around a tr range is ok here, (it's
    # even required, for portability to Solaris 10's /usr/bin/tr), since
    # the square bracket bytes happen to fall in the designated range.
    test $(git diff --cached --name-only --diff-filter=A -z $against |
      LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
then
    cat <<\EOF
Error: Attempt to add a non-ASCII file name.

This can cause problems if you want to work with people on other platforms.

To be portable it is advisable to rename the file.

If you know what you are doing you can disable this check using:

  git config hooks.allownonascii true
EOF
    exit 1
fi

# If there are whitespace errors, print the offending file names and fail.
exec git diff-index --check --cached $against --

III. hook 만들기

일반 사용자에게 가장 추천되는 hook은 pre-commit 을 이용해 자동으로 코드 스타일을 검사하도록 하는 작업입니다. 이 문단에서는 commit 시 black formatting check을 실행하도록 pre-commit을 구성합니다.

1. pre-commit 패키지 설치

앞서 살펴본 sample처럼 스크립트를 직접 작성할 필요없이 간단히 pre-commit을 만들어주는 패키지가 이미 존재합니다.
pip install pre-commit을 통해 패키지를 설치합니다.

2. config.yaml 작성

pre-commit hook을 심을 repo 최상위 경로에 .pre-commit-config.yaml 파일을 생성하고, 아래 내용을 입력해 저장합니다.

repos:
  - repo: https://github.com/psf/black
    rev: stable
    hooks:
      - id: black

3. pre-commit install

해당 경로에서 터미널을 열고 pre-commit install 명령어를 작성하면 아래와 같이 자동으로 pre-commit hook이 추가된 것을 확인할 수 있습니다!

스크린샷 2020-10-24 오후 3 18 13

이 상태에서 commit 을 실행하면 아래와 같이 자동으로 black style check가 실행됩니다.

스크린샷 2020-10-24 오후 3 43 57

반응형
복사했습니다!