본문 바로가기

Git

husky를 이용한 git-hooks 자동화

오늘은 프로젝트에서 다들 사용하는 git에 관련된 내용입니다!

그중에서 git-hooks에 대해 알아볼건데요!

 

git-hooks란?

git과 관련된 이벤트가 발생했을떄 특정 스크립트를 실행할 수 있도록 하는 기능

 

git init을 하면 자동적으로 생기는 기능이라고 합니다..!(git 넘나 좋은것..)

 

종류

이렇게 있다고 하는데 그 중에서 오늘 소개할 부분은 빨간네모 부분인 prepare-commit-msg, commit-msg, pre-push 입니다!

 

 

 

git init을 하면 안에 .git/hooks폴더가 생성되게 됩니다.

폴더 내부를 살펴보면

이렇게 구성되어있는데 뒤에 .sample확장자를 없애주면 hooks가 실행됩니다!

 

 

하지만 프로젝트를 진행할때 .git폴더는 올라가지 않는거 알고 있죠?!

아무리 좋은 스크립트를 작성하더라도 내 컴퓨터만 적용되는 거라는거..ㅜ(clone받은 상대방에게는 적용되지 않습니다요..)

 

그러면 상대방이 clone받을때 마다 .git/hooks폴더 안에 있는 스크립트들을 전달해줘서 복사받게 해야 할까요?

이런 불편함을 해결해주는 것이 git-hooks를 공유할 수 있는 husky라는 모듈입니다!

 

 

husky란?

git hooks를 쉽게 적용할 수 있게 해주는 npm모듈

commit, push정책을 관리하고 공유할 수 있게 해준다.

 

 

그렇다면 어떻게 프로젝트 세팅시 적용할 수 있을까?

 

1. 먼저 husky를 설치한다.

npm install -D husky 혹은 yarn add -D husky

 

 

다음 단계로 검색해보니 많은 블로그에서 .huskyrc파일을 만들어 관리할 수 있다고 하지만 무슨일인지 내 컴퓨터에선 아무리 설정파일을 만들어도 적용되지 않았다...(아마 node_modules/husky/package.json 파일에 install 스크립트 부분이 빠진 것 같다..!)

그래서 나는 https://typicode.github.io/husky/#/ 요기 링크를 참고해 npx husky-init && yarn를 해주었다.

 

이렇게 되면 

다음과 같은 .husky폴더가 생성된다!

이제 여기에서 pre-push, pre-commit등 여러가지 스크립트를 정의하면 된다!

 

 

 

이번 글에서는 총 세가지를 설정해줄 것이다.

 

1. commit시 commit template적용

2. commit 완료시 형식에 맞지 않을시 commit 되지 않음

3. develop, master에 push시 에러 발생(git-flow 브랜치 전략을 따르기 위함) - git-flow 에 대한 설명은 요기서 ->

 

 

[Git] Git-Flow에 대하여

오늘은 회사에서 새로운 프로젝트를 진행할때 git-flow 브랜치 전략을 적용하기 위해 사전 학습한 내용을 정리하고자 한다. 먼저 브랜치 전략이란? 소프트웨어의 상태에 따라 브랜치를 분리하는

fansor.tistory.com

 

 

1. 먼저 commit시 template적용이다!

 

일단 루트경로에 .gitmessage로 출력하고 싶은 메시지를 적어준다.

그 다음 prepare-commit-msg파일을 다음과 같이 수정하자!

# prepare-commit-msg

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3

PROJECT_ROOT="$(git rev-parse --show-toplevel)"
TEMPLATE_FILE="$PROJECT_ROOT/.gitmessage"

if [ "$COMMIT_SOURCE" = "commit" ]; then
    # 템플릿의 변경사항이 있는지 체크섬 확인, 있는경우 종료
    [ "$(cksum "$TEMPLATE_FILE" | cut -d' ' -f1)" != "2429101225" ] && exit

    TITLE_LINENO=2
    BODY_LINENO=5
    # 제목, 본문 라인의 내용을 변경하여 덮어쓰기
    awk "
        NR==${TITLE_LINENO} {
            printf \"%s\", \"$(git show -s --format=%s $SHA1)\"
        }
        NR==${BODY_LINENO} {
            $(git show -s --format=%b $SHA1 | sed -e 's/.*/print "&";/')
        }
        { print }" "$TEMPLATE_FILE" > "$COMMIT_MSG_FILE"
elif [ "$COMMIT_SOURCE" = "template" ] || [ -z "$COMMIT_SOURCE" ]; then
    # 원본 메시지 파일 백업
    mv "$COMMIT_MSG_FILE" "$COMMIT_MSG_FILE.bak"
    # 덮어쓰기
    cat "$TEMPLATE_FILE" > "$COMMIT_MSG_FILE"
fi

스크립트는 아직 잘몰라 검색을 통해 어찌저찌 완성하였다..!

 

이제 다음과 같이 git commit을 할때마다 템플릿 메시지가 출력되어 쉽게 commit메시지를 작성할 수 있다!

 

 

2. 다음으로 형식에 맞지 않는 commit의 경우 commit을 하지 않도록 하는 기능이다!

 

commit-msg 파일에 다음과 같은 스크립트 파일을 작성해준다.

# commit-msg

#!/bin/sh

# 주석 제거
sed -i.bak -e '/^#/d' "$1"

if test "" = "$(grep -o -E '^Merge ' "$1")" && \
    test "" = "$(sed -n -E \
    -e 's/^(fixup|amend|squash)\! //' \
    -e '/^([a-z]+)(\([^\)]+\))?\!?: /,1p' "$1")"; then

    echo >&2 '메시지는 반드시 "<타입>[적용 범위(선택 사항)]: "으로 시작해야 합니다'
    echo >&2 '참고: https://www.conventionalcommits.org/ko/v1.0.0-beta.4/'

    exit 1
fi

정규식을 사용해 commit 메시지 형식에 어긋났을때 commit이 되지 않는다!

 

 

3. 마지막으로 git-flow전략을 따르기 위해 develop, master에 push시 에러를 발생시키는 기능이다.

 

git-flow 브랜치 전략에서 master와 develop에는 직접 push하면 안되므로 제한을 걸어준다.

pre-push파일에 다음과 같은 스크립트를 작성해준다,

# pre-push

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

CURRENT_BRANCH=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
NOPUSH_BRANCHES=("master", "develop")

for branch in ${NOPUSH_BRANCHES[@]};
do
    if [ $branch == $CURRENT_BRANCH ]; 
    then
        echo "DO NOT PUSH $CURRENT_BRANCH BRANCH"
        exit 1 
    fi
done

exit 0

추가하고 싶은 브랜치가 있다면 NOPUSH_BRANCHES에 추가해주면 된다!

 

다음과 같이 develop에 push하려고 할때 에러가 나게 된다!

 

 

오늘은 git-hooks와 husky를 이용한 git-hooks 자동화에 대해 알아보았습니다!

 

끝!

반응형
SMALL

'Git' 카테고리의 다른 글

[Git] Git-Flow에 대하여  (0) 2022.06.07
[Git] commit 쪼개기  (0) 2021.10.16