Community코딩 & 개발github.com

roselletabuena/git-atomic-commit

작업 트리의 변경 사항을 분할하여 원자적이고 단일 목적의 git 커밋을 만듭니다. 변경 사항을 조사하고, 논리적 단위로 그룹화하고, 각 커밋이 빌드되도록 순서를 정하며, 저장소의 기존 스타일에 맞는 메시지를 작성합니다.

git-atomic-commit란 무엇인가요?

이 스킬은 작업 트리의 변경 사항을 논리적 단위로 분할하여 원자적 커밋을 만드는 방법을 제공합니다. 사용자가 커밋을 요청하거나, 여러 논리적 변경 사항이 있을 때, 커밋을 분할, 재정렬, 재구성 또는 정리해야 할 때 사용합니다. 또한 커밋 메시지에 "그리고"라는 단어가 필요하거나 파일의 일부만 스테이징해야 할 때도 유용합니다. 이 스킬은 git add -p나 git add -i와 같은 대화형 명령이 비대화형 환경에서 조용히 실패하는 문제를 해결하는 기술을 제공합니다. 주요 기능으로는 변경 사항 조사, 논리적 단위 그룹화, 커밋 순서 지정, 부분 스테이징, 저장소 스타일에 맞는 커밋 메시지 작성 등이 있습니다. 이 스킬은 Claude Code, Cursor, Codex 등 다양한 AI 에이전트에서 사용할 수 있으며, SKILL.md 문서에 자세한 워크플로우와 예방 조치가 설명되어 있습니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/roselletabuena/skills/tree/HEAD/plugins/git-workflows/skills/git-atomic-commit

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

원자적 커밋

원자적 커밋은 정확히 하나의 논리적 변경 사항을 포함합니다. 그 대가는 단순히 정리정돈이 아닙니다. 커밋이 혼합될 때 팀이 잃게 되는 세 가지 구체적인 능력이 있습니다:

  • 리뷰: 리뷰어는 하나의 아이디어를 머릿속에 담고 판단할 수 있습니다.
  • 되돌리기: 잘못된 변경 사항을 좋은 변경 사항과 함께 되돌리지 않고 제거할 수 있습니다.
  • 이분 탐색: git bisect는 버그를 도입한 커밋을 찾아낼 수 있습니다. 각 커밋이 하나의 변경 사항이고 그리고 각 커밋이 빌드되어야만 작동합니다.

마지막 조항이 가장 자주 놓치는 부분입니다. 원자적이라는 것은 "가능한 한 작게"가 아니라 "하나의 완전한 변경"을 의미합니다. 함수를 필요한 호출 지점과 분리하는 커밋은 더 작지만 원자적이지 않습니다. 트리가 깨지기 때문입니다.

워크플로우

1. 스테이징 전에 먼저 조사하세요

트리를 어떻게 나눌지 결정하기 전에 전체 트리를 이해하세요:

git status --porcelain      # 추적되지 않은 파일을 포함한 모든 경로
git diff                    # 스테이징되지 않은 변경 사항
git diff --cached           # 이미 스테이징된 변경 사항
git log --oneline -15       # HEAD의 위치와 로컬 스타일

git add -A와 git commit -a를 첫 번째 동작으로 사용하지 마세요. 이것들은 혼합된 트리를 혼합된 커밋으로 만드는 방법이며, 한 번 커밋되면 분할하는 것이 사전에 분할하는 것보다 훨씬 더 많은 작업이 필요합니다. 또한 커밋해서는 안 되는 변경 사항(빌드 출력, .env 파일, 디버그 출력, 잘못된 에디터 설정)이 있는지 확인하세요.

2. 변경 사항을 논리적 단위로 그룹화하세요

가장 신뢰할 수 있는 테스트는 언어적입니다: 커밋 제목을 초안으로 작성해보고, 정확성을 위해 "그리고"가 필요하다면 두 개 이상의 커밋이 있는 것입니다. "로그인 리디렉션 수정 및 lodash 업데이트"는 두 가지입니다. 리뷰어의 질문이 두 번째 테스트입니다: 변경 사항 X를 이해해야 변경 사항 Y를 판단할 수 있습니까? 그렇지 않다면 변경 사항은 독립적이므로 분리되어야 합니다.

분리:

분리할 사항이유
서식/공백 vs. 논리서식 변경은 실제 세 줄의 변경 사항을 400줄의 노이즈 속에 묻어버립니다. 이것은 가장 가치 있는 분할입니다.
이름 변경 vs. 동작 변경같은 이유 - 이름 변경은 모든 것을 건드려 중요한 한 줄을 숨깁니다.
의존성 업데이트 vs. 코드각각 고유한 되돌리기 스토리가 필요합니다.
관련 없는 버그 수정독립적인 되돌리기, 독립적인 이분 탐색.
리팩토링 vs. 이를 사용하는 기능리뷰어가 리팩토링이 동작을 보존하는지 확인할 수 있습니다.

함께 유지:

하나의 커밋에 유지할 사항이유
변경 사항과 그 테스트하나의 논리적 단위입니다. 출시되지 않은 코드에 대한 테스트, 또는 테스트 없는 코드는 각각 반쪽짜리 변경 사항입니다.
이름 변경과 모든 호출 지점분할하면 트리가 깨집니다 - 원자성의 반대입니다.
시그니처 변경과 호출자동일.
변경 사항과 이를 설명하는 문서/체인지로그동일한 결정을 설명하므로 함께 되돌려야 합니다.

3. 모든 커밋이 빌드되도록 순서를 정하세요

각 커밋이 트리를 작동 가능한 상태로 유지해야 하므로 순서가 중요합니다. 기반이 되는 것을 먼저 배치하고 그것을 사용하는 것을 나중에 배치하세요: 헬퍼를 호출하는 코드보다 먼저 추가하고, 기능보다 먼저 리팩토링을 수행하고, 쿼리보다 먼저 스키마를 적용하세요. 두 그룹이 상호 의존적이라면 실제로는 하나의 커밋이라는 신호입니다.

4. 각 그룹을 스테이징하세요

가장 덜 침습적인 기술을 사용하세요. 더 간단한 방법이 분할을 표현할 수 없을 때만 상위 레벨로 올라가세요:

레벨 1 - 전체 파일 스테이징. 대부분의 실제 분할을 처리합니다. 논리적 변경 사항은 일반적으로 다른 파일에 있기 때문입니다:

git add src/auth.py tests/test_auth.py
git commit -m "..."

레벨 2 - 전체 파일 따로 보관 트리에 실수로 커밋하기 쉬운 내용이 있을 때 사용합니다:

git stash push -- requirements.txt    # 잠시 치워둠
# ... 나머지를 커밋 ...
git stash pop                         # 다시 가져옴

레벨 3 - 단일 파일 내 변경 사항 분할. 한 파일에 실제로 두 개의 논리적 변경 사항이 있을 때만 필요합니다. 작업이 까다롭고 미묘하게 잘못되기 쉬우므로 시도하기 전에 references/splitting-one-file.md를 읽으세요.

git add -p는 비대화형 환경에서 작동하지 않으며, 조용히 실패합니다. 첫 번째 헝크를 출력하고, stdin에서 EOF에 도달하고, 아무것도 스테이징하지 않고, 종료 코드 0으로 종료됩니다. 여기서 성공적인 종료 코드는 아무 일도 일어나지 않았음을 의미합니다. git add -i, git commit -p 및 git checkout -p에도 동일하게 적용됩니다. 실패가 성공처럼 보이기 때문에, 일반적으로 비어 있거나 의도한 변경 사항이 누락된 커밋이 발생합니다. 따라서 참조 파일의 기술을 사용하고, 커밋하기 전에 git diff --cached로 인덱스를 확인하세요.

5. 저장소의 스타일에 맞게 각 메시지를 작성하세요

규칙을 가져오기보다는 주변 기록과 일치시키세요. 일반적인 산문 제목 로그에 feat: 접두사를 붙이는 것은 노이즈이며, 기록을 두 개의 프로젝트처럼 보이게 만듭니다. 먼저 로컬 스타일을 읽으세요:

git log --no-merges --format='%s' -n 30               # 제목 스타일
git log --no-merges -n 10 --format='%n---%n%s%n%b'    # 본문 사용 여부

찾아야 할 것: type: 또는 type(scope): 접두사 (Conventional Commits), [PROJ-123]와 같은 티켓 접두사, 대문자 사용, 명령형 vs. 과거형 ("Add" vs. "Added"), 일반적인 제목 길이, 본문 사용 여부. 발견한 것을 채택하세요. Conventional Commits은 로그가 이미 사용 중이거나 저장소에 기록이 없고 사용자가 선호하는 방식이 없을 때만 좋은 기본값입니다.

어떤 로컬 스타일이든, 제목은 무엇이 변경되었는지 말해야 하고, 본문(기록이 본문을 사용하는 경우)은 왜 변경되었는지 말해야 합니다. diff가 이미 무엇을 보여주기 때문입니다. 저장소에 CONTRIBUTING.md나 commit-msg 훅이 있다면 로그 추론보다 우선합니다.

규칙을 맞추는 것이 데이터를 만들어내는 것을 의미하지는 않습니다. 로컬 스타일에 티켓이나 이슈 참조(예: [PROJ-123], Fixes #456)가 포함되어 있는데 실제 식별자를 제공받지 못했다면 추측하지 말고 로그에서 본 번호를 계속 사용하지 마세요. 그럴듯해 보이는 [PROJ-124]는 접두사가 없는 것보다 더 나쁩니다: 영구적이고, 실제 추적 가능성처럼 읽히며, 아마도 다른 사람의 관련 없는 티켓을 가리킬 것입니다. 참조를 생략하고 나머지 스타일은 맞추되, 답변에 ID가 없으므로 사용자가 제공할 수 있도록 언급하세요. 커밋은 아직 푸시되지 않았고 수정하기 쉽습니다. 사용자가 물어볼 수 있다면 번호를 요청하세요.

6. 돌려주기 전에 확인하세요

git log --oneline -n <count>     # 만든 커밋의 형태
git status --porcelain           # 남은 것이 무엇인지

각 커밋이 자신의 변경 사항만 포함하는지 (git show --stat <sha>) 확인하고, 아무것도 바닥에 떨어지지 않았는지 확인하세요. 의도적으로 커밋되지 않은 변경 사항이 남아 있다면 명시적으로 말하세요. 사용자가 깨끗하다고 생각했지만 실제로는 그렇지 않은 트리는 최악의 결과입니다. 나중에 발견하고 그것이 의도적인지 알 수 없기 때문입니다.

안전장치

  • 커밋 방법을 결정할 뿐, 커밋 여부를 결정하지는 않습니다. 사용자가 커밋을 요청하지 않았다면 이 스킬은 커밋을 만드는 것이 적절하지 않으며, 푸시를 암시하지 않습니다.
  • 분할을 쉽게 하기 위해 작업을 절대 버리지 마세요. git checkout -- <file>, git reset --hard 및 git stash drop은 아직 커밋되지 않은 작업을 파괴하며 복구할 수 없습니다. 기술이 이러한 것 중 하나를 필요로 한다면 먼저 내용을 백업하고 실행하기 전에 백업이 존재하는지 확인하세요.
  • 공개된 히스토리를 정리하기 위해 다시 쓰지 마세요. 이미 푸시된 커밋을 분할하는 것은 다른 사람이 가져갔을 수 있는 히스토리를 다시 쓰는 강제 푸시를 의미합니다. 먼저 물어보세요.
  • 철저해 보이기 위해 과도하게 분할하지 마세요. 각각 빌드를 깨는 세 개의 커밋은 작동하는 하나의 커밋보다 나쁩니다. 의심스러울 때는 각 커밋이 기능하도록 유지하는 그룹화를 선호하세요.
  • 트리에 하나의 논리적 변경 사항만 있다면 하나로 커밋하세요. 모든 트리가 분할을 필요로 하는 것은 아니며, 그렇게 말하는 것도 좋은 결과입니다.

Individual skills in this repo

This repo contains 2 individual skills — each has its own dedicated page.

관련 스킬