이 문서는 팀 프로젝트에서 일관된 Git 협업 방식을 유지하기 위한 규칙을 정의합니다.
모든 팀원은 아래 규칙을 기준으로 Issue 생성, 브랜치 작업, 커밋, Pull Request, 코드 리뷰, 충돌 해결을 진행합니다.
우리 팀은 GitHub Flow를 사용합니다.
main브랜치는 항상 정상적으로 동작하는 상태를 유지합니다.main브랜치에는 직접 push하지 않습니다.- 모든 변경 사항은 Pull Request를 통해 병합합니다.
- Pull Request는 최소 1명의 승인을 받은 후 병합합니다.
모든 작업은 main에서 새로운 feature 브랜치를 생성하여 진행합니다.
main
└─ feature/...
작업이 완료되면 Pull Request를 생성하고, 코드 리뷰와 승인을 거친 후 main에 병합합니다.
GitHub Flow는 브랜치 구조가 단순해 팀원들이 각자의 작업을 독립적으로 진행하기 쉽습니다. Pull Request와 코드 리뷰를 중심으로 작업하기 때문에 변경 사항을 확인하고 협의한 뒤 안전하게 병합할 수 있습니다. 이번 프로젝트의 핵심 목표인 Issue, Branch, PR, Review 기반 협업을 연습하기에 적합합니다.
브랜치 이름은 다음 형식을 사용합니다.
feature/<name>-<topic>
예시:
feature/jeongbeen-collaboration-guide
feature/minwoo-conflict-resolution
feature/taedong-troubleshooting-log
- 모두 소문자를 사용합니다.
- 단어 구분은
-를 사용합니다. - 브랜치 이름만 보고 작업 내용을 어느 정도 유추할 수 있도록 작성합니다.
- 한 브랜치에서는 하나의 작업 단위만 처리하는 것을 권장합니다.
feature/taedong-string-utils
feature/jeongbeen-add-contributing-guide
feature/minwoo-input-validation
feature/test
feature/work
feature/final
feature/update
모든 작업은 가능하면 Issue를 먼저 생성한 후 진행합니다.
Issue에는 최소한 다음 내용을 작성합니다.
- 작업 내용
- 완료 조건
- 참고 사항
예시:
[Feature] 문자열 뒤집기 함수 구현
## 작업 내용
- 입력받은 문자열을 뒤집어 반환하는 함수를 구현합니다.
## 완료 조건
- reverse_string 함수 구현
- 정상 입력 확인
- 사용 예시 작성작업 브랜치와 Pull Request는 해당 Issue를 기준으로 생성합니다.
커밋 메시지는 다음 형식을 사용합니다.
<type>: <subject>
예시:
feat: add string reverse utility
fix: handle empty string input
docs: add pull request guidelines
refactor: simplify validation logic
| Type | 설명 |
|---|---|
feat |
새로운 기능 추가 |
fix |
버그 수정 |
docs |
문서 수정 |
refactor |
기능 변경 없이 코드 구조 개선 |
test |
테스트 코드 추가 또는 수정 |
chore |
기타 설정 및 유지보수 작업 |
- 변경 대상과 내용을 알 수 있도록 작성합니다.
- 지나치게 긴 문장은 사용하지 않습니다.
- 하나의 커밋에는 가능한 한 하나의 목적만 포함합니다.
- 변경 내용을 구체적으로 표현합니다.
feat: add string length utility
fix: prevent error on empty input
docs: document branch naming convention
refactor: extract common validation logic
다음과 같이 변경 내용을 유추하기 어려운 메시지는 사용하지 않습니다.
update
fix
temp
wip
final
edit file
bug fix
모든 feature 브랜치는 Pull Request를 통해 main에 병합합니다.
작업을 완료한 후 다음 사항을 확인합니다.
- 작업과 관련된 Issue가 존재하는지 확인합니다.
- 로컬에서 변경 사항이 정상적으로 동작하는지 확인합니다.
- 불필요한 파일이 포함되지 않았는지 확인합니다.
- 의미 있는 커밋 메시지를 사용했는지 확인합니다.
PR 제목만 보고 변경 내용을 알 수 있도록 작성합니다.
예시:
feat: add string utility functions
docs: add contributing guide
fix: handle invalid numeric input
모든 PR에는 최소한 다음 내용을 포함합니다.
Closes #<issue-number>
예시:
Closes #3
무엇을 변경했는지 작성합니다.
왜 해당 변경이 필요한지 작성합니다.
어떤 방법으로 정상 동작을 확인했는지 작성합니다.
예시:
## 연결 이슈
- Closes #3
## 변경 사항 (What)
- 문자열을 뒤집는 reverse_string 함수를 추가했습니다.
- 문자열 길이를 반환하는 string_length 함수를 추가했습니다.
## 변경 이유 (Why)
- 문자열 관련 기본 유틸리티 기능을 제공하기 위해 추가했습니다.
## 테스트/검증 방법 (How)
- Python에서 각 함수를 직접 실행했습니다.
- 일반 문자열과 빈 문자열 입력을 확인했습니다.PR은 아래 조건을 충족한 경우에만 main에 병합합니다.
- 최소 1명의 팀원이 Approve 했을 것
- 실질적인 코드 리뷰가 최소 1개 이상 존재할 것
- 리뷰어와 작성자 사이에 최소 1회 이상 상호작용이 있을 것
- 필요한 수정 사항이 반영되었을 것
- 미해결 리뷰 대화가 없을 것
- 충돌이 발생한 경우 충돌을 해결했을 것
코드 리뷰는 단순히 오류를 찾는 과정이 아니라 팀원 간에 구현 의도를 공유하고 더 나은 방법을 찾는 과정으로 진행합니다.
각 PR에는 단순한 LGTM, 좋아요, 확인했습니다만 남기지 않습니다.
최소 1개 이상의 실질적인 의견을 작성합니다.
다음과 같은 리뷰를 권장합니다.
- 특정 코드 또는 파일에 대한 질문
- 구현 방식에 대한 대안 제안
- 예외 상황에 대한 질문
- 버그 가능성 지적
- 가독성 개선 제안
- 변수명 또는 함수명 개선 제안
- 중복 코드 개선 제안
- 유지보수 관점에서의 의견
빈 문자열이 들어왔을 때도 현재 함수가 정상 동작하는지 확인하면 좋을 것 같습니다.
이 조건문을 별도 함수로 분리하면 함수의 역할이 더 명확해질 것 같습니다.
현재 변수명 value만으로는 의미를 파악하기 어려운데 input_number처럼 구체적으로 작성하는 것은 어떨까요?
LGTM
좋아요
확인했습니다
수고하셨습니다
리뷰할 때는 일반적인 입력뿐 아니라 빈 값이나 잘못된 입력에서 어떤 동작을 하는지도 확인합니다.
1. 빈 문자열 입력
이 함수에 빈 문자열
""이 들어오면 어떤 결과를 반환하나요? 빈 문자열을 그대로 반환할지, 잘못된 입력으로 처리할지 기준을 정하고 해당 입력의 테스트를 추가하면 좋겠습니다.
2. 공백만 있는 문자열 입력
현재 빈 문자열은 검사하지만
" "처럼 공백만 입력된 경우도 허용되는 것으로 보입니다. 공백만 있는 값을 유효한 입력으로 볼지 확인하고, 허용하지 않는다면strip()을 적용한 뒤 검사하는 것은 어떨까요?
3. None 입력
text.strip()을 호출하는 부분에서text가None이면AttributeError가 발생할 수 있습니다. 이 함수가None을 받을 가능성이 있다면, 먼저 입력을 검사하고 명확한 예외 메시지를 제공하는 것은 어떨까요?
4. 빈 리스트 입력
첫 번째 원소에 접근하는
items[0]부분은 빈 리스트가 들어오면IndexError가 발생합니다. 빈 리스트를 받았을 때의 반환값이나 예외 처리 기준을 정하고 테스트를 추가하면 좋겠습니다.
5. 숫자 변환 실패
int(value)에서"abc"처럼 숫자로 변환할 수 없는 값이 들어오면ValueError가 발생합니다. 이 예외를 호출한 쪽에 전달할지, 여기서 처리할지 의도를 설명해주시면 좋겠습니다.
리뷰에서는 예외 처리를 무조건 추가하도록 요구하기보다, 함수가 허용하는 입력 범위와 잘못된 입력의 처리 기준을 먼저 확인합니다.
위와 같은 표현은 추가적인 실질 리뷰와 함께 사용하는 것은 가능하지만, 이것만 작성해서는 안 됩니다.
PR 작성자는 리뷰 코멘트를 확인한 후 다음 중 하나의 방식으로 반드시 상호작용합니다.
코드를 수정한 뒤 새로운 커밋을 추가합니다.
예시:
fix: handle whitespace-only input
그리고 리뷰 댓글에 답변합니다.
말씀해주신 내용을 반영해서 공백 문자열 처리 로직을 추가했습니다.
왜 현재 구현을 유지하는 것이 적절하다고 판단했는지 설명합니다.
예시:
현재 함수의 역할을 단순 문자열 변환으로 제한하기로 팀에서 합의했기 때문에 해당 예외 처리는 별도 함수에서 처리하겠습니다.
리뷰에 아무런 답변 없이 PR을 병합하지 않습니다.
각 팀원은 다음 조건을 충족해야 합니다.
- 본인 PR을 제외하고 최소 2개의 PR에 리뷰를 작성합니다.
- 최소 1개의 본인 PR에서 리뷰 의견을 반영한 경험을 남깁니다.
- 리뷰어와 작성자 사이에 최소 1회 이상의 상호작용을 기록으로 남깁니다.
충돌이 발생하면 임의로 한쪽 코드를 삭제하거나 바로 병합하지 않습니다.
다음 순서로 해결합니다.
- 충돌이 발생한 브랜치와 파일을 확인합니다.
- 어떤 변경 사항끼리 충돌했는지 확인합니다.
- 관련 작업을 수행한 팀원에게 충돌 사실을 공유합니다.
- 어떤 변경 사항을 유지할지 팀원과 협의합니다.
- 충돌 마커를 확인하고 직접 수정합니다.
- 충돌 마커가 모두 제거되었는지 확인합니다.
- 수정된 결과가 정상적으로 동작하는지 확인합니다. 문서일 경우 링크/목차/마커 잔존 여부를 확인하고, 코드면 실행·테스트를 수행합니다.
- 충돌 해결 내용을 커밋합니다.
docs/conflict-resolution.md에 해결 과정을 기록합니다.
Git 충돌 발생 시 다음과 같은 형태가 나타납니다.
<<<<<<< HEAD
현재 브랜치의 내용
=======
병합하려는 브랜치의 내용
>>>>>>> feature/...
각 영역은 다음을 의미합니다.
<<<<<<< HEAD: 현재 브랜치의 내용=======: 두 변경 사항의 구분선>>>>>>>: 병합하려는 브랜치의 내용
최종 코드를 결정한 후 해당 충돌 마커는 모두 삭제해야 합니다.
- 충돌 내용을 이해하지 못한 상태에서 무조건 한쪽 변경 사항을 선택하지 않습니다.
- 다른 팀원의 코드를 임의로 삭제하지 않습니다.
- 충돌 해결 후 반드시 실행 또는 테스트를 통해 정상 동작을 확인합니다.
- 충돌 해결 과정은 재현할 수 있도록 기록합니다.
- 팀 합의 없이 공유 브랜치에서 강제 push하지 않습니다.
Git 작업 중 문제가 발생하면 상황에 따라 적절한 명령을 사용합니다.
최근 커밋의 메시지나 내용을 수정할 때 사용합니다.
공유된 커밋에 무분별하게 사용하지 않습니다.
아직 원격에 push하지 않은 로컬 커밋을 취소하면서 변경 사항은 유지하고 싶을 때 사용합니다.
공유된 원격 커밋을 되돌리는 용도로 사용하지 않습니다.
이미 원격에 공유된 커밋을 안전하게 취소할 때 사용합니다.
기존 히스토리를 삭제하지 않고 되돌리는 새로운 커밋을 생성합니다.
작업이 완료되지 않은 상태에서 다른 브랜치로 이동해야 할 때 현재 변경 사항을 임시 보관하는 용도로 사용합니다.
작업을 다시 복원할 때는 다음과 같이 사용합니다.
git stash pop실습 과정과 결과는 docs/troubleshooting-log.md에 기록합니다.
다음 작업은 팀 합의 없이 수행하지 않습니다.
main브랜치 직접 push- 공유 브랜치에서 강제 push
- 공유된 커밋에 대한 임의의 history rewrite
- 다른 팀원의 브랜치 삭제
- 리뷰 없이 PR 병합
- 충돌 내용을 확인하지 않고 한쪽 변경 사항 삭제
- Issue 없이 추적하기 어려운 작업 진행
- 의미 없는 커밋 메시지 사용
특히 다음 명령은 공유 브랜치에서 사용하지 않습니다.
git push --force
git reset --hard
git rebasegit rebase는 공유 브랜치에서는 금지합니다. 다른 팀원의 히스토리와 충돌할 수 있기 때문입니다.
개인 feature 브랜치에서 히스토리를 정리할 목적으로는, 팀 합의 후 사용할 수 있습니다.
git push --force와 git reset --hard도 공유 브랜치에서는 사용하지 않으며, 필요한 경우 반드시 팀원과 먼저 협의합니다.
모든 기능 작업은 아래 흐름을 따르는 것을 원칙으로 합니다.
Issue 생성
↓
feature 브랜치 생성
↓
작업
↓
Commit
↓
Push
↓
Pull Request 생성
↓
Code Review
↓
리뷰 반영
↓
Approve
↓
Merge
↓
Issue Close
- 충돌 해결 기록:
docs/conflict-resolution.md - Git 문제 해결 기록:
docs/troubleshooting-log.md - 제출물 인덱스:
SUBMISSION.md