Vojta Jina, Igor Minar
목표
- 스크립트를 통해 CHANGELOG.md 생성 가능
- 중요하지 않은 커밋(형식 변경 등)을 git bisect에서 무시 가능
- 히스토리 탐색 시 더 나은 정보 제공
CHANGELOG.md 생성
CHANGELOG에는 새 기능, 버그 수정, 호환성 깨짐 등 세 가지 섹션을 사용합니다. 릴리즈할 때 스크립트를 통해 이 리스트를 생성할 수 있습니다. 관련 커밋에 대한 링크도 함께 제공합니다. 실제 릴리즈 전에 이 목록을 수정할 수 있지만, 스크립트가 기본 골격을 생성합니다.
지난 릴리즈 이후 커밋 메시지의 모든 제목을 보려면:
git log <last tag> HEAD --pretty=format:%s
이번 릴리즈에서 새 기능을 보려면:
git log <last release> HEAD --grep feature
중요하지 않은 커밋 인식
형식 변경(공백/줄바꿈 추가 또는 제거, 들여쓰기), 누락된 세미콜론, 주석 등은 중요하지 않은 커밋입니다. 코드의 논리적 변경이 없으므로 이러한 커밋은 무시할 수 있습니다.
bisect 중일 때, 이러한 커밋을 무시하려면:
git bisect skip $(git rev-list --grep irrelevant <good place> HEAD)
히스토리 탐색 시 더 많은 정보 제공
이 정보는 일종의 “문맥” 정보를 추가합니다. 아래는 최근 Angular의 몇 가지 커밋 메시지입니다:
- 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)
이 메시지들은 변경된 위치가 명시되지 않아서, 안에 무엇이 들어 있는지 추측하기 어렵습니다. 위치를 명시하는 규칙이 없어서 그렇습니다.
파일이 수정된 위치를 확인하는 방법도 있지만, 이 방법은 느립니다. git 히스토리를 볼 때 많은 개발자가 위치를 명시하려고 노력하는데, 단지 통일된 규칙이 없을 뿐입니다.
커밋 메시지 형식
<type>(<scope>): <subject>
<BLANK LINE>
<body>
<BLANK LINE>
<footer>
커밋 메시지의 각 줄은 100자를 넘지 않아야 합니다! 이렇게 하면 GitHub 및 다양한 git 도구에서 메시지를 더 쉽게 읽을 수 있습니다.
커밋 메시지는 헤더, 본문, 푸터로 구성되며, 각각 빈 줄로 구분됩니다.
되돌리기(Revert)
이전 커밋을 되돌리는 커밋인 경우, 헤더는 revert: 로 시작해야 하며, 뒤에 되돌릴 커밋의 헤더가 따라옵니다. 본문에는 이 커밋은 라고 작성해야 하며, 여기서 는 되돌리는 커밋의 SHA입니다.
메시지 헤더
메시지 헤더는 한 줄로 작성되며, 변경 사항을 간결하게 설명하는 type, 선택적 scope, subject를 포함합니다.
허용되는
이 부분은 커밋이 제공하는 변경 사항의 종류를 설명합니다.
- feat (새로운 기능)
- fix (버그 수정)
- docs (문서화)
- style (코드 포맷, 세미콜론 누락 등)
- refactor (코드 리팩토링)
- test (테스트 코드 추가)
- chore (유지보수 작업)
허용되는
Scope는 커밋 변경 사항의 위치를 지정하는 데 사용됩니다. 예를 들어, $location, $browser, $compile, $rootScope, ngHref, ngClick, ngView 등이 가능합니다.
더 적합한 scope가 없을 경우 *을 사용할 수 있습니다.
텍스트
- 매우 짧은 변경 사항 설명
- 명령형 현재 시제 사용: “change”로 작성, “changed”나 “changes”는 사용하지 않음
- 첫 글자를 대문자로 하지 않음
- 끝에 마침표(.) 사용하지 않음
메시지 본문
- 마찬가지로 명령형 현재 시제를 사용: “change”로 작성, “changed”나 “changes”는 사용하지 않음
- 변경 이유 및 이전 동작과의 차이점 포함
메시지 푸터
브레이킹 체인지(Breaking Changes)
모든 브레이킹 체인지는 커밋 메시지 푸터에 브레이킹 체인지 블록으로 작성해야 하며, BREAKING CHANGE:로 시작합니다. 그 뒤에 변경 사항에 대한 설명, 이유 및 마이그레이션 방법을 적습니다.
예시:
BREAKING CHANGE: isolate scope 바인딩 정의가 변경되었으며
directive 컨트롤러의 주입 옵션이 제거되었습니다.
마이그레이션 방법은 아래 예시를 따르세요:
이전:
scope: {
myAttr: 'attribute',
myBind: 'bind',
myExpression: 'expression',
myEval: 'evaluate',
myAccessor: 'accessor'
}
이후:
scope: {
myAttr: '@',
myBind: '@',
myExpression: '&',
// myEval - 일반적으로 유용하지 않음. 하지만 표현식이 할당 가능한 경우에는 '='를 사용할 수 있음
myAccessor: '=' // directive 템플릿에서 myAccessor()를 myAccessor로 변경
}
제거된 `inject` 옵션은 일반적으로 directive에서 유용하지 않았기 때문에 코드에서 거의 사용되지 않았을 것입니다.
이슈 참조
해결된 버그는 푸터에서 “Closes”라는 키워드로 별도의 줄에 나열해야 합니다. 예를 들어:
Closes #234
또는 여러 이슈가 있는 경우:
Closes #123, #245, #992