ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • husky를 이용한 git-hooks 자동화
    Git 2022. 6. 21. 18:50
    728x90
    반응형

    오늘은 프로젝트에서 다들 사용하는 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 자동화에 대해 알아보았습니다!

     

    끝!

    728x90
    반응형
    SMALL

    'Git' 카테고리의 다른 글

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