다시 시작하는 Git, GitHub 고급 2

Hyuno Choi·2021년 3월 26일
0
post-thumbnail

2021년 3월 25일

지금까지는 로컬 환경에서 Git을 사용하는 방법에 대해 알아보았는데요, 오늘은 GitHub에서 원격 저장소를 만들고 원격 저장소로 커밋을 보내는 방법에 대해 포스팅하겠습니다.

원격 저장소 만들기

우선 GitHub 사이트에서 새 원격 저장소를 만들어줍니다. GitHub 계정이 필요합니다. GitHub에 로그인 한 후에 메인 페이지 우측 상단에 있는 +버튼을 누르고 New repository 버튼을 누릅니다.

그리고 나면 다음과 같은 간단한 입력창이 뜨는데요, 차례대로 정보를 입력하면 됩니다.

  • Repository name : 저장소의 이름입니다.
  • Description : 저장소에 대한 간단한 설명입니다.
  • Public/Private : 저장소를 공개할지의 여부를 선택합니다.

마지막으로 가장 밑에 Initialize this repository with: 이라고 적혀있는 부분에서는 레포지토리에 유용한 파일을 추가해줍니다.

  • Add a README file : 리드미 파일을 추가합니다.
  • Add .gitignore : 이 파일에 적힌 폴더나 파일은 원격 저장소에 올라가지 않습니다.
  • Choose a license : 라이센스 관련 파일을 추가합니다.

해당하는 부분을 전부 입력하고 Create repository 버튼을 누르면 새 원격 저장소가 만들어집니다. 이제 이 원격 저장소를 로컬 저장소와 연결하는 방법에 대해 알아보겠습니다.

원격 저장소 연결

  1. 원격저장소 URL을 복사합니다.

  2. 자신의 프로젝트 폴더에서 $ git init을 실행합니다.

  3. $ git remote add origin <URL>을 입력합니다. 일반적으로 저장소별명은 origin이라는 이름을 사용합니다.

  4. $ git remote -v 명령어로 원격 저장소가 잘 연결되었는지 확인합니다. 아래와 같이 fetch와 push의 주소가 출력된다면 연결이 잘 된 것입니다.

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

혹은, 단순히 $ git clone <저장소 URL> 명령어를 실행해서 위의 과정을 모두 생략할 수도 있습니다.

원격 저장소와 주고받기

로컬 저장소는 혼자 사용하지만, 원격 저장소는 프로젝트 구성원 모두의 변경 사항을 관리하게 됩니다. 따라서 개발을 진행하다가 원격 저장소와 로컬 저장소를 주기적으로 동기화해야 합니다. 동기화 과정은 크게 두 가지 상황으로 나눌 수 있습니다.

  1. 원격 저장소의 최신 코드를 내 로컬 환경에 가져와 병합하기(pull)
  2. 로컬 저장소에서 개발한 내용을 원격 저장소에 밀어넣기(push)

첫 번째 상황에서는 pull, 두 번째 상황은 push 명령어를 사용하게 됩니다. 이제부터 두 명령어의 기본적인 사용법과 소스 코드 병합과 관련된 심화적인 상황에 대해 알아보겠습니다.

pull

왼쪽에 있는 것이 로컬 저장소, 오른쪽에 있는 것이 원격 저장소입니다. 현재 상황을 정리해보자면 다음과 같습니다.

  • 로컬 저장소에 업데이트 되지 않은 변경 사항이 원격 저장소에 있습니다.
  • 원격 저장소가 로컬 저장소의 모든 변경 사항을 포함하고 있습니다.

즉, 그저 원격 저장소에서 최신 변경 사항을 가져와 병합시켜주기만 하면 됩니다. 병합은 fast-forward로 진행될 것입니다.

로컬 환경에서 $ git pull origin master 명령어를 입력합니다.

pull 명령어를 통해 원격 저장소의 커밋을 받아와 병합한 모습입니다. 이번에는 원격 저장소와 로컬 저장소에서 각각 변경 사항이 발생한 경우에 대해 알아보겠습니다.

처음 세 커밋까지는 원격 저장소와 로컬 저장소의 커밋이 동일합니다. 이후 로컬과 원격에서 새로운 커밋이 각각 두 개씩 만들어진 모습입니다. 이렇게 변경 사항이 겹칠 경우 앞에서와 같은 fast-forward 병합은 불가능합니다. 여기서 pull 명령어를 입력하면 리모트 브랜치와 master 브랜치의 병합 커밋이 생성됩니다. 만약 충돌이 생긴다면 충돌이 발생한 부분을 수정하고 커밋을 진행해야 합니다.

pull 명령어를 입력한 결과 master 브랜치와 리모트 브랜치가 병합된 커밋이 생겼습니다.

지금까지 pull을 설명할 때 받아오기라는 말과 병합이라는 말을 같이 사용했습니다. 그 이유는 pull 명령어가 최신 코드를 받아오고 그것을 로컬 브랜치에 병합하는 두 가지 일을 하기 때문입니다. 이 명령어가 작업하는 두 가지 일을 분리해서 시킬 수도 있습니다. 바로 fetchmerge를 사용하는 방법입니다.

  • fetch : 최신 코드를 받아오기
  • merge : 최신 코드와 로컬 코드를 병합하기

이 두 가지 명령어를 합친 것이 pull이라고 할 수 있습니다.

fetch

이번에는 pull 대신 fetch + merge로 원격 저장소에서 최신 커밋을 받아오고 병합하는 과정을 진행해보겠습니다.

전과 같은 상황입니다. push 후에 로컬에서 새로운 커밋 두 개가 생겼고, 원격에서도 로컬에 반영되지 않은 새 커밋 두 개가 생겼습니다. 여기서 $ git fetch origin master 명령어를 입력합니다.

실행 결과입니다. 다음과 같이 원격 저장소의 새로운 커밋을 리모트 브랜치에 받아오기만 할 뿐 아직 병합은 이루어지지 않았습니다.

여기서 $ git merge origin/master 명령어를 입력하면 pull 명령어를 입력했을 때와 같은 결과가 나오게 됩니다. 물론 rebase를 사용할 수도 있습니다. $ git rebase origin/master 명령어로 원격 저장소의 최신 커밋을 master 브랜치에 적용할 수 있습니다.

rebase를 시각화한 모습입니다. 이렇게 하면 원격 저장소의 최신 커밋을 로컬에서 작업한 내용에 적용할 수 있습니다. 지금까지 원격 저장소의 코드를 끌어오는 pullfetch에 대해 알아보았는데요, 이젠 로컬에서 작업한 내용을 원격 저장소에 보내는 push에 대해 알아보겠습니다.

push

$ git push origin <브랜치 이름> 명령어로 원격 저장소의 해당 브랜치에 로컬에서 작업한 커밋을 업로드할 수 있습니다. 이때 마지막으로 clone이나 pull을 받은 이후에 추가적인 변경 사항이 원격 저장소의 해당 브랜치에 생겼다면 내 커밋을 push할 수 없습니다. 이럴 때는 반드시 로컬 저장소를 최신화 한 다음 push를 진행해야 합니다.

로컬에서 push가 reject되는 상황을 가정해보겠습니다.

  1. 로컬 저장소를 최신화하고 커밋을 진행했습니다.
  2. 내가 push하기 전에 다른 누군가가 원격 저장소의 master 브랜치에 push를 날렸습니다.
  3. push를 해보지만 reject됩니다.

이런 경우에는 먼저 로컬 저장소에 원격 저장소의 최신 커밋을 받아와야 합니다.

  1. $ git pull origin master 명령어로 원격 저장소의 최신 커밋을 당겨와 병합합니다.

  1. 병합 시 충돌이 발생한다면 충돌이 발생한 줄을 적절히 수정하고 머지 커밋을 이어서 진행합니다.

  2. $ git push origin master로 push를 다시 진행합니다.

push 결과입니다. 로컬에서 만들었던 새 커밋과 머지 커밋 모두 원격 저장소에 반영되었습니다. 물론 fetch + rebase 조합을 이용해 reject 상황을 해결할 수도 있습니다. 리베이스를 사용할 경우 마치 모든 커밋이 시간 순서대로 일어난 것처럼 깔끔하게 커밋 이력을 정리할 수 있게 됩니다. 아까의 reject 상황으로 다시 돌아갑니다.

  1. $ git fetch origin master 명령어로 원격 저장소의 새 커밋을 '끌어오기만' 합니다.

  1. $ git rebase origin/master 명령어로 로컬에서 만들었던 새 커밋을 원격 저장소의 최신 커밋 뒤에 '이어붙입니다.'

이렇게 하면 내가 만든 커밋이 원격 저장소의 변경 이력을 모두 반영한 것이 됩니다.

  1. $ git push origin master로 push를 다시 진행합니다.

아까 merge를 사용했을 때보다 커밋 이력이 훨씬 깔끔해진 것을 볼 수 있습니다. 마치 모든 커밋이 차례대로 일어난 것처럼 보입니다.

push, pull 간편하게 하기

지금까지 pull이나 push를 할 때 인자로 <원격저장소 별명> <원격 저장소 브랜치 이름>을 주었는데요, 보통은 원격 저장소와 로컬 저장소의 브랜치명이 같기 때문에 설정을 통해 인자를 생략할 수 있습니다.

  1. $ git push -u origin master처럼 -u 옵션을 주게 되면 브랜치를 바꾸기 전까지는 $ git push 이후의 인자를 생략할 수 있습니다.

  2. 원격 저장소와 로컬 저장소의 모든 브랜치명이 동일하다면
    $ git config --global push.default current 명령어를 입력해 push, pull을 할 때 인자 없이 같은 이름의 브랜치라는 것을 알려줄 수 있습니다.

오늘은 로컬 저장소와 원격 저장소 간 pushpull을 통해 변경 이력을 주고 받는 방법에 대해 알아보았는데요, 다음 포스팅에서는 forkPull request, 오픈소스 기여에 대해 작성하겠습니다.


<참고 문서>

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

2개의 댓글

comment-user-thumbnail
2021년 3월 30일

안녕하세요. 강사로 참여했던 개발자입니다 :) 정말 정리를 잘해놓으셔서 몇군데에도 공유해봅니다. 현업에서 뵙게되면 인사 나눠요~

1개의 답글