커밋 체크리스트

이 문서는 Commit Checklist(docs/commit_checklist.md) 문서의 한국어 전체 번역입니다.

다음은 Gerrit에 변경 목록(CL)을 업로드하기 전과 코드 리뷰 과정 중에 살펴보면 유용한 체크리스트입니다. Gerrit은 Chromium 프로젝트의 코드 리뷰 플랫폼입니다. 이 체크리스트는 간결하게 사용할 수 있도록 설계되었습니다. 더 자세한 참고 자료는 Chromium에 기여하기를 보세요. 대상 독자는 Chromium 프로젝트 기여에 익숙하지 않은 소프트웨어 엔지니어입니다. 현재 업로드하는 패치셋에 적용되지 않는 단계는 자유롭게 건너뛰어도 됩니다.

Atul Gawande의 Checklist Manifesto에 따르면, 체크리스트는 자신이 만들어 내는 작업의 일관된 품질을 보장하는 훌륭한 도구입니다. 또한 체크리스트는 어떤 단계를 빠뜨리지 않게 하고 다음에 무엇을 해야 할지 알아내는 데 머리를 낭비하지 않도록 해 주어 더 효율적으로 일하는 데도 도움이 됩니다.

1. 새 브랜치를 만들거나 올바른 브랜치로 전환하기

개발 작업을 시작하기 전에 새 브랜치를 만들어야 합니다. Git에서는 일찍 브랜치를 만들고 자주 브랜치를 만드는 것이 도움이 됩니다. git new-branch <branch_name> 명령을 사용하세요. 이는 git checkout -b <branch_name> --track origin/main과 동일합니다.

다른 로컬 브랜치를 업스트림 브랜치로 설정하고 싶을 수도 있습니다. git checkout -b <branch_name> --track <upstream_branch>로 그렇게 할 수 있습니다. 작업을 여러 CL에 나누고 싶지만 일부 CL이 다른 CL에 의존하는 경우 이렇게 하세요. 현재 브랜치를 업스트림으로 설정하면서 새 브랜치를 만들려면 git new-branch --upstream_current <new_branch_name>을 사용하세요.

관련 crbug를 "started"로 표시하여 다른 사람들이 당신이 해당 버그 작업을 시작했다는 것을 알 수 있게 하세요. 이 단계를 수행하면 중복 작업을 피할 수 있습니다.

이미 브랜치를 만들었다면 개발 작업을 다시 시작하기 전에 올바른 브랜치로 git checkout <branch_name>하는 것을 잊지 마세요. 아이디어나 피드백 구현을 끝내고, 어떤 수수께끼 같은 버그를 디버깅하는 데 몇 시간을 보낸 뒤에야 그 버그가 그동안 잘못된 브랜치에서 작업했기 때문에 생겼다는 사실을 발견하는 것만큼 답답한 일도 드뭅니다.

2. 로컬 업스트림 브랜치가 있다면 업스트림 변경 사항 리베이스하기

다운스트림 브랜치가 업스트림 브랜치에 체인으로 연결되어 있다고 가정해 봅시다. 업스트림 브랜치에 변경 사항을 커밋했고 그 변경 사항이 다운스트림 브랜치에 나타나기를 원한다면 다음을 해야 합니다.

  • 다운스트림 브랜치로 git checkout <branch_name>합니다.
  • 업스트림 변경 사항을 현재 브랜치로 가져오기 위해 git rebase -i @{u}를 실행합니다.
  • 다운스트림 변경 사항을 업스트림 브랜치 위로 리베이스하기 위해 git rebase -i @{u}를 다시 실행합니다.

수많은 병합 충돌을 고쳐야 할 것으로 예상하세요. 작업이 끝나면 git rebase --continue를 사용하세요.

3. 변경 사항 만들기

할 일을 하세요. 여기서는 코드를 작성하거나 고치는 방법에 대해 더 이상의 조언은 없습니다.

4. 코드가 올바르게 빌드되는지 확인하기

변경 사항을 만든 뒤에는 일반적인 대상이 올바르게 빌드되는지 확인하세요.

  • chrome(Linux, ChromeOS 등)
  • unit_tests
  • browser_tests

여러 대상을 빌드하는 방법은 여기에서 지침을 찾을 수 있습니다.

현재 작업 중이 아닌 다른 빌드 중 하나를 자신도 모르게 실수로 깨뜨리기 쉽습니다. Commit Queue가 모든 빌드 오류를 잡아내야 하긴 하지만, CQ Dry Run은 실행하는 데 시간이 걸릴 수 있고 때로는 몇 시간 정도 걸리므로 먼저 로컬에서 확인하면 시간을 절약할 수 있습니다.

5. 변경 사항 테스트하기

Chrome 바이너리를 실행하거나 변경 사항을 테스트 기기에 배포하여 변경 사항을 수동으로 테스트하세요. ChromeOS용 Chrome을 테스트하는 경우 Simple Chrome 지침에 따라 변경 사항을 테스트 기기에 배포하세요. 변경한 모든 코드 경로를 반드시 실행해 보세요.

몇 가지 테스트 팁:

  • 디버깅에는 LOG(ERROR) << "debug print statement"를 사용하세요. ChromeOS 기기의 /var/logs/chrome/에서 로그를 찾을 수 있습니다. 로그 문을 더 빨리 찾을 수 있도록 출력문에 키워드를 추가할 수 있습니다.
  • 디버깅 중 중단점을 설정하려면 GDB를 사용하세요.

코드를 깨뜨릴 수 있는 엣지 케이스를 테스트하는 것도 생각해 보세요. 고려할 만한 일반적인 엣지 케이스는 다음과 같습니다.

  • 게스트 모드
  • Enterprise/EDU/감독 대상 사용자
  • 접근성
  • 공식 Chrome 브랜드 빌드(Googler용)

6. 새 코드에 대해 단위 테스트 또는 브라우저 테스트 작성하기

이전 단계에서 수행한 수동 테스트를 자동화하는 것을 고려하세요.

7. 코드가 보기 좋게 포맷되었는지 확인하기

git cl format --js를 실행하세요. --js 옵션은 JavaScript 변경 사항도 포맷합니다.

8. 변경 사항 검토하기

이전 커밋 이후 자신이 만든 모든 변경 사항을 검토하려면 git diff를 사용하세요. 업스트림 브랜치 이후 자신이 만든 모든 변경 사항을 검토하려면 git upstream-diff를 사용하세요. git upstream-diff의 출력이 Gerrit에 업로드될 내용입니다.

9. 커밋할 관련 파일 스테이징하기

CL에 포함하고 싶은 수정 파일 모두에 대해 git add <path_to_file>을 실행하세요. svn 같은 다른 버전 관리 시스템과 달리, git commit을 호출하기 전에 커밋하려는 파일을 명시적으로 git add해야 합니다.

10. 변경 사항 커밋하기

git commit을 실행하세요. 유용한 커밋 메시지를 반드시 작성하세요. 좋은 커밋 메시지 작성 팁이 몇 가지 있습니다. 이전 단계와 이 단계를 결합하는 단축 방법은 git commit -a -m <commit_message>입니다.

11. 커밋 스쿼시하기

현재 브랜치에 커밋이 많고 다음 단계에서 커밋별로 발생하는 성가신 병합 충돌을 피하고 싶다면, 모든 변경 사항을 하나의 커밋으로 모으는 것을 고려하세요. git rebase -i @{u}를 실행하세요. @{u}는 업스트림 브랜치를 가리키는 축약 포인터로, 보통 origin/main이지만 로컬 브랜치 중 하나일 수도 있습니다. git rebase 명령을 실행하면 커밋 목록이 보일 것이며, 각 커밋은 "pick"이라는 단어로 시작합니다. 첫 번째 커밋은 "pick"으로 되어 있는지 확인하고, 나머지는 "pick"에서 "squash"로 바꾸세요. 그러면 각 커밋이 이전 커밋으로 스쿼시되며, 모든 커밋이 첫 번째 커밋으로 스쿼시될 때까지 계속됩니다.

커밋들을 하나의 커밋으로 스쿼시하는 다른 방법은 이전 단계에서 git commit --amend를 하는 것입니다.

또는 git squash-branch를 실행할 수도 있습니다.

12. 로컬 저장소 리베이스하기

리베이스는 원격 저장소의 변경 사항을 동기화하고 CL의 병합 충돌 오류를 해결하는 깔끔한 방법입니다. git rebase-update를 실행하세요. 이 명령은 개발 작업을 시작한 이후, 어쩌면 꽤 오래전부터, 원격에 랜딩된 변경 사항으로 모든 로컬 브랜치를 업데이트합니다. 또한 해당 브랜치와 연결된 CL이 병합된 뒤처럼 원격 저장소와 일치하는 브랜치를 삭제합니다. 요약하면, git rebase-update는 로컬 브랜치를 정리합니다.

리베이스 충돌을 만날 수 있습니다. 계속 진행하기 전에 수동으로 고친 뒤 git rebase --continue를 실행하세요.

리베이스는 빌드를 깨뜨릴 가능성이 있으므로, 이후 다시 빌드해 보고 싶을 수 있다는 점에 유의하세요. rebase-update 후 다시 빌드를 시도하기 전에 서드파티 의존성을 업데이트하기 위해 gclient sync -D를 실행해야 합니다.

13. Gerrit에 CL 업로드하기

git cl upload를 실행하세요. 유용한 옵션에는 다음이 포함됩니다.

  • --cq-dry-run(또는 -d)은 패치셋이 CQ Dry Run을 수행하도록 설정합니다. 의미 있는 변경 사항이 있는 새 패치셋마다 try job을 실행하는 것이 좋습니다.
  • -r <chromium_username>은 리뷰어를 추가합니다.
  • -b <bug_number>는 커밋 메시지의 버그 참조 줄을 자동으로 채웁니다. 관련 crbug가 없다면 -b None을 사용하세요.
  • -x <bug_number>는 커밋 메시지의 버그 참조 줄을 자동으로 채우고, CL이 제출 및 병합되면 버그를 자동으로 닫힘으로 표시합니다.
  • --edit-description은 커밋 메시지를 업데이트할 수 있게 해 줍니다. 커밋 메시지 제목에 [hashtag]처럼 대괄호를 사용하면 CL에 해시태그가 추가됩니다. 이 기능은 관련 CL을 함께 묶는 데 유용합니다.

올바른 Gerrit CL에 업로드하고 있는지 확인하려면 git cl issue를 확인하세요. 새 CL을 업로드하는 경우 이슈 번호는 none입니다. 업로드하면 새 CL이 자동으로 생성됩니다. 새 패치를 업로드할 기존 CL을 대상으로 지정하려면 git cl issue <issue_number>를 사용하세요.

리뷰어가 더 쉽게 따라올 수 있도록, 각 패치셋에 변경 사항을 요약하고 누구의 댓글을 반영했는지 나타내는 제목을 제공하는 것도 권장됩니다. git cl upload를 실행하면 새 패치셋이 업로드되고 짧은 패치셋 제목을 입력하라는 메시지가 표시됩니다. 제목의 기본값은 가장 최근 커밋 요약입니다(-T 옵션은 묻지 않고 이것을 사용합니다). 모든 커밋을 하나로 스쿼시하는 편이라면 업로드할 때마다 새 요약을 입력해 보세요. Gerrit에서 패치셋 제목을 직접 수정할 수도 있습니다.

14. Gerrit에서 CL 다시 확인하기

현재 브랜치와 연결된 Gerrit URL로 이동하려면 git cl web을 실행하세요. 최신 패치셋을 열고 업로드된 모든 파일이 올바른지 확인하세요. Expand All을 클릭하여 개별 줄 단위 변경 사항을 모두 다시 살펴보세요. 기본적으로 리뷰어에게 리뷰를 요청하기 전에 셀프 리뷰를 하세요.

15. 모든 자동 회귀 테스트가 통과하는지 확인하기

CQ Dry Run을 클릭하세요. 오류가 있으면 고치세요. 그렇지 않으면 CL이 commit queue(CQ) 검사를 통과하지 못합니다. 결과로 인해 CL에 큰 변경이 필요할 수 있으므로, 리뷰어에게 알리기 전에 CQ Dry Run이 통과할 때까지 기다리는 것을 고려하세요.

또는 git cl try를 실행할 수 있습니다.

16. 코드를 리뷰할 리뷰어 추가하기

Find Owners를 클릭하거나 git cl owners를 실행하여 코드를 리뷰할 파일 소유자를 찾고, 그들에게 어느 부분에 집중해 주기를 원하는지 알려 주세요. 보통 해당 영역에 대한 도메인 지식이 가장 많으므로, 수정 중인 파일에 더 구체적인 소유자를 선호하세요(즉 //chrome/OWNERS보다 //chrome/foo/bar/OWNERS를 선호하세요). 다음으로, 코드를 리뷰해야 한다고 생각하는 다른 사람을 추가하세요. Code Search의 blame 기능은 CL이 건드리는 코드 부분에 익숙할 수 있는 리뷰어를 식별하는 좋은 방법입니다. CL이 랜딩되려면, 자신이 일부 파일의 소유자인 경우를 제외하고, 변경한 각 파일에 대해 소유자 한 명의 승인이 필요합니다. 자신이 소유자인 파일에 대해서는 별도의 소유자 승인이 필요하지 않습니다.

CL에 이미 필요한 모든 owners 리뷰가 있더라도, 제출(CQ+2)하기 전에 적극적으로 참여하는 모든 리뷰어가 변경 사항에 CR+1을 줄 때까지 기다리는 것이 기대됩니다. 혼란과 실수를 방지하는 것 외에도, 이러한 기대가 존재하는 이유는 다음과 같습니다.

  1. 참여 리뷰어들은 지속 가능한 코드를 작성하도록 도와주고 있으며, 그들이 승인할 수 있게 하는 것은 그들의 노력에 대한 존중입니다.
  2. owners 시스템은 완벽하지 않으며, 때로는 전체 변경을 승인할 수는 있지만, 더 지식이 많은 다른 owners에게 일부에 대한 승인을 위임할 소유자가 필요할 수 있습니다.

이 기대를 깨야 한다면, 댓글에서 그 이유를 정당화해야 하며, 적절한 추가 주의가 필요할 수 있습니다(예: 제출 후 리뷰 받기, 실패하거나 flaky한 테스트 모니터링하기, 문제가 발생하면 되돌리기 등).

17. 리뷰 시작하기

실제 리뷰 절차를 시작하려면 Start Review 버튼을 클릭하세요. 이 버튼을 누르기 전까지는 아무도 당신의 변경 사항을 보지 않습니다. 버튼을 누르면 리뷰어에게 전송되는 알림에 추가 메시지를 포함할 기회가 주어집니다.

18. 리뷰어의 피드백 구현하기

그런 다음 이 커밋 체크리스트를 다시 따라가세요. Gerrit에서 리뷰어의 모든 댓글에 답하고, 해결된 모든 이슈를 resolved로 표시하세요. 해결되지 않은 모든 댓글을 보려면 Gerrit의 "Comments" 탭을 클릭하세요. 댓글에서 자유 형식으로 상호작용하는 것(Reply 또는 Quote 사용) 외에, 일반적인 관례는 다음과 같습니다.

  • 댓글에서 Done을 클릭하면 "Done"이라고 댓글을 달고 이 댓글을 해결 처리합니다. 이는 보통 리뷰어가 요청한 변경에 대한 응답으로 사용되며, 리뷰어가 요청한 변경을 수행했음을 알려 줍니다.
  • 댓글에서 Ack를 클릭하면 "Ack"("Acknowledged"의 줄임말)라고 댓글을 달고 이 댓글을 해결 처리합니다. 이는 보통 리뷰어의 실행 불가능한 댓글에 대한 응답으로 사용되며, 이해했다는 것을 리뷰어에게 알려 줍니다.

마지막으로, 리뷰어가 알림을 받도록 CL에서 Reply를 클릭하세요. 이렇게 하면 다시 리뷰할 준비가 되었다는 신호가 됩니다. 왜냐하면 reply를 누르기 전까지는 CL이 리뷰 준비가 되지 않았다고 가정하기 때문입니다.

빠르고 생산적이며 존중하는 리뷰를 보장하려면 Respectful Changes의 지침을 따르세요.

변경 사항이 단순하고 다음 반복에서 리뷰어가 CL을 승인할 것이라고 자신한다면 Auto-Submit +1을 설정할 수 있습니다. 승인 후 CL은 자동으로 다음 단계로 진행됩니다. 이 기능은 리뷰어가 다른 시간대에 있고 CL을 더 빨리 랜딩하고 싶을 때 유용합니다. 이 플래그를 설정하면 CL을 랜딩할 책임도 리뷰어에게 넘어갑니다.

19. CL 랜딩하기

변경 사항을 랜딩하기 위한 최소 요구 사항을 충족하려면 다음을 갖추어야 합니다.

  • Looks Good To Me(LGTM)를 획득해야 하며, 이는 Gerrit에서 Code-Review+1로 반영됩니다.
    • 자신이 소유자인 파일을 제외하고 각 파일마다 최소 한 명의 owner로부터
    • 두 명의 committer로부터, 또는 자신도 committer라면 한 명의 committer로부터
  • 모든 코드 리뷰 댓글을 해결해야 합니다.

위에서 언급했듯이, 이미 OWNERS 승인을 받았더라도 일반적으로 모든 리뷰어가 변경 사항을 승인할 때까지 기다리는 것이 기대됩니다. CL이 서브시스템에 의미 있는 변경을 가한다면 chrome/OWNERS를 포괄적인 승인 도장처럼 사용하지 마세요. Submit to CQ(Commit-Queue +2)를 클릭하면 commit queue(CQ)에서 변경 사항을 시도하고 성공 시 자동으로 랜딩합니다.

또는 git cl set-commit을 실행할 수 있습니다.

CL이 CQ를 통과했다고 해서 아직 완전히 안심할 수 있다는 뜻은 아닙니다. 내부 비공개 try job 실패가 있을 수도 있고, 코드 리뷰 과정에서 눈에 띄지 않은 버그가 있을 수도 있습니다. CL이 랜딩된 뒤 약 하루 동안 Chromium tree를 모니터링하는 것을 고려하세요. Sheriff나 다른 누군가가 실패를 알려 주면, 먼저 CL을 되돌리고 질문은 나중에 하세요. Gerrit은 revert CL을 자동으로 생성할 수 있습니다.

20. 정리

CL이 랜딩된 뒤에는 git rebase-update 또는 git cl archive를 사용하여 로컬 브랜치를 정리할 수 있습니다. 이 명령들은 병합된 브랜치를 자동으로 삭제합니다. 관련 crbug를 "fixed"로 표시해 주세요.