Original article: https://www.freecodecamp.org/news/git-clone-branch-how-to-clone-a-specific-branch/

SVN 이나 CVS와 같은 오래된 중앙 집중 버전 관리 시스템들과는 달리 Git은 분산되어 있다. 개발자들은 로컬과 리모트 두 환경 모두에서 자신이 쓴 코드에 대한 히스토리와 완전한 권한이 있다. 또한 코드의 여러 다른 부분들에 대한 접근과 쓰기 권한이 있다.

Linus Torvalds(리누스 토르발스-리눅스 운영 체제를 만든 사람)가 2005년에 리눅스 커널 개발을 위해 Git을
만든 이후로 Git은 세계에서 가장 많이 사용되고 있는 버전 관리 시스템이 되었다.

이 글에서는 Git 클론(clone)과 브랜치(branch) 워크플로우에 대해 소개하려고 한다. 내가 필요한 것에 따라 특정한 브랜치를 클론 하는 법을 알아보자.

준비 사항

  • 터미널(terminal)에 대한 기본 지식
  • 터미널에 명령어 쓸 수 있기
  • Git 설치 (설치를 어떻게 하는지도 아래에서 설명하겠다)
  • GitHub 계정
  • 웃음 띤 얼굴 (얼굴에 웃음 준비!)

Git 과 GitHub 소개

위키피디아에 나온것을 보면

Git은 분산 버전 관리 시스템으로써 소프트웨어 개발 프로젝트(코드)의 변화를 추적한다. Git은
개발자들간의 조직화, 협업, 속도, 효율성을 높히는 목적으로 쓰인다.

한편 깃허브(GitHub) 는 Git을 사용하는, 웹에서 호스팅하는 버전 관리 시스템이다. 깃허브는 분산된
버전 관리 기능을 제공하고 Git의 소스 코드 (source code) 관리 기능을 포함한 여러가지 다른 기능들을 제공한다.

윈도우에서 Git을 설치하는 방법

최신의 윈도우용 Git을 다운로드 받고 설치한다.

Git을 리눅스에서 설치하는 방법

리눅스 배포판(distro)에 따라 각각 설치하는 명령어는 다음과 같다.

데비안(Debian)이나 우분투(Ubuntu)

sudo apt-get update
sudo apt-get install git

페도라(Fedora)

sudo dnf install git

센토스(CentOS)

sudo yum install git

아치 리눅스(Arch Linux)

sudo pacman -Sy git

젠투(Gentoo)

sudo emerge --ask --verbose dev-vcs/git

맥에서 Git을 설치하는 법

최신의 맥(Mac)을 위한 Git을 다운로드 받고 설치한다.

혹은 밑의 명령어를 사용해도 된다.

brew install git

이제 Git 설치를 마쳤으니 본격적으로 튜토리얼을 시작하겠다.

Git 클론 소개

Git은 프로젝트들의 버전을 리포지토리(Repository)에서 관리할 수 있게 해준다.
이 리포지토리는 깃허브와 같은 웹 기반 호스팅 서비스에 저장되어 있다.

이 리포지토리를 클론(clone)해서 모든 파일들과 브랜치(branch)들을 로컬 컴퓨터에 저장할 수 있다.
(브랜치에 대한 설명은 뒤에서 하겠다.)

깃 클론 버튼 스크린

예를 들어서 프리코드캠프의 리포지토리는 SSH를 이용해서 터미널에 다음 명령어를 써서 클론할 수 있다.

git clone git@github.com:freeCodeCamp/freeCodeCamp.git

Git 브랜치 소개

한 프로젝트를 할 때는 보통 개발해야 할 여러 가지 다른 기능(feature)들이 있기 마련이다.
그리고 다수의 기여자(contributor)들이 이 프로젝트의 여러 다른 기능들을 더하기 위해 일하고 있을 것이다.

브랜치는 master 브랜치와 같은 파일들을 가진 일종의 "놀이/실험 공간"(playground)을 만들어준다.
이 브랜치를 이용하면 프로덕션 코드를 망치거나 코드에 영향을 미치지 않으면서 기능을 독립적으로 개발하거나 새로운 기능을 테스트해볼 수도 있으며, 큰 변화를 주거나 버그를 수정하고, 문서 작성 및 새로운 아이디어도 구현해볼 수 있다.
작업이 완성되었다면 이 브랜치를 프로덕션용 master 브랜치에 병합(merge)한다.

브랜치는 Git의 중심적인 개념이다. 또한 깃허브에서 한 프로젝트의 다양한 버전들과 워크플로우를 관리하기 위해서 사용된다.
master 브랜치는 (역주: 혹은 main 브랜치) 리포지토리의 기본 브랜치로써 보통 "프로덕션용, 배포(deploy)
할 수 있는 코드"가 있는 곳이라고 간주된다. 새로 만든 브랜치들, 예를 들면 password-authrefactor-signup-ux 같은 브랜치들은 master 브랜치로부터 생성할 수 있다.

프리코드캠프 리포지토리의 브랜치들 스크린
프리코드캠프에 있는 모든 브랜치들

Git 브랜치들을 클론 하는 방법

리포지토리는 git clone 명령어를 써서 클론할 수 있는데 이렇게 하면 원격(remote)의 HEAD 와 브랜치를 클론하게 된다. 보통 이 기본값 브랜치인 master 와 리포지토리에 속한 다른 모든 브랜치들이 포함되있다.

한 리포지토리를 클론한다는 건 master 브랜치를 포함한 다른 모든 브랜치들을 다 클론한다는 뜻이다. 이렇게 하면 원하는 브랜치로 스스로 전환(checkout)해야 한다.

예를 들어서 어떤 프로젝트에 비밀번호가 필요없는 인증 기능을 개발해야 하는 상황이라고 가정해보자. 이 기능은
passwordless-auth 브랜치에서 작업되고 있다.

이런 상황이라면 딱히 master 브랜치가 필요한 상황은 아니다. 왜냐하면 내가 작업해야할 기능이 들어있는 그 브랜치는 나중에 master 로 병합될 것이기 때문이다. 그렇다면 내가 필요 없는 모든 파일들을 포함한 다른 브랜치들을 다 같이 클론 하는 대신 이 passwordless-auth 브랜치만 클론하는 방법은 무엇일까?

이를 설명하기 위해 샘플 리포지토리를 만들었다. 이 리포지토리는 Nextjs를 이용해서 만든 간단한 블로그인데 4개의 더미(dummy) 브랜치들을 포함하고 있다:

  • master
  • dev
  • staging
  • passwordless-auth

Nextjs에서는 pages/api 폴더 안에 있는 모든 파일은 /api/* 경로(path)로 매핑(mapping)된다.
그래서 page가 되는 것이 아니라 API(응용 프로그램 프로그래밍 인터페이스) 엔드포인트로 처리된다. 우리의 샘플 리포지토리에는
각각 다른 더미 API를 이 디렉토리에 만들어서 각각의 브랜치를 다르게 했다.

master 브랜치는 pages/api/hello.js 파일을 갖고 있는 반면 passwordless-auth 브랜치는 pages/api/auth.js 파일을 갖고 있다. 이 두 파일은 각각 더미 텍스트를 응답으로 보내준다. master 브랜치에 있는 hello API의 응답을 여기에서 볼 수 있다. (그리고 당신을 위한 특별한 메세지가 포함 되어있을지도?)

이 리포지토리를 클론해보자:

git clone git@github.com:BolajiAyodeji/nextjs-blog.git

이 명령어는 우리에게 이 리포지토리에 있는 모든 브랜치에 대한 접근 권한을 준다. 그리고 브랜치를 바꿔가면서 각 다른 버전들과
그 버전에 포함된 파일들을 쉽게 볼 수 있다.

git branch -a

리포지토리의 모든 브랜치 목록이 터미널에 출력된 화면

여기 나온 remotes/origin/.. 브랜치들은 어디서 온 것일까?

리포지토리를 클론하게 되면 인터넷상의, 혹은 **원격(remote)**이라고 하는 내부 서버에 있는 데이터를 가져오게 된다. origin 이라는 말은 깃에서 만든 일종의 별명(alias)인데 이 별명을 원격 URL 대신
쓸 수 있다(내가 원하는 다른 별명(alias)로 바꿔도 된다).

여기 나온 **remotes/origin/..**의 브랜치들은 인터넷에서 클론한 리포지토리에 연결되어 있기 때문에 origin으로 pull/push와 같은 명령을 수행할 수 있다.

깃 리모트 버전(git remote -v) 명령어 결과가 터미널에 출력된 화면

컴퓨터에 master를 클론한다고 할 때, remotes/origin/master는 인터넷상에 있는 본래의 master 브랜치이고, master는 내가 쓰는 컴퓨터에 있는 것이다.
그래서 pull/push 같은 명령은 이 곳, remotes/origin/master을 포인트로 하게 된다.

요약하자면 Remote는 인터넷에 있는 리포지토리를 가르키는 URL이고 Origin은 리모트 URL의 별명(alias)인 것이다.

리모트상의 브랜치들을 터미널에 출력한 화면

특정한 브랜치를 클론하는 법

이제 우리의 데모용 리포지토리에서 특정한 브랜치를 클론해보자. 특정한 브랜치를 클론하는 방법에는 두가지가 있다:

  • 리포지토리를 클론한 다음 모든 브랜치들을 가져온다(fetch). 그리고나서 특정한 브랜치로 전환(checkout)한다.
  • 리포지토리를 클론한 후에 그 특정한 브랜치만 페치한다.

첫번째 방법

git clone --branch <branchname> <remote-repo-url>

또는

git clone -b <branchname> <remote-repo-url>

여기에서 -b--branch의 줄임말이다.

이 명령어로 리포지토리에 있는 모든 브랜치들을 페치한 후에 특정한 브랜치로 전환한다. 그러면 그 브랜치를 기준으로 로컬에서 git pushgit pull를 할 수 있도록 설정이 된다. 하지만 이렇게 하면 각 브랜치가 갖고 있는 모든 파일들을 다 페치한 상태이다. 그렇게까지 할 필요는 없을 수도 있다(혹은 원하지 않은 결과일 수도 있다).

테스트를 해보자:

 git clone -b passwordless-auth git@github.com:BolajiAyodeji/nextjs-blog.git

이렇게 하게 되면 자동으로 passwordless-auth 브랜치가 로컬 브랜치로 설정 되는 동시에 다른 브랜치들도 추적할 수 있다.

git remote show origin 명령어. 추적하는 모든 브랜치들을 보여주는 터미널 화면

git branch -a 명령어가 출력하는 터미널 화면

두번째 방법

git clone --branch <branchname> --single-branch <remote-repo-url>

또는

git clone -b <branchname> --single-branch <remote-repo-url>

여기에서 -b--branch의 줄임말이다.

이 명령어는 첫번째 방법과 같은 동작을 수행한다. 차이점은 --single-branch 옵션이 붙었다는 것인데 이 옵션은 Git 버전 1.7.10 에서 소개되었고 그 이후 버전들에서도 가능하다.
이 옵션을 붙이게 되면 특정한 브랜치의 파일들만 페치하고 다른 브랜치들에서는 페치를 하지 않는다.

테스트를 해보자:

git clone -b passwordless-auth --single-branch git@github.com:BolajiAyodeji/nextjs-blog.git

이렇게 하게 되면 자동으로 passwordless-auth 브랜치를 로컬 브랜치로 설정하고 이 브랜치만 추적하게 된다.

두번째 방법에서 git remote show origin 명령어. 추적하는 모든 브랜치들을 보여주는 터미널 화면

두번째 방법에서 git branch -a 명령어가 출력하는 터미널 화면

터미널에서 cd pages/api 를 실행해보면 처음의 프로젝트 설정에서와 같이 passwordless-auth 브랜치에 있는 auth.js 파일이 있는 것을 확인할 수 있다.

결론

어쩔 때는 인터넷 연결이 끊기거나 컴퓨터의 메모리 용량이 거의 남지 않은 상황에서 특정한 브랜치에서 작업을 해야하는 경우가 있을 수 있다. 혹은 다른 여러가지 이유들로 특정한 브랜치에 있는 파일들만 클론하고 싶은 경우도 있을 수 있다. 다행히도 Git은 이것을 가능하게 해주는 기능을 제공한다. 또 새로운 것을 배우게 된 자신을 칭찬해주고, 이제 이것을 스스로 한번 활용해보길 바란다. 앞으로도 Git에 대해 배워야 할 것이 아직 많다.

무엇이든지 한 번에 하나씩 하면 된다. 그렇지 않은가?