GitHub Pull Request

간단한 Python 계산기 프로젝트로 Pull Request 실습

Python으로 작성된 간단한 계산기 프로젝트를 통해 GitHub Pull Request 생성 및 병합 과정을 단계별로 실습한다.

Engineering
Git
저자

Kwangmin Kim

공개

2023년 05월 05일

1 들어가며

GitHub Pull Request(PR)는 협업 개발 과정에서 코드 변경 사항을 제안하고 검토하는 핵심적인 기능이다. 이 글에서는 간단한 Python 계산기 프로젝트를 예제로 사용하여 Pull Request를 직접 만들고 병합하는 전체 과정을 단계별로 알아본다.

2 초기 저장소 코드 준비

먼저, 기본 기능을 가진 초기 코드를 준비한다. 이 코드가 원본 저장소의 main 브랜치에 존재한다고 가정한다.

2.1 main.py

def add(a, b):  
    """두 숫자를 더하는 함수"""  
    return a + b  

def subtract(a, b):  
    """두 숫자를 빼는 함수"""  
    return a - b  

def main():  
    print("간단한 계산기 프로그램")  
    print("1. 더하기")  
    print("2. 빼기")  
    
    choice = input("원하는 연산을 선택하세요 (1/2): ")  
    
    num1 = float(input("첫 번째 숫자: "))  
    num2 = float(input("두 번째 숫자: "))  
    
    if choice == '1':  
        print(f"{num1} + {num2} = {add(num1, num2)}")  
    elif choice == '2':  
        print(f"{num1} - {num2} = {subtract(num1, num2)}")  
    else:  
        print("잘못된 선택입니다.")  

if __name__ == "__main__":  
    main()  

2.2 README.md

# 간단한 계산기 프로젝트  

이 프로젝트는 GitHub Pull Request 연습을 위한 간단한 계산기 프로그램이다.  

## 기능  
- 두 숫자 더하기  
- 두 숫자 빼기  

## 사용 방법  
1. `main.py` 파일을 실행한다.  
2. 원하는 연산을 선택한다.  
3. 두 개의 숫자를 입력한다.  
4. 결과를 확인한다.  

3 Pull Request로 추가할 새 기능 코드

이제 새로운 기능을 추가할 차례이다. 새 브랜치를 생성하고, 기존 코드에 곱하기와 나누기 기능을 추가한다.

3.1 main.py (수정)

def add(a, b):  
    """두 숫자를 더하는 함수"""  
    return a + b  

def subtract(a, b):  
    """두 숫자를 빼는 함수"""  
    return a - b  

def multiply(a, b):  
    """두 숫자를 곱하는 함수"""  
    return a * b  

def divide(a, b):  
    """두 숫자를 나누는 함수"""  
    if b == 0:  
        return "0으로 나눌 수 없습니다."  
    return a / b  

def main():  
    print("간단한 계산기 프로그램")  
    print("1. 더하기")  
    print("2. 빼기")  
    print("3. 곱하기")  
    print("4. 나누기")  
    
    choice = input("원하는 연산을 선택하세요 (1/2/3/4): ")  
    
    num1 = float(input("첫 번째 숫자: "))  
    num2 = float(input("두 번째 숫자: "))  
    
    if choice == '1':  
        print(f"{num1} + {num2} = {add(num1, num2)}")  
    elif choice == '2':  
        print(f"{num1} - {num2} = {subtract(num1, num2)}")  
    elif choice == '3':  
        print(f"{num1} * {num2} = {multiply(num1, num2)}")  
    elif choice == '4':  
        print(f"{num1} / {num2} = {divide(num1, num2)}")  
    else:  
        print("잘못된 선택입니다.")  

if __name__ == "__main__":  
    main()  

3.2 README.md (수정)

# 간단한 계산기 프로젝트  

이 프로젝트는 GitHub Pull Request 연습을 위한 간단한 계산기 프로그램이다.  

## 기능  
- 두 숫자 더하기  
- 두 숫자 빼기  
- 두 숫자 곱하기  
- 두 숫자 나누기  

## 사용 방법  
1. `main.py` 파일을 실행한다.  
2. 원하는 연산을 선택한다.  
3. 두 개의 숫자를 입력한다.  
4. 결과를 확인한다.  

4 GitHub에서 Pull Request 생성 과정

다음은 GitHub에서 Pull Request를 생성하고 병합하는 단계이다.

  1. 저장소 생성 및 클론:

    • GitHub에 로그인하여 새 저장소(예: calculator-project)를 생성한다.
    • 생성한 저장소를 로컬 환경으로 클론한다:
      bash git clone https://github.com/your-username/calculator-project.git cd calculator-project
  2. 초기 코드 커밋 및 푸시:

    • 준비된 초기 main.pyREADME.md 파일을 저장소에 추가하고 커밋한 후, main 브랜치에 푸시한다:

          # 파일 생성 및 내용 작성 후  
          git add main.py README.md  
          git commit -m "초기 계산기 프로젝트: 더하기, 빼기 기능"  
          git push origin main  
          ```
      Enumerating objects: 4, done.
      Counting objects: 100% (4/4), done.
      Delta compression using up to 8 threads
      Compressing objects: 100% (3/3), done.
      Writing objects: 100% (4/4), 1.02 KiB | 1.02 MiB/s, done.
      Total 4 (delta 0), reused 0 (delta 0), pack-reused 0
      To https://github.com/your-username/calculator-project.git
       * [new branch]      main -> main
      ```

      [new branch] main -> main 은 원격에 main 브랜치가 처음 생성됐다는 메시지이다.

  3. 새 브랜치 생성 및 기능 추가 코드 커밋/푸시:

    • 새로운 기능(곱하기, 나누기)을 추가하기 위한 브랜치(예: feature-multiply-divide)를 생성하고 체크아웃한다:

          git checkout -b feature-multiply-divide  
          ```
      Switched to a new branch 'feature-multiply-divide'
      ```
    • 수정된 main.pyREADME.md 파일을 커밋하고, 새 브랜치를 원격 저장소에 푸시한다:

          # 파일 수정 후  
          git add main.py README.md  
          git commit -m "곱하기와 나누기 기능 추가"  
          ```
      [feature-multiply-divide 3a7f219] 곱하기와 나누기 기능 추가
       2 files changed, 16 insertions(+), 4 deletions(-)
      ```
          git push origin feature-multiply-divide  
          ```
      Enumerating objects: 7, done.
      Counting objects: 100% (7/7), done.
      Delta compression using up to 8 threads
      Compressing objects: 100% (4/4), done.
      Writing objects: 100% (4/4), 523 bytes | 523.00 KiB/s, done.
      Total 4 (delta 2), reused 0 (delta 0), pack-reused 0
      remote: Resolve any open comments. Push again to dismiss.
      remote:
      remote: Create a pull request for 'feature-multiply-divide' on GitHub by visiting:
      remote:      https://github.com/your-username/calculator-project/pull/new/feature-multiply-divide
      remote:
      To https://github.com/your-username/calculator-project.git
       * [new branch]      feature-multiply-divide -> feature-multiply-divide
      ```

      GitHub가 remote: 줄에서 PR 생성 링크를 직접 안내한다. 이 URL을 브라우저에서 열면 PR 작성 페이지로 바로 이동한다.

  4. GitHub에서 Pull Request 생성:

    • GitHub 웹사이트에서 해당 저장소로 이동한다.
    • feature-multiply-divide 브랜치가 푸시되면, 저장소 페이지 상단에 Compare & pull request 버튼이 나타난다. 이 버튼을 클릭한다.
    • PR 제목과 설명을 작성한다. 예를 들어:
      • 제목: “곱하기와 나누기 기능 추가”
      • 설명: “이 PR은 계산기에 곱하기와 나누기 기능을 추가한다.”
    • Create pull request 버튼을 클릭하여 PR을 생성한다.

    대안: gh CLI로 터미널에서 PR 생성하기
    GitHub CLI(gh)가 설치되어 있으면 웹 브라우저 없이 터미널에서 바로 PR을 만들 수 있다:

    gh pr create --title "곱하기와 나누기 기능 추가" \
                 --body "이 PR은 계산기에 곱하기와 나누기 기능을 추가한다." \
                 --base main \
                 --head feature-multiply-divide
    Creating pull request for feature-multiply-divide into main in your-username/calculator-project
    
    https://github.com/your-username/calculator-project/pull/1

    출력의 마지막 줄이 생성된 PR URL이다. gh pr view --web 으로 브라우저에서 해당 PR을 열 수도 있다.

  5. Pull Request 검토 및 병합:

    • 생성된 PR 페이지에서 변경된 코드 내용을 검토한다.
    • 필요하다면 코멘트를 남겨 피드백을 주고받는다.
    • 리뷰 결과는 크게 3가지이다:
      • Approved — 승인됨. 병합 가능.
      • Changes requested — 수정 요청. 리뷰어가 지적한 사항을 반영해 추가 커밋 후 재요청한다.
      • Commented — 의견만 남긴 것으로 승인/거절이 아님.
    • 코드 검토가 완료되고 모든 사항이 만족스러우면, Merge pull request 버튼을 클릭하여 변경 사항을 main 브랜치에 병합한다.
    • 병합 후, feature-multiply-divide 브랜치는 더 이상 필요 없으므로 삭제할 수 있다.
  6. 병합 후 로컬 정리:

    • GitHub 웹에서 원격 브랜치를 삭제했다면, 로컬에도 정리가 필요하다:

          git switch main
          git pull origin main
          ```
      Updating 3a7f219..9c1e4b2
      Fast-forward
       main.py  | 16 ++++++++++++
       README.md |  2 ++
       2 files changed, 18 insertions(+)
      ```

      PR이 병합된 커밋이 로컬 main에 Fast-forward로 합쳐진다.

          git branch -d feature-multiply-divide
          ```
      Deleted branch feature-multiply-divide (was 3a7f219).
      ```

      로컬 feature 브랜치도 삭제한다. 원격에서 삭제된 브랜치 목록을 로컬에서도 정리하려면 아래 명령을 사용한다:

          git fetch --prune
          ```
      From https://github.com/your-username/calculator-project
       - [deleted]         (none)     -> origin/feature-multiply-divide
      ```

      [deleted] 줄이 나타나면 원격에서 삭제된 브랜치의 추적 참조가 로컬에서도 제거된 것이다.

5 PR에서 자주 발생하는 상황과 해석

5.1 병합 충돌 (Merge Conflict)

PR 페이지에 아래 메시지가 나타나면 자동 병합이 불가능한 상태이다:

This branch has conflicts that must be resolved

main 브랜치와 feature 브랜치가 같은 파일의 같은 줄을 서로 다르게 수정한 경우 발생한다. 해결 방법:

git switch feature-multiply-divide
git fetch origin
git merge origin/main
Auto-merging main.py
CONFLICT (content): Merge conflict in main.py
Automatic merge failed; fix conflicts and then commit the result.

main.py를 열면 충돌 마커가 삽입되어 있다:

<<<<<<< HEAD
    print("3. 곱하기")
    print("4. 나누기")
=======
    print("3. 제곱")
>>>>>>> origin/main

<<<<<<< HEAD======= 사이가 현재 브랜치 코드, =======>>>>>>> origin/main 사이가 main에서 온 코드이다. 원하는 내용만 남기고 마커를 전부 삭제한 후 커밋한다:

git add main.py
git commit -m "merge: main과 충돌 해결"
git push origin feature-multiply-divide

푸시하면 PR 페이지의 충돌 경고가 사라지고 병합 버튼이 다시 활성화된다.

5.2 CI 검사 실패

저장소에 GitHub Actions 등 CI가 설정된 경우, PR 페이지 하단에 다음과 같은 상태가 표시된다:

Some checks were not successful
  × tests (ubuntu-latest) — Tests failed
  ✓ lint (ubuntu-latest) — Lint passed

tests 작업이 실패한 것이다. Details 링크를 눌러 로그를 확인하고, 코드를 수정한 뒤 다시 push하면 자동으로 CI가 재실행된다. CI를 통과해야만 Merge pull request 버튼이 활성화되는 경우가 많다.

5.3 이미 병합되거나 닫힌 PR에 push

PR이 Closed 상태인데 해당 브랜치에 push하면 PR이 자동 재개되지 않는다. 새 PR을 열어야 한다.

6 결론

PR 워크플로우는 브랜치 생성 → 커밋/푸시 → PR 생성 → 리뷰 → 병합 → 로컬 정리 순서로 진행된다. 각 단계에서 터미널 출력을 통해 진행 상황을 확인하고, 충돌이나 CI 실패 시 메시지를 해석해 정확한 조치를 취하는 것이 중요하다. gh CLI를 활용하면 브라우저 없이 터미널에서 전체 과정을 완결할 수 있다.

Subscribe

Enjoy this blog? Get notified of new posts by email: