[Git] Repository Fork, Sync

들어가며

Git을 사용하는 사내의 대형 프로젝트에서 협업을 하는 경우 혹은 대형 오픈소스에 기여를 하고 싶은 경우에 clone 보다 fork 를 선호할 수 있다.
(나의 경우에는 fork가 사내의 공식 국룰?인 경우이다.)

clone? fork?

무엇이 다를까?
가장 크게 와닿는 차이점은 clone의 경우 origin repo에 직접 반영이 되는 것이고, fork의 경우에는 origin 으로부터 복제된 repo에 반영이 되는 것으로 보인다.
그래서 fork는 어떤 특정 repo가 있다고 했을 때, fork 하는 시점의 모든 스냅샷을 나만의 repo로 복제하는 것이라고 이해하니 사용이 수월했다.
이 때 원본 repo의 태그, 브랜치 등 모든 정보를 포함하여 복제되며, 저장소의 주소가 다음과 같은 패턴으로 변경된다.
realm의 swiftlint repo를 예로 들면,
원본 repo: https://github.com/realm/SwiftLint
fork repo: https://github.com/njkim0529/SwiftLint이렇게 주소가 바뀌게 된다.
swiftlint의 원본 repo 에 대해서는 내 맘대로 어떤 변경을 했을 때 반드시 허락(pull request)을 받아야 하는 반면, fork repo 는 내 것이기 때문에 내 맘대로 변경을 해도 관계가 없다.

Sync with Origin

이렇게 fork 된 repo는 fork 시점의 모든 origin repo의 정보를 포함하지만, fork 된 뒤로는 origin repo의 변경을 자동으로 반영해 주지 않는다.
따라서 수동으로 변경을 fork repo로 반영해 주어야 한다.
나의 경우에는 GitKraken이나 SourceTree와 같은 gui 툴로도 쉽게 작업할 수 있지만, 터미널에서 git command로 origin 과 sync를 맞추는 것을 더 선호하기 때문에 터미널에서 sync 하는 법을 소개한다.
소개에 앞서 용어의 정리가 필요한데, 글에서는 편의상 origin을 원본 repo 라고 표현했지만 이제부터는 fork repo의 입장에서 설명해야 하므로 아래와 같이 용어를 변경한다.
origin: fork된 나의 repo (https://github.com/njkim0529/SwiftLint)
upstream: 복제한 repo (https://github.com/realm/SwiftLint)
fork를 한 후 repo를 나의 local 로 clone 한다.

git clone https://github.com/njkim0529/SwiftLint.git

그 후, 내 로컬에 등록된 remote 저장소의 정보를 살펴보면 다음과 같다.

git remote -v

origin  https://github.com/njkim0529/SwiftLint.git (fetch)
origin  https://github.com/njkim0529/SwiftLint.git (push)

fork 된 repo 가 origin으로 등록된 것을 확인할 수 있다.
원본 repo를 다음과 같이 upstream 으로 등록하고 다시 확인해 본다.

git remote add upstream https://github.com/realm/SwiftLint.git
git remote -v                                                 

origin  https://github.com/njkim0529/SwiftLint.git (fetch)
origin  https://github.com/njkim0529/SwiftLint.git (push)
upstream    https://github.com/realm/SwiftLint.git (fetch)
upstream    https://github.com/realm/SwiftLint.git (push)

그러면 이제 fork 된 repo는 origin 으로, 원본은 upstream 으로 추가된 것을 확인할 수 있다.
이제 sync 를 맞출 준비가 완료됐다.
upstream의 정보를 반영하기 위해서는 다음과 같은 절차를 수행한다. 예시로는 upstream의 master 를 대상으로 한다.

// upstream의 정보를 먼저 fetch
git fetch upstream

// upstream/master 를 merge
// upsream 의 다른 브랜치를 merge 하고 싶다면,
// git merge upstream/{branch_name}
git merge upstream/master

이렇게 하면 upstream/master 의 변경을 나의 repo로 반영할 수 있다.
로컬에서 작업한 내용을 remote로 반영하고자 할 때에는 다음과 같이 작업하면 된다.

// 변경 사항을 전부 스테이징.
git add -A

// 변경을 commit
git commit -m "commit message"

// fork repo로 push 할 때,
git push origin

// upstream repo 로 push 할 때,
git push upstream

upstream의 branch protection 규칙에 따라 upstream push가 불가할 수 있다.
이 때는, upstream repo로 pull-request 를 하여야만 내 변경을 upstream에 반영할 수 있다.

댓글 남기기