
git blame이 나 대신 사과하도록 만들었습니다
요약
git blame의 결과를 Gemini AI를 활용해 재미있는 사과나 농담으로 변환해주는 CLI 도구인 'git-sorry'를 소개합니다. 코드 작성자를 판별하여 Slack이나 Discord로 메시지를 전송하는 기능을 갖추고 있습니다.
핵심 포인트
- git blame 결과를 Gemini API로 분석하여 메시지 생성
- 본인 코드일 경우 사과, 팀원 코드일 경우 농담(roast) 메시지 출력
- Slack 및 Discord 웹훅을 통한 자동 메시지 전송 지원
- TypeScript로 구현된 가볍고 재미있는 개발 생산성 도구
모든 코드베이스에는 보는 것만으로도 움찔하게 만드는 줄이 하나씩 있습니다. 권한 확인(authorization check) 로직 내부에서 3단계나 중첩된 삼항 연산자(nested ternary)가 또 다른 조건문 안에서 true : false를 반환하고 있고, 그 위에는 _"나에게 묻지 말고 수정하지 마시오."_라는 주석이 달려 있는 식이죠.
보통 그다음 행동은 git blame을 실행한 뒤, 어색한 대화를 나누는 것입니다. 때로는 그 대화 상대가 자기 자신일 수도 있습니다. 왜냐하면 결과로 나오는 이름이 바로 본인의 이름이기 때문입니다.
git-sorry는 그 어색한 부분을 대신 처리해주며, 아무도 방어적인 태도를 취하지 않을 만큼 재미있게 만들어 줍니다.
내가 만든 것
git-sorry는 파일과 줄 번호를 입력받아 git blame을 실행하고, 범인이 본인인지 아니면 다른 사람인지 판별합니다. 그런 다음 Gemini에게 적절한 응답을 작성하도록 요청합니다. 해당 줄이 본인의 것이라면 비굴한 사과를, 팀원의 것이라면 놀리는(roast) 메시지를 작성하여 팀의 Slack 또는 Discord에 게시합니다.
다음은 Marcus라는 가상의 동료가 작성한 바로 그런 종류의 코드 줄을 대상으로 실행한 실제 결과입니다:

이 출력물은 편집되지 않은 것입니다. 놀리는 내용은 그날 오후에 모델이 생성해낸 결과물 그대로입니다.
사용해보기
Google AI Studio에서 무료 Gemini API 키가 필요합니다. 그 외에는 설치도 필요 없고, --dry-run을 사용하면 웹훅(webhook)도 필요 없습니다:
npx git-sorry config --set-key <GEMINI_API_KEY>
npx git-sorry blame src/auth.ts 42 --dry-run
--dry-run은 판결 내용을 터미널에 출력할 뿐 아무에게도 알리지 않습니다. 처음 시도할 때는 이 방식을 추천합니다. 왜냐하면 도구가 당신에 대해 뭐라고 말할지 아직 모르기 때문입니다.
다른 사람들을 참여시킬 준비가 되었다면:
git-sorry config --set-webhook <SLACK_OR_DISCORD_WEBHOOK_URL>
git-sorry blame src/auth.ts 42
운명을 거스르고 싶을 때 사용할 수 있는 두 가지 플래그가 있습니다. --roast는 해당 라인을 누가 작성했는지와 상관없이 작성자를 비난(roast)하며, --apology는 본인의 잘못이 아닐 때조차 당신이 굴욕적으로 사과(grovel)하게 만듭니다.
작동 원리
의도적으로 아주 작게 만들었습니다. 약 250줄의 TypeScript로 구성되어 있습니다.
git blame -L <n>,<n> --porcelain 명령은 작성자, 날짜, 그리고 소스 라인을 제공합니다. 이 정보가 로컬의 git config user.name과 비교되어 사과를 할지 비난을 할지 결정됩니다. 프롬프트(prompt)는 Gemini Flash로 전송되고, 응답은 boxen을 통해 박스 안에 담긴 후 당신의 웹훅(webhook)으로 게시됩니다.
제가 은밀하게 만족스러워하는 디테일 하나는 이렇습니다. Slack은 웹훅 페이로드(payload)의 text 필드를 읽고, Discord는 content 필드를 읽습니다. 두 필드를 모두 포함하는 바디(body)를 보내면, 어떤 서비스를 사용하는지 묻는 설정이나 분기 처리 없이도 동일한 단일 요청으로 두 서비스 모두에서 작동합니다.
네이티브 fetch가 요청을 처리하므로 HTTP 의존성이 없습니다. 설정은 소유자 전용 권한을 가진 일반 JSON 파일에 저장되므로 별도의 설정 라이브러리도 필요 없습니다. 호출에 실패하면 두 번 재시도하지만, API 키가 거부된 경우에는 즉시 실패합니다. 잘못된 키는 아무리 재시도해도 해결되지 않기 때문입니다.
왜 이런 일을 하는가
솔직한 답변은 농담으로 시작했다가 약간 유용한 도구가 되었다는 것입니다.
코드 리뷰에서의 비난 문화(Blame culture)는 대부분 어조(tone)의 문제입니다. "누가 이걸 썼지?"라고 말하는 메시지는 부정적인 인상을 줍니다. 반면 "마커스, 자기야, 논리 게이트(logic gates)가 중년의 위기를 표현할 수 있는지 몰랐네"라고 말하는 메시지는 왠지 괜찮게 받아들여지며, 결과적으로 해당 라인은 수정됩니다. 지적하는 행위를 팀 전체가 공유하는 하나의 유머(bit)로 바꾸면, 코드에 대한 실제 대화를 나누기가 훨씬 쉬워집니다.
또한 사람들이 평소에는 절대 하지 않는 git blame 출력 결과를 읽게 만들어 주기도 합니다.
소스 코드는 GitHub에 있으며, MIT 라이선스를 따릅니다. 풀 리퀘스트(Pull requests)는 언제나 환영하며, 특히 프롬프트에 새로운 성격(personality)을 부여하는 것을 환영합니다. 현재 프롬프트는 연극 평론가와 실망한 부모 사이 어딘가에 머물러 있는데, 그보다 더 낮은 단계(더 엄격하거나 실망한 상태)로 내려갈 여지가 많을 것 같습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기