[Git] AngularJS Git Commit Message Conventions 정리

Kozel·2022년 11월 5일
0
post-thumbnail

본문은 AngularJS Git Commit Message Conventions을 번역하여 정리한 글입니다.

오역이 있을 수 있습니다. 혹여나 잘못된 내용이나 조언할게 있어 피드백 주신다면 감사하겠습니다.

1. 목표

AngularJS Git Commit Message Conventions은 다음과 같은 목표를 가지고 있습니다.

  • 스크립트로 CHANGELOG.md을 작성할 수 있다.
  • git bisect으로 중요도가 떨어지는 commit을 무시할 수 있다.
  • commit 기록을 확인 할 때 추가적인 정보를 제공할 수 있다.

해당 목표를 상기하며 본문을 살펴봅시다.



2. CHANGELOG.md 작성

CHANGELOG.md는 이름에서 알 수 있듯이 특정 소프트웨어 프로그램에 대한 모든 변경 사항을 기록하는 파일입니다.

CHANGELOG.md은 개발자와 배포된 서비스를 접하는 사용자 모두에게 도움이 됩니다.

개발자에게는 변경 사항의 추적과 유지보수에 도움이 되고 사용자에게는 서비스의 어떤 이슈가 있고 현재 상태가 어떤지 확인하여 사용에 도움을 줍니다.

CHANGELOG.md의 작성법에 대한 더 자세한 내용은 CHANGELOG.md 가이드라인을 참고하시면 될 것 같습니다.

여기선 CHANGELOG.md 파일에 기재할 commit log 리스트를 간단하게 출력해보는 방법을 알아봅시다.


  • 마지막 릴리즈 이후 모든 커밋 메시지의 첫번째 줄 출력

    git log <last tag> HEAD --pretty=format:%s

    <last tag>에는 가장 마지막에 릴리즈했던 태그를 입력합니다.

    제가 했던 프로젝트 중 하나를 예시로 보겠습니다. 우선 다음과 같은 명령어로 태그를 확인합니다.

    tag는 주로 릴리즈 버전관리를 위해 사용합니다.
    git tag에 대한 자세한 내용은 추후에 다뤄보도록 하겠습니다.

    그리고 확인하고 싶은 마지막 태그를 다음과 같이 입력합니다.

    주의해야 할 점은 태그와 'HEAD'사이에 '..'을 넣어줘야 합니다.

    위와 같이 마지막 태그부터 가장 최근까지의 커밋을 확인합니다.
    커밋 컨벤션은 조금도 신경쓰지 않았을 때의 커밋이라,, 혹시나 참고하지는 않도록 합시다.

    --pretty 옵션에 관한 자세한 내용은 git PRETTY FORMATS을 참고해주세요.


  • 현재 릴리즈의 새로운 기능 출력

    git log <last release> HEAD --grep feature
    • <last release>에는 위의 <last tag> 같은 역할을 합니다.
    • --grep은 커밋 메시지 안의 텍스트를 검색하는 속성으로 위의 명령어에서는 'feature'을 검색한다는 의미입니다.

    정리하자면 'last release에서 지금까지의 커밋 중 feature이 들어간 커밋을 검색한다.' 입니다.


    다음과 같이 명령어를 입력한다면

    업로드중..

    검색어가 포함된 커밋을 출력합니다.


2.1. 중요하지 않은 커밋 메세지 식별

커밋 중에서는 분명 기록하기에 불필요한, 중요도가 떨어지는 메세지가 있을 것입니다.
가장 큰 예로 다음과 같은 커밋이 있습니다.

  • 형식 변경(공백, 빈 줄 추가, 제거, 들여쓰기)
  • 세미콜론 누락
  • 주석

위와 같은 예시같이 로직에 변경 사항이 없는 커밋은 무시하는 것이 좋습니다.

이 때 git bisect을 사용할 수 있습니다.

git bisect skip $(git rev-list --grep irrelevant <good place> HEAD)

git bisect은 커밋을 2진 탐색하며 커밋에 문제가 있는지 없는지 확인하기 위해 사용합니다.

위의 명령어는 탐색을할 때 'irrelevant'라는 문구가 있는 커밋은 무시하라는 뜻입니다.

git bisect skip에 대한 내용은 학습이 부족해서 자세히 기재하지 못했습니다. 추후에 다뤄보도록 하겠습니다.

혹시나 궁금하다면 git-bisect 문서를 참고해주세요.


2.2. Commit 기록을 검색할 때 추가 정보 제공

커밋을 확인할 때 더 많은 정보를 제공하기 위해 '문맥'정보를 추가합니다.

다음은 커밋의 예시입니다.

  • Fix small typo in docs widget (tutorial instructions)
  • Fix test for scenario.Application - should remove old - iframe
  • docs - various doc fixes
  • docs - stripping extra new lines
  • Replaced double line break with single when text is fetched from Google
  • Added support for properties in documentation

위 메세지들은 어디가 어떻게 바뀌었는지 명시하였지만 정해진 형식이 없습니다.

다음의 커밋도 봅시다.

  • fix comment stripping
  • fixing broken links
  • Bit of refactoring
  • Check whether links do exist and throw exception
  • Fix sitemap include (to work on case sensitive linux)

이번엔 어느정도 형식이 있지만 어떤 내용이 변경되었는지 알기 어렵습니다.

위의 둘과 같은 커밋에서도 찾고자 하면 찾을 수 있을 겁니다. 다만 효율성이 떨어질 것입니다.


위에서 살펴본 내용을 정리하자면, 형식을 지키고 변경 내용을 확실하게 기재하여 커밋한 뒤 적절한 명령어로 커밋 탐색 후 CHANGELOG.md을 작성한다면 개발자와 사용자 모두 유용할 것입니다.



3. Commit 메세지의 형식

commit 메세지의 형식은 다음과 같습니다.

<type>(<scope>): <subject> 	// Subject line
<BLANK LINE>				// 빈 줄
<body>						// Message body
<BLANK LINE>				// 빈 줄
<footer>					// Message footer

전체적으로 지켜야 할 것이 있다면 가독성을 위해 각 줄마다 100자는 넘기지 않는 것을 권장합니다.

이제 각 줄마다 어떤 형식으로 무슨 내용을 적어야하는지 봅시다.

3.1. Commit 메세지의 Header(Subject line)

<type>(<scope>): <subject>

Subject line에는 변경사항에 대한 간략한 설명을 적습니다.

3.1.1. <type>

commit 어떤 내용이냐에 따라 <type>을 정할 수 있습니다.

  • feat (feature) : 기능 구현
  • fix (bug fix) : 버그 수정
  • docs (documentation) : 문서 관련 사항
  • style (formatting, missing semi colons, …) : 스타일 변경 (형식, 세미콜론 누락 등)
  • refactor : 리팩토링
  • test (when adding missing tests) : 테스트
  • build : 빌드 관련 파일 수정
  • ci : CI 설정 파일 수정
  • perf : 성능 개선
  • chore (maintain) : 빌드, 패키지 관련 (업데이트 등) 혹은 그 외 자잘한 수정

3.1.2. <scope>

<scope>에는 변경 사항이 있는 어떤 위치든 적을 수 있습니다. 단, 생략 가능합니다.

예를 들어 $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView, 등등...

쉽게 말하자면 변경사항이 있는 함수나 메서드, 클래스도 기재할 수 있습니다.


3.1.3. <subject>

<subject>에는 다음과 같은 규칙을 준수합니다.

  • 명령문, 현재 시제로 작성합니다.
    EX) “changed”, “changes”가 아닌 “change”로 작성합니다.
  • 첫글자를 대문자로 쓰지 않고 소문자로 작성합니다.

  • 마지막에 마침표(.)를 붙이지 않습니다.


3.2. Commit 메세지의 Body(Message body)

<body>

<body>에는 커밋의 주 내용을 적습니다.

  • 명령문, 현재 시제로 작성합니다.

  • 변경된 이유와 변경 전과의 차이를 기재합니다.

다음은 참고할 자료입니다.
Writing Git commit messages
A Note About Git Commit Messages


<footer>

<footer>에는 주요 변경 내역과 어떤 이슈를 해결하였는지 기재합니다.

3.3.1. 주요 변경 내역(Breaking Changes)

모든 주요 변경 사항은 변경 점(change), 변경 이유(justification), 마이그레이션 참고사항(migration notes)과 함께 footer에 작성합니다.

다음은 예시입니다.

				// 변경 점
BREAKING CHANGE: isolate scope bindings definition has changed and
    the inject option for the directive controller injection was removed.
    
    // 마이그레이션 참고사항
    To migrate the code follow the example below:
    
    Before:
    
    scope: {
      myAttr: 'attribute',
      myBind: 'bind',
      myExpression: 'expression',
      myEval: 'evaluate',
      myAccessor: 'accessor'
    }
    
    After:
    
    scope: {
      myAttr: '@',
      myBind: '@',
      myExpression: '&',
      // myEval - usually not useful, but in cases where the expression is assignable, you can use '='
      myAccessor: '=' // in directive's template change myAccessor() to myAccessor
    }
    
    // 변경 이유
    The removed `inject` wasn't generaly useful for directives so there should be no code using it.

상단 부터 차례로 변경 점, 마이그레이션 참고사항, 변경 이유가 기재되어 있는 것을 확인할 수 있습니다.


3.3.2. 해결된 이슈(Referencing Issues)

해결된 이슈가 있다면 footer에 'Closes #<이슈번호>'로 기재합니다.

Closes #234

// 해결된 이슈가 여러가지라면
Closes #123, #245, #992


4. Examples

위의 컨벤션을 따라 작성된 커밋 메세지를 살펴보자.

feat($browser): onUrlChange event (popstate/hashchange/polling)

Added new event to $browser:
- forward popstate event if available
- forward hashchange event if popstate not available
- do polling when neither popstate nor hashchange available

Breaks $browser.onHashChange, which was removed (use onUrlChange instead)
fix($compile): couple of unit tests for IE9

Older IEs serialize html uppercased, but IE9 does not...
Would be better to expect case insensitive, unfortunately jasmine does
not allow to user regexps for throw expectations.

Closes #392
Breaks foo.bar api, foo.baz should be used instead
feat(directive): ng:disabled, ng:checked, ng:multiple, ng:readonly, ng:selected

New directives for proper binding these attributes in older browsers (IE).
Added coresponding description, live examples and e2e tests.

Closes #351
style($location): add couple of missing semi colons
docs(guide): updated fixed docs from Google Docs

Couple of typos fixed:
- indentation
- batchLogbatchLog -> batchLog
- start periodic checking
- missing brace
feat($compile): simplify isolate scope bindings

Changed the isolate scope binding options to:
  - @attr - attribute binding (including interpolation)
  - =model - by-directional model binding
  - &expr - expression execution binding

This change simplifies the terminology as well as
number of choices available to the developer. It
also supports local name aliasing from the parent.

BREAKING CHANGE: isolate scope bindings definition has changed and
the inject option for the directive controller injection was removed.

To migrate the code follow the example below:

Before:

scope: {
  myAttr: 'attribute',
  myBind: 'bind',
  myExpression: 'expression',
  myEval: 'evaluate',
  myAccessor: 'accessor'
}

After:

scope: {
  myAttr: '@',
  myBind: '@',
  myExpression: '&',
  // myEval - usually not useful, but in cases where the expression is assignable, you can use '='
  myAccessor: '=' // in directive's template change myAccessor() to myAccessor
}

The removed `inject` wasn't generaly useful for directives so there should be no code using it.


5. 결론

정리하자면 다음과 같다.

  • 릴리즈를 업데이트 할 때마다 (버전 업데이트) CHANGELOG.md에 중요 커밋들을 정리한다.

  • Commit 메세지의 형식을 지켜 작성한다.

    • Subject line : 변경사항에 대한 간략한 설명
    • Message body : 변경된 이유와 변경 전과의 차이
    • Message footer : 주요 변경 내역과 해결된 이슈


6. 마치며

전체적으로 보면 커밋 메세지에 꽤 자세히 작성하며 나쁘게 보면 귀찮다고 느낄 수 있다.

하지만 그만큼 내가 전까지 했던 커밋들이 얼마나 가독성이 부족하고 성의 없었는지 알 수 있었다.

그리고 커밋 컨벤션을 지킨다는 것은 협업에 대한 기본 사항이기 때문에 충분히 익힐 필요가 있다.


잘못된 점에 대한 지적과 조언은 언제든 환영입니다.

profile
front-end developer

1개의 댓글