원본저장소를 복사해서 다른 원격저장소를 만든다.

커밋을 올릴 권한이 없는 쪽에서 코드를 추가하고 싶은 경우 원격저장소를 복사해서 사용하게 된다. 남의 원격저장소를 내 계정의 원격저장소로 복사해오는 명령어를 **포크(fork)**라고 한다.

원본저장소에 커밋을 푸시할 수 있는 권한은 소유자인 본인뿐이다. 협력자로 등록하고 싶을 경우 Setting-Collaborators 페이지에 들어가서 등록하려는 유저를 찾고, 'Add collaborator'를 클릭하며 된다.

협력자가 늘어날 수록 원본저장소를 관리하기 힘들어진다. 협력자가 원본저장소에 직접 푸시하기 때문이다. 동시에 개발자들은 오픈소스에 참여하고 싶어하지만 직접 푸시하기에 부담이 있다. 이럴 때에 대안이 되는 방법이 'Pull Request'다. 개발자는 원본저장소를 자신의 계정에 복사(fork)해서 원격장소를 생성하고 이곳에, 커밋을 올린 후 원본저장소의 소유자에게 병합요청을 하면 원본저장소의 소유자는 개발자의 병합 요청을 검토해서 원본저장소에 반영한다.

Name 의의 편리한 점 불편한 점
브랜치 하나의 원본저장소에 분기를 나눈다. 하나의 원본저장소에서 코드 커밋 이력을 편하게 볼 수 있다. 다수의 사용자가 다수의 브랜치를 만들면 관리하기 힘들다.
포크 여러 원격저장소를 만들어 분기를 나눈다. 원본저장소에 영향을 미치지 않으므로 원격저장소에서 마음것 코드를 수정할 수 있다. 이력을 보려면 따로 주소를 추가해야한다.

묵은 커밋을 새 커밋으로 이력 조작하기 : Rebase

A의 원본저장소를 B가 Fork했을 때 A와 B가 같은 코드를 고치고 병합하는 상황에서 충돌이 난다고 가정해보자. B가 '좋아요 기능 추가'커밋을 만들고 Pull Request하여 A가 Merge Pull Request한 상황이다.

B는 '좋아요 기능 추가' 커밋 위에 '찜하기 기능 추가' 커밋을 만들고 원격저장소에 푸시했다.

A는 B가 수정했던 파일을 수정해서 '싫어요 기능 추가'라는 커밋을 만들었다. 이 경우 A와 B가 같은 부분을 수정했기 때문에 병합하면 충돌이 일어난다. A는 본인이 만든 커밋을 푸시한다.

A는 다른 파일을 수정하여 '개발자 목록에 너구리 추가'라는 커밋을 하나 더 만들고 푸시한다.

여기서 B는 A가 어떤 파일을 수정했는지 알지 못한다. B는 Pull Request를 보내려고 한다.

B가 Pull Request를 보내려고 하면 GitHub 화면에 "Can't automatically merge"라는 메세지가 표시된다. 이는 코드 충돌이 일어났다는 메세지이다. 이 경우 충돌이 나는 부분을 해결하고 다시 Pull Request를 보내야 한다.