다시 시작하는 Git/GitHub 고급 3

Hyuno Choi·2021년 4월 6일
0
post-thumbnail

2021년 4월 6일

강의는 3월 초에 들었지만 4월 초가 되어서야 마지막 주제인 저장소 ForkPull request에 대해 정리하게 되었습니다. 왜 Fork라는 개념이 GitHub에 존재하는지, 말로만 듣던 Pull request는 무엇인지 적어보려고 합니다.✏️

믿고 맏기는 리포지토리🔐?

내가 오픈소스 리포지토리의 주인이고, 프로젝트를 이끌어나가고 있다고 가정해봅시다. 어떤 깃헙 사용자가 내 프로젝트에 관심을 갖고 자신도 프로젝트에 기여하고 싶다고 말합니다. 이럴 때 우리는 어떻게 그 사람이 나의 프로젝트에 기여할 수 있도록 해야 할까요?

가장 간단하게는 그 사람에게 이메일 등으로 매번 소스코드 파일을 받아서 어떤 변경 사항이 있는지 확인한 다음 직접 리포지토리에 push 하는 방법이 있습니다. 이런 방법을 사용할 경우, 그 사람이 프로젝트에 기여할 때마다 매번 번거로운 작업이 일어날 것입니다. 파일 두 개를 직접 비교하고, 내 로컬 저장소에 그 사람이 짠 코드를 집어넣고, 문제가 있는지 테스트 한 다음에 다시 원격 저장소에 push 하는 과정은 생각만해도 끔찍합니다.😅

두 번째 방법은 기여자를 콜라보레이터로 등록해서 프로젝트 저장소에 push 할 수 있는 권한을 주는 것입니다. 이 경우 기여자가 기여 과정을 모두 알아서 진행할 수 있게 됩니다. 그러나 이 방법은 집 키를 모르는 사람에게 공유해주는 것만큼 위험합니다. 내 생각과 다른 코드를 원격 저장소에 집어넣거나, 커밋 이력을 마음대로 바꿔서 충돌을 일으킬 수도 있을 뿐더러, 처음부터 악의를 가지고 있었다면 내 프로젝트를 망가뜨릴 수도 있습니다.💥

다행히도 GitHub는 여러 사람이 기여하는 과정에서 편리함과 안전함을 모두 잡을 수 있는 방법을 제공합니다. 바로 ForkPull request가 그것인데요, 하나씩 알아보도록 하겠습니다.🧐

Git Fork🍽️

포크는 리포지토리를 복사하는 것입니다. 리포지토리를 포킹하는 것은 원본 프로젝트에 영향을 주지 않고 자유롭게 변화를 주고 실험할 수 있게 해줍니다.

GitHub 공식 문서에 나와있는 fork에 대한 설명입니다. 한마디로 원본 저장소의 복사본을 만들어와서 걱정 없이 커밋을 날리는 것입니다. 중요한 발표 자료를 수정할 때, 복사본을 만들어 임시로 수정을 해보고 이후에 원본에도 적용했던 기억이 있다면 깃 포크가 더 쉽게 와닿을 것입니다.

이제 리포지토리를 포크하는 과정을 다음 순서대로 직접 진행해보겠습니다. 기존 깃허브 계정 말고 실습용 계정을 하나 더 만들어줍니다.

  1. 다른 사람의 리포지토리를 내 리포지토리로 포크하기
  2. 포크한 리포지토리 클론 받기
  3. 커밋 날리고 push하기

Git Fork 실습

  1. 우선 실습용 계정으로 리포지토리 하나를 만들고 README.md 파일을 추가합니다.

  2. 자신의 본 계정으로 로그인해 방금 만든 리포지토리 페이지로 들어갑니다.

  3. 리포지토리 페이지 오른쪽 위를 보면 Fork라는 버튼이 보이는데요, 클릭해서 포크해봅시다.

여기서 제일 오른쪽 버튼이 Fork 버튼입니다. 이 버튼을 누르게 되면 자신의 리포지토리 목록에 포크된 리포지토리가 생기게 됩니다.

포크된 리포지토리 페이지로 이동한 모습인데요, forked from soonitoonClone/fork_test라고 포크된 저장소임을 명시적으로 밝혀주는 것을 확인할 수 있습니다.

  1. 로컬 환경에서 $ git clone <포크 받은 저장소 URL> 명령어로 리포지토리를 클론 받습니다.

  2. README.md 파일을 열어 아무 내용이나 작성한 뒤 commit을 진행합니다.

  3. $ git push origin master 명령어로 내 리포지토리에 푸쉬합니다.

이때, 지금까지 한 모든 작업이 원본 저장소가 아닌 포크 받아온 저장소에서 일어나는 일이라는 것에 주의하세요.

우리는 원본 저장소를 포크 받고, 포크 받은 저장소를 로컬 환경에 클론하고, 로컬에서 새로 작업한 내용을 다시 push하는 과정까지 진행했습니다. 그런데 이렇게 만든 변경 사항을 어떻게 원본 저장소에 적용시킬 수 있을까요?

Pull request

Pull request는 말 그대로 'Pull 요청'이라고 번역할 수 있습니다. 내가 만든 변경 사항(커밋)을 원본 저장소의 관리자에게 끌어가라고 요청을 보내는 것입니다. 다시 포크 받은 리포지토리 페이지로 돌아가보겠습니다.

This branch is 1 commit ahead of soonitoonClone:master라는 메시지가 보입니다. 현재 브랜치가 원본 저장소의 브랜치보다 한 커밋 앞서 나갔으니, Pull request를 보내거나 변경 사항을 비교해보라고 알려줍니다. 이제부터 Pull request를 보내는 실습을 진행해보겠습니다.

  1. Pull request 버튼을 클릭합니다.

버튼을 클릭하면 다음과 같은 창이 뜨게 됩니다. Pull request를 보내기 전, 내 요청을 점검해볼 수 있는 페이지입니다.

  • 상단의 브랜치 명을 확인하고 리퀘스트를 보낼 브랜치와 받을 브랜치를 선택합니다.
  • Able to merge라는 글자가 뜬다면 충돌 없이 병합할 수 있다는 뜻입니다. 만약 충돌이 예상된다면 해당 부분을 수정한 후에 다시 리퀘스트를 보냅니다.
  • 페이지 하단에서는 해당 Pull request로 변경될 파일과 라인을 표시해줍니다. 내가 의도하지 않은 변경 사항이 리퀘스트에 들어가지 않도록 반드시 변경 내용을 확인한 후 리퀘스트를 보내야 합니다.
  1. 모든 내용을 확인했다면, Create pull request 버튼을 눌러 리퀘스트를 생성합니다.

버튼을 클릭하면 리퀘스트의 제목과 설명을 적을 수 있는 페이지가 나타납니다. 커밋 메시지를 작성하는 데에도 일정한 규칙이 있듯이 Pull request에 대한 설명을 적을 때에도 기본적으로 들어가야하는 정보들이 있습니다. 다음은 pullrequest.com에서 가져온 Pull request description 템플릿입니다.

  • What : 이 작업은 무엇에 관한 것인가?

  • Why : 왜 해당 작업을 하였는가?

  • How : 해당 작업을 어떻게 하였는가?

  • Testing :
    테스트가 이루어졌는가?
    테스트가 이루어지지 않은 부분이 있는가?
    왜 테스트를 하지 못했는가?
    그 부분이 어떤 문제를 발생시킬 수 있는가?

  • Screenshots : UI관련 변화

  • Anything Else

링크 : https://www.pullrequest.com/blog/writing-a-great-pull-request-description

설명을 모두 작성하였다면 Create pull request 버튼을 눌러 Pull request 보내기를 완료합니다.

Pull request를 보내면 해당 저장소에 pull request로 등록됩니다. 여기서 사람들끼리 해당 리퀘스트에 대해 토론을 할 수도 있고, 저장소 관리자라면 병합 방법을 선택하거나 리퀘스트를 닫아버릴 수도 있습니다.

리포지토리의 주인인 두 번째 계정으로 접속했습니다. 해당 pull request에 대한 정보와 댓글 기능, 그리고 병합 방법을 선택할 수 있는 초록색 버튼이 보이는데요, Pull request 병합 방법은 세 가지로 나뉩니다.

  • Merge pull request
  • Squash and merge
  • Rebase and merge

여기서 Merge와 Rebase는 전 포스팅에서 다뤘으므로 어떤 방식으로 병합이 진행되는지 예상할 수 있습니다. 여기서 특이한 것은 Squash인데요, 간단히 말해서 해당 pull request가 가진 모든 커밋을 하나의 커밋으로 원본 저장소의 브랜치에 추가하는 것을 의미합니다.

출처 : https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges

D와 E라는 커밋 두 개가 있다면, 이를 F라는 하나의 커밋으로 바꾸어 브랜치에 추가하는 방법이 바로 Squash입니다.

여기서는 Merge pull request를 선택하도록 하겠습니다.

pull request를 승인한 후 원본 리포지토리의 해당 브랜치 커밋 이력을 보면 다음과 같이 pull request가 가진 커밋과 머지 커밋이 생성된 것을 볼 수 있습니다.

지금까지의 과정으로 Fork와 Pull request가 가지는 장점이 분명해졌습니다. 다른 사람의 프로젝트에 기여하고 싶은 사람은 Fork를 통해 마치 자신의 리포지토리처럼 자유롭게 작업을 진행할 수 있고, 프로젝트의 주인 또한 Pull request라는 과정을 통해 다른 사람의 작업물을 점검하고 받아들일 수 있는 일종의 '안전망'이 생기는 것입니다.

그런데 이 과정에서 우리가 알아야 할 사항이 하나 더 있습니다. 바로 포크 받은 리포지토리의 최신화 과정입니다. 내가 포크를 받은 후에도 다른 사람에 의해 원본 리포지토리에 변화가 생길 수 있기 때문입니다.

Fork받은 저장소 최신 상태 유지

출처 : https://vitess.io/docs/contributing/github-workflow

최신 상태 유지에 대해 알기 전에 위의 그림을 이해해야 합니다. 여기서 Upstream이란 원본 저장소, Origin은 포크 받아온 저장소, Local은 로컬 저장소를 의미합니다. 지금까지 우리는

  1. Upstream을 포크해 Origin을 만들고
  2. Origin 저장소를 Local에 클론 받고
  3. Local에서 작업한 내용을 Origin에 push하고
  4. Origin의 커밋을 Upstream에 Pull request로 보내는 작업을 진행하였습니다.

이제 해야할 일은 Upstream과 Local의 연결 고리를 만들어주는 것입니다. 이 연결 고리는 Upstream이라는 원격 저장소를 하나 더 등록해주면 간단히 만들어집니다.

로컬 저장소에서 $ git remote -v 명령어를 치면 현재는 origin이라는 저장소만 존재합니다.

$ git remote -v
origin  https://github.com/soonitoon/fork_test (fetch)
origin  https://github.com/soonitoon/fork_test (push)

Upstream 저장소와 연결해주기 위해 $ git remote add upstream <원본 저장소 URL> 명령어를 입력합니다.

$ git remote -v
origin  https://github.com/soonitoon/fork_test (fetch)
origin  https://github.com/soonitoon/fork_test (push)
upstream   https://github.com/soonitoonClone/fork_test (fetch)
upstream   https://github.com/soonitoonClone/fork_test (push)

이제 로컬저장소는 Origin과 Upstream 모두와 연결된 상태가 되었습니다. Upstream 저장소에 변경 사항이 생긴다면 fetch를 통해 로컬 저장소로 해당 내용을 받아오고, push를 통해 Origin에도 반영할 수 있습니다.

지금까지의 포스팅으로 충북대학교의 Git/GitHub 기초/고급 특강 정리를 모두 마치게 되었습니다. 다음 포스팅에서는 이미 날린 커밋을 되돌리는 방법에 대해 부록처럼 작성하려고 합니다.


<참고 문서>
profile
프론트엔드 웹 개발자를 목표로 하고 있습니다.

0개의 댓글