1. Git hook
Github 공식문서 - Git Hooks 설명
1-1 Git hook 이란 ?
Git 에서 어떤 이벤트가 생겼을 때 자동으로 특정 스크립트를 실행할 수 있게 함.
1-2 종류
Git hook 의 종류는 많지만 주로 활용할 hook 을 위주로 아래 정리함.
1-2-1 클라이언트 훅
- pre-commit
- 실행 시점
- commit 시 가장 먼저 호출됨
- commit 메세지 작성하기 전에 호출됨
- 용도
- commit 하는 Snapshot 점검
- 커밋 할 때 꼭 확인해야 하는 부분이 있는 경우
- lint 로 코드 스타일을 검사
- 라인 끝의 공백 문자를 검사
- 새로 추가한 코드에 주석을 달았는지
- 테스트 확실히 했는지
- Exit 코드가 0 이 아니면 커밋 취소
- git commit --no-verify 실행 시 일시적으로 생략 가능
- prepare-commit-msg
- 실행시점
- Git이 commit 생성 - prepare-commit-msg - 편집기를 실행하기 전
- 사람이 커밋 메세지를 수정 전 + 프로그램이 커밋 메시지를 손보고 싶을 때
- Argumnet : 커밋 메세지가 들어 있는 파일의 경로, 커밋의 종류
- 용도
- commit 메세지를 자동으로 생성하는 commit 에 이용
- commit 메세지에 Templete 적용 | Merge 커밋 | Squash 커밋 | Amend 커밋
- commit-msg
- 실행 시점
- 최종적으로 commit 이 완료되기 전 → 프로젝트 상태 | 커밋 메세지 검증
- Argument : 커밋 메시지가 들어 있는 임시 파일의 경로
- 0 이 아닌 값을 반환하면 커밋 x
- post-commit
- 실행 시점
- Argument : x
- 커밋 해시 정보는 git log -1 HEAD 명령으로 가져올 수 있음
- 용도
- 커밋 된 것을 누군가 or 다른 프로그램에게 알릴 때 사용
기타 hook
- pre-rebase
- 실행 시점
- 0 이 아닌 값을 반환하면 Rebase 취소
- 이용 예시)
- 이미 Push 한 커밋을 Rebase 하지 못하게 할 수 있음
- post-rewrite
- 시행시점
- 커밋을 변경하는 명령 실행 시(ex)git commit --amend 이나 git rebase) 실행
- git filter-branch 는 해당 x
- Argument: 커밋을 변경하게 한 명령, stdin 으로 변경된 커밋 목록이 전달
- 용도
- post-checkout 이나 post-merge 훅과 비슷
- 디렉토리에서 할 일이 있을 때 - 용량이 크기나 | Git이 관리하지 않는 파일을 옮기거나 | 문서를 자동으로 생성
- post-merge
- 실행되는 시점
- 용도
- 파일 권한같이 Git이 추적하지 않는 정보를 관리하는 데 사용
- merge로 Working Tree가 변경될 때 → Git이 관리하지 않는 파일이 원하는 대로 잘 배치됐는지 검사
- pre-push
- 실행 시점 :
- git push 명령을 실행하면 동작
- Remote 정보를 업데이트하고 난 후 → pre-push → Remote 데이터를 전송
- Parameter : Remote 이름과 주소
- stdin 을 통해 업데이트할 해시 리스트를 전달받는다
- 용도 :
- Push 하기 전에 커밋이 유효한지 확인하는 용도
- 0 이 아닌 값을 반환 시 Push 중지
1-2-2 서버 훅
- Push 전후에 실행된다
- Push 전에 실행되는 훅이 0이 아닌 값을 반환 →해당 Push는 거절 → 클라이언트는 에러 메시지를 출력
- 아주 복잡한 Push 정책도 가능
- pre-receive
- 실행 시점 :
- 표준 입력(STDIN)으로 Push 하는 Refs의 목록을 입력받음
- 0이 아닌 값을 반환하면 해당 Refs가 전부 거절
- 용도 :
- Fast-forward Push가 아니면 거절
- 브랜치 Push 권한을 제어
- 관리자만 브랜치를 새로 Push 하고 삭제할 수 있고 일반 개발자는 수정사항만 Push 할 수 있게
- update
- 각 브랜치마다 한 번씩 실행된다는 것을 제외하면 pre-receive 스크립트와 거의 같음
- ex) 1 번에 n개 브런치 push → pre-receive = 1번 실행 + update = 브랜치마다 실행
- Argument:
- 표준 입력(STDIN) x
- 브랜치 이름, 원래 가리키던 SHA-1 값, 사용자가 Push 하는 SHA-1 값
- 0이 아닌 값을 반환 → 해당 Refs만 거절되고 나머지 다른 Refs는 상관없음
- post-receive
- 실행 시점 :
- 용도
- 사용자나 서비스에 알림 메세지를 보낼 수 있다.
- 메일링리스트에 메일을 보내기
- CI(Continuous Integration) 서버 | Ticket-tracking 시스템의 정보를 수정
- Ticket을 만들고, 수정하고, 닫을 수 있다
- 표준 입력(STDIN)으로 Refs 목록이 넘어감
- 이 스크립트가 완전히 종료할 때까지 클라이언트와의 연결은 유지되고 Push를 중단시킬 수 없다 → 이 스크립트로 시간이 오래 걸릴만한 일을 할 때는 조심해야 한다.
1-3 Git Hook 의 Argument & 자주 사용되는 명령어
commit-msg-file (커밋 메시지 파일)
commit-source (커밋되는 파일)
sha-1 (커밋 번호 - 수정하는 커밋일 때)
git rev-parse --abbrev-ref HEAD
: HEAD가 가리키는 커밋의 해시 넘버를 가져오고, 그 넘버가 가리키는 브랜치 이름을 가져오라는 뜻
2. Husky
2-1 Husky 란?
git-hook 제어를 간편하게 하기 위해 사용
2-2 이용 방법
Husky 공식 문서
2-2-1 권장하는 자동 설치 방법
npx husky-init && npm install # npm
npx husky-init && yarn # Yarn 1
yarn dlx husky-init --yarn2 && yarn # Yarn 2+
pnpm dlx husky-init && pnpm install # pnpm
"scripts": {
...
"prepare": "husky install"
},
2-2-2 hook 추가 방법
husky add .
예시
npx husky add .husky/pre-commit "yarn yarn lint-staged"
- 직접 파일 추가
2-3 적용한 코드
2-3-1 pre-commit 파일 - lint-stage 실행 코드
위치 : .husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
yarn lint-staged
2-3-2 prepare-commit-msg 파일 - [프로젝트 이름 및 브랜치 이름] 자동 적용 코드
위치 : .husky/prepare-commit-msg
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
COMMIT_MSG_FILE=$1
COMMIT_SOURCE=$2
SHA1=$3
BRANCH_NAME=`git rev-parse --abbrev-ref HEAD`
PROJECT_NAME=''
PREFIX=''
if [[ "${BRANCH_NAME}" == *"/"* ]];then
PROJECT_NAME=`echo ${BRANCH_NAME} | cut -d '/' -f1`
PREFIX=`echo PREFIX ${BRANCH_NAME} | cut -d '/' -f2`
fi
FIRST_LINE=`head -n1 ${COMMIT_MSG_FILE}`
if [[ ${PROJECT_NAME} == '' ]]; then
exit
fi
if [ -z "$FIRST_LINE" ]; then
sed -i ".bak" "1s/^/[$PROJECT_NAME] $PREFIX : /" ${COMMIT_MSG_FILE}
fi
[참고 사이트]
Git hook 으로 Commit message 설정
git argument & shell 용어 정리
3. lint-staged
3-1 lint-staged 란?
stage 상태(변경 사항만)의 git 파일에 대해 lint와 우리가 설정해둔 명령어를 실행하기 위해 사용
https://github.com/okonet/lint-staged#readme
3-2 이용 방법
- lint-staged 설치
# npm
npm install --save-dev lint-staged
# yarn
yarn add -D lint-staged
- package.json 설정
ts/tsx 의 경우 prettier 및 eslint 적용 시 아래 코드 설정
"lint-staged": {
"*.{ts,tsx}": [
"prettier --write",
"eslint --fix"
]
},