GitHub Fork로 협업하기
한눈에 보기
원본 저장소에 쓰기 권한이 없어도 포크한 내 저장소에서 작업하고 풀 리퀘스트로 기여하는 오픈 소스 협업 방식을 다룬다. upstream 등록과 동기화, 공유 저장소 방식과의 비교까지 정리한다.
최종 업데이트 2026.09.17
포크(fork)는 다른 사람의 GitHub 저장소를 내 계정으로 통째로 복사해서 독립적으로 작업할 수 있게 만드는 기능이다. 원본 저장소에 쓰기 권한이 없어도 포크한 내 저장소에서 자유롭게 커밋하고, 그 변경을 풀 리퀘스트(Pull Request)로 원본에 제안할 수 있기 때문에 오픈 소스 협업의 표준 방식으로 자리 잡았다. 포크 협업의 핵심은 원본을 가리키는 upstream 원격을 등록하고 주기적으로 동기화하면서, 작업은 항상 별도의 브랜치에서 하는 것이다.
포크 모델은 왜 필요한가
같은 회사 팀원이라면 하나의 저장소를 공유하고 브랜치만 나눠 쓰면 된다. 하지만 오픈 소스 프로젝트는 불특정 다수가 기여하는 구조라서 모든 기여자에게 원본 저장소의 쓰기 권한을 줄 수 없다. 포크 모델은 이 문제를 해결한다. 기여자는 원본을 내 계정으로 복사한 뒤 내 저장소에서 마음껏 실험하고, 완성된 변경만 풀 리퀘스트로 제안한다. 원본 관리자(maintainer)는 제안된 변경을 리뷰하고 받아들일지 결정한다. 쓰기 권한이 관리자에게만 있으므로 원본의 품질과 보안이 지켜지고, 기여의 문턱은 낮아진다.
포크는 단순 복제(clone)와 다르다. 클론은 내 컴퓨터에만 존재하는 로컬 복사본이지만, 포크는 GitHub 서버에 생기는 원격 저장소이고 원본과의 관계가 플랫폼 차원에서 추적되므로 저장소 사이의 풀 리퀘스트가 가능하다.
포크에서 풀 리퀘스트까지 실제 절차
전형적인 기여 흐름은 다음과 같다. 먼저 GitHub 웹에서 원본 저장소의 Fork 버튼을 눌러 내 계정에 복사본을 만들고, 그 복사본을 로컬로 클론한다. 이때 원격 이름은 관례적으로 내 포크가 origin, 원본이 upstream이 된다.
# 1. 내 포크를 클론한다
git clone https://github.com/<내계정>/<저장소>.git
cd <저장소>
# 2. 원본 저장소를 upstream으로 등록한다
git remote add upstream https://github.com/<원본계정>/<저장소>.git
git remote -v
작업은 반드시 main이 아닌 주제 브랜치(topic branch)에서 한다. main을 깨끗하게 유지해야 원본과의 동기화가 쉬워지고, 브랜치 하나가 풀 리퀘스트 하나에 대응해서 리뷰가 깔끔해진다.
# 3. 브랜치를 만들어 작업한다
git switch -c fix/<이슈-요약>
git add .
git commit -m "fix: 널 입력 시 예외 처리 추가"
# 4. 내 포크로 푸시하고 PR을 연다
git push -u origin fix/<이슈-요약>
푸시한 뒤 GitHub에서 내 포크의 브랜치를 원본의 기본 브랜치로 향하는 풀 리퀘스트로 연다. 리뷰에서 수정 요청을 받으면 같은 브랜치에 커밋을 추가해 푸시하기만 하면 PR에 자동 반영된다. 대부분의 프로젝트는 CONTRIBUTING 문서에 커밋 컨벤션과 테스트 요건을 정해 두므로 PR 전에 확인해야 한다. 변경 범위는 작게 유지하는 것이 좋다. 관리자 입장에서 수백 줄짜리 PR보다 목적이 하나인 작은 PR이 리뷰하기 쉽고, 그만큼 병합될 확률도 높아진다. 큰 작업이라면 먼저 이슈로 방향을 논의한 뒤 나눠서 제안하는 것이 예의이자 전략이다.
원본 저장소와 동기화하기
내가 작업하는 동안에도 원본에는 다른 사람들의 변경이 계속 병합된다. 포크는 자동으로 갱신되지 않으므로 upstream에서 직접 가져와야 한다. 동기화를 게을리하면 풀 리퀘스트 시점에 대규모 충돌을 만나게 된다.
# 원본의 최신 변경을 가져와 내 main에 반영한다
git fetch upstream
git switch main
git merge --ff-only upstream/main
git push origin main
# 작업 중인 브랜치를 최신 main 위로 옮긴다
git switch fix/<이슈-요약>
git rebase main
리베이스(rebase) 후에는 커밋 해시가 바뀌므로 git push --force-with-lease로 내 포크에 강제 푸시해야 한다. 내 포크의 내 브랜치이므로 강제 푸시가 허용되지만, --force 대신 --force-with-lease를 써서 예상치 못한 덮어쓰기를 방지하는 습관이 좋다. GitHub 웹 화면의 Sync fork 버튼으로 포크의 main을 갱신하는 방법도 있다.
포크 방식과 공유 저장소 방식 비교
| 항목 | 포크 방식 | 공유 저장소 방식 |
|---|---|---|
| 쓰기 권한 | 원본에는 관리자만, 기여자는 자기 포크에만 가진다 | 팀원 전원이 하나의 저장소에 가진다 |
| PR 방향 | 포크의 브랜치에서 원본 브랜치로 | 같은 저장소의 브랜치 사이 |
| 동기화 부담 | upstream 동기화를 직접 챙겨야 한다 | git pull만으로 충분하다 |
| 적합한 환경 | 오픈 소스, 외부 기여자, 권한 분리가 필요한 조직 | 서로 신뢰하는 소규모 팀 |
| CI 비밀값 | 포크에서 온 PR에는 비밀값 접근을 제한하는 것이 보통이다 | 저장소 설정을 그대로 쓴다 |
사내 협업이라도 저장소 권한을 엄격히 분리하고 싶거나 기여자가 많은 플랫폼성 코드라면 포크 모델을 쓰기도 한다. 반대로 매일 함께 일하는 팀이라면 공유 저장소에 브랜치 보호 규칙을 거는 편이 오버헤드가 적다.
면접에서 이렇게 물어본다
- 포크와 클론의 차이를 설명하고, 오픈 소스 협업에서 포크가 필요한 이유를 말해 보라.
- origin과 upstream 원격은 각각 무엇을 가리키며, 포크를 원본과 동기화하는 절차를 설명해 보라.
- 포크에서 작업할 때 main 브랜치를 직접 쓰지 않고 주제 브랜치를 만드는 이유는 무엇인가.
- 리베이스 후 강제 푸시가 필요한 이유와 --force-with-lease를 권장하는 이유를 설명해 보라.
- 사내 프로젝트에서 포크 방식과 공유 저장소 방식 중 무엇을 택할지, 판단 기준은 무엇인가.
Git과 협업에서 같이 읽기
- Node.js 프로젝트의 Git 협업node_modules와 .env는 제외하고 잠금 파일은 커밋하는 이유부터 npm ci, 기능 브랜치와 풀 리퀘스트 리뷰, 병합 전략까지 Node.js 팀의 표준 Git 협업 방식을 정리한다.
- Git 커밋 메시지 컨벤션커밋 메시지의 형식과 어휘를 통일하는 규칙을 다룬다. 제목, 본문, 꼬리말 구조와 컨벤셔널 커밋 타입 체계, commitlint와 husky로 컨벤션을 강제하는 방법까지 정리한다.
- Git Flow, GitHub Flow, GitLab Flow 비교릴리스 중심의 Git Flow, 지속 배포를 위한 GitHub Flow, 환경 브랜치로 배포 단계를 표현하는 GitLab Flow를 비교하고 배포 주기와 제품 형태에 따른 선택 기준을 정리한다.
- GitHub 저장소 미러링모든 브랜치와 태그를 다른 원격 저장소에 그대로 복제하는 미러링을 다룬다. git clone --mirror와 push --mirror 절차, 동기화 자동화, LFS와 메타데이터 관련 주의사항을 정리한다.
이 개념, 내 코드에서는 어떻게 물어볼까요
데브핏(DevFit)에 채용공고 URL을 붙여 넣고 레포지토리를 연결하면, 내가 쓴 커밋에서 예상 질문과 어필 포인트를 만듭니다. 하루 10회까지 무료입니다. 합불 판정이나 지원자 랭킹은 만들지 않고, 최종 판단은 사람이 합니다.
공고 넣고 시작하기