특정 문자열이 커밋되는 것을 막아보자

페이스북이나 인스타그림 등의 open api를 사용하기 위해서는 인증을 위한 토큰 값이나 키 값을 사용해야 할 때가 있습니다. 민감할 수 있는 정보라 git 에 커밋하는게 그리 달갑지 않아, 이런 경우 직접 코드를 삭제하고 커밋하곤 했습니다. 커밋 전에 뭔가 diff 에 걸러져 나오는 코드에 특정 문자열이 포함되어 있는 경우에 커밋이 불가능하도록 하고 싶어 찾아 보았습니다.

git 에는 어떤 이벤트가 생겼을 때 자동으로 특정 스크립트를 실행 하도록 할 수 있도록 git hook 이라는 기능을 제공하고 있습니다.

git hook의 종류

  • 클라이언트 훅
    • 커밋이나 merge 할 때 실행
  • 서버 훅
    • push 할 때 서버에서 실행

git hook 을 사용하기 위해서는 별도로 새로운 어플리케이션을 설치할 필요가 없습니다. .git 디텍토리의 하위 디렉토리인 hooks 에 훅 스크립트를 생성해주기만 하면 자동으로 git 명령어가 실행될 때 스크립트가 구동됩니다.

클라이언트 훅

앞서 언급한 것 처럼 클라이언트 훅은 커밋이나 merge 를 할 때 실행됩니다. 클라리언트 훅에는 commit workflow hook, e-mail workflow hook, 그리고 나머지 훅으로 분류할 수 있다고 합니다. 본 포스트에서는 commit workflow hook 만 간단하게 알아보고, 특정 문자열이 포함된 소스코드가 있는 경우 커밋이 되게 하지 않도록 스크립트를 만들어 보겠습니다.

commit workflow hook 은 다음과 같이 4종류가 있습니다.

  1. pre-commit
    • 커밋할 때 가장 먼저 호출되는 훅
    • 커밋 메시지를 작성하기 전에 호출
    • 커밋하는 snapshot을 점검
    • 빠뜨린 것은 없는지, 테스트는 확실히 했는지 등 검사
    • 커밋할 때 꼭 확인해야 할 게 있으면 이 훅으로 확인
    • Exit 코드가 0이 아니면 커밋은 취소
    • git commit –no-verify 를 통해서 훅을 일시적으로 생략 가능
  2. prepare-commit-msg
    • git이 커밋 메시지를 생성하고 나서 편집기를 실행하기 전에 실행
    • 사람이 커밋 메시지를 수정하기 전에 프로그램을 손보고 싶을 때 사용
    • 커밋 메시지가 들어 있는 파일의 경로, 커밋 종류를 아규먼트로 받음
    • 커밋 메시지를 자동으로 생성하는 커밋에 적합
    • 커밋 메시지에 템플릿을 적용
    • 커밋 메시지 템플릿에 정보를 삽입
  3. commit-msg
    • 커밋 메시지가 들어 있는 임시 파일의 경로를 아규먼트로 수신
    • 커밋 메시지가 정책에 맞는지 검사하는 스크립트
  4. post-commit
    • 커밋된 것을 누군가에게 알릴 때 사용

참고로 클라이언트 훅의 경우에는 git clone 을 통해서 복사되지 않기 때문에 개별적으로 직접 설치하고 관리해야 한다고 합니다.

pre-commit 훅 만들어 보기

hooks 디렉토리에는 다음과 같이 이미 여러가지 훅 샘플들이 준비되어 있습니다.

1
2
applypatch-msg.sample		post-update.sample		pre-commit.sample		pre-rebase.sample		prepare-commit-msg.sample
commit-msg.sample pre-applypatch.sample pre-push.sample pre-receive.sample update.sample

특정 문자열이 포함되어 있는 경우 커밋되는 것을 원치 않기 때문에 pre-commit 훅을 만들어 보겠습니다. hooks 디텍토리에 pre-commit 이란 이름의 파일을 생성합니다. 저는 consumerKey, consumerSecret, token, secret 과 같은 문자열들이 포함된 경우 커밋이 되지 않도록 스크립트를 작성하였습니다.

1
2
3
4
5
6
7
8
9
10
11
12
disallowed="consumerKey consumerSecret token secret"

git diff --cached --name-status | while read x file; do
if [ "$x" == 'D' ]; then continue; fi
for word in $disallowed
do
if egrep $word $file ; then
echo "ERROR: Disallowed expression \"${word}\" in file: ${file}"
exit 1
fi
done
done || exit $?

저장을 해줌으로써 pre-commit 훅 을 생성하였습니다. Test 클래스를 추가하여 다음과 같이 파일을 수정해주었습니다.

1
2
3
4
5
6
public class Test {
String consumerKey = "";
String consumerSecret = "";
String token = "";
String secret = "";
}

커밋을 해보겠습니다. git commit 으로 커밋을 시도하였더니, 다음과 같은 결과를 확인하였습니다.

1
2
3
daeuky$ git commit -m "pre commit test"
String consumerKey = "";
ERROR: Disallowed expression "consumerKey" in file: src/main/java/com/...

consumerKey 라는 문자열이 포함되어 있어 커밋을 허용할 수 없다는 메시지가 노출됩니다. git log 를 통해서 커밋 이력을 확인해보아도 pre commit test 라는 커밋 메시지를 확인 할 수 없습니다. 해당 부분을 제거하고 다시 커밋을 시도해보니 이제야 커밋이 정상적으로 진행됩니다.

마무리

본 포스트에서는 깃 훅에 대해서 간단히 알아보고, 그 중 하나인 pre-commit 훅 을 직접 만들어 보았습니다. 이런 경우 커밋할 때마다 해당 문자열에 대해서 수동으로 제거해줘야 하는 번거로움이 있을 수 있습니다. 문자열을 관리하는 프로퍼티 파일이 있는 경우 해당 파일을 .gitignore 에 추가하는 것도 하나의 방법이 될 수 있을 것 같네요.

JUnit5 - assertAll 외 자바로 카프카 프로듀서 만들기

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×