[GitHub 기초] Branch, checkout - 1
카테고리: GitHub
태그: Git
“[GitHub 기초] 버전 만들기”와 이어지는 내용을 다룰 것이므로 “[GitHub 기초] 버전 만들기” 를 먼저보고 해당 포스트를 보는 것을 추천한다.
Branch , checkout
모든 버전 관리 시스템은 브랜치를 지원한다. 개발을 하다 보면 코드를 여러 개로 복사해야 하는 일이 자주 생긴다. 코드를 통째로 복사하고 나서 원래 코드와는 상관없이 독립적으로 개발을 진행할 수 있는데, 이렇게 독립적으로 개발하는 것이 브랜치다.
사람들은 브랜치 모델이 Git의 최고의 장점이라고, Git이 다른 것들과 구분되는 특징이라고 말한다. 당최 어떤 점이 그렇게 특별한 것일까. Git의 브랜치는 매우 가볍다. 순식간에 브랜치를 새로 만들고 브랜치 사이를 이동할 수 있다. 다른 버전 관리 시스템과는 달리 Git은 브랜치를 만들어 작업하고 나중에 Merge 하는 방법을 권장한다. 심지어 하루에 수십 번씩해도 괜찮다. Git 브랜치에 능숙해지면 개발 방식이 완전히 바뀌고 다른 도구를 사용할 수 없게 된다.
참조 : Git - 브랜치란 무엇인가
Branch (브랜치)
브랜치(Branch)는 독립적으로 작업을 하기위한 Working Directory를 생성하는 기능이라 할 수 있다. 예를 들어 동일한 소스 코드 위에 신규 개발 혹은 오류 수정 등의 업무를 협업한다면 동시에 서로 영향을 주지 않고 다양한 작업을 할 수 있게 만들어 주는 기능인 것이다. 브랜치는 하나의 프로젝트를 여러 갈래로 나누어 관리를 하고 각각 독립적인 브랜치에서 마음대로 소스 코드를 수정한 뒤 원래 버전과 비교하여 새로운 버전을 만들 수 있으고 독립된 브랜치들을 병합하여 하나의 버전으로 만드는 것도 가능하다.
Branch 만들기
기본적으로 branch 명령어를 사용해 Branch를 생성할 수 있다.
$ git branch (브랜치 이름)
Branch를 이해하기 위한 간단한 예제를 작성해보자
$ git branch testing
앞서 3번의 commit이 있었다고 가정할 때 현재 작업은 다음과 같은 형태를 가지게 될 것이다.
현재 master 브랜치와 testing 브랜치가 마지막으로 commit한 버전을 가리키고 있다. master 브랜치는 저장소를 초기화 할 때 자동으로 만들어지는 브랜치로 사실 특별한 브랜치는 아니다.(다른 브랜치와 완전히 같다.) 다만 이 최초의 브랜치를 굳이 애써 다른 이름으로 변경하지 않으므로 대부분의 (거의 모든) 저장소에는 master 브랜치가 존재한다. (최근에는 인종차별적 요소나 주종 관계의 의미를 담고 있는 whitelist/blacklist, master/slave등의 용어를 제거하면서 기본 브랜치의 이름이 main으로 변경되었다. 본인의 기본 브랜치가 main이라면 master브랜치를 main 브랜치로 이해하면 될 것이다.)
HEAD
위의 상황에서 새로운 작업을 하고 커밋을 할 경우 그 작업은 testing 브랜치가 아닌 master 브랜치에서 이루어지는데 이는 HEAD가 여전히 master 브랜치를 가리키고 있기 때문이다.
HEAD는 현재 작업 중인 브랜치를 가리키는 포인터로 현재는 master브랜치를 가리키고 있다.
독립적인 브랜치로 활용하기 위해서는 이 HEAD가 testing 브랜치를 가리키도록 해야하는데 이때 사용되는 것이 바로 checkout이다.
Checkout
브랜치(Branch) 이동하기
$ git checkout (이동할 브랜치 이름)
위의 명령어를 이용해 HEAD가 가리키는 브랜치를 변경할 수 있다. (checkout은 HEAD가 가리키는 브랜치를 변경한다.) 따라서 다음의 명령어를 이용하면 HEAD가 testing브랜치를 가리키고 따라서 현재 작업하는 브랜치는 testing 브랜치가 된다.
$ git checkout testing
#Switched to branch 'testing'
이제 현재의 파일들에 원하는 수정을 한 뒤 새로 스테이징하고 commit을 해보자 간단하게 ex1.txt에 두 번째 줄을 추가해보았다.(이전 commit에서 ex1.txt에 첫 번째 줄 까지 작성되어 있었다고 가정한다.)
그후 log를 확인해 보면 다음과 같은 모습을 확인할 수 있다.
$ git log --oneline
# b16d6a4 (HEAD -> testing) checkout test
# e58febc (origin/master, master) vscode push
# 61f892c second version
# 0f1fcf9 first commit
HEAD는 testing을 가리키고 있고 testing브랜치와 master 브랜치가 분리되었다.
이로써 우리는 독립된 Branch를 만들어 해당 Branch에서 독립된 작업을 하는 것에 성공했다.
작업 환경 되돌리기
위의 작업을 진행했다면 이제 다음 명령어를 통해 master브랜치로 HEAD를 이동시켜보자.
$ git checkout master
그리고 ex1.txt파일을 열어보면 놀랍게도 수정하기 전의 모습으로 돌아와 있다.
$ git log --oneline
# e58febc (HEAD -> master, origin/master) vscode push
# 61f892c second version
# 0f1fcf9 first commit
로그를 확인해보면 testing 브랜치가 사라진 모습을 볼 수 있는데 이는 log 명령어가 HEAD가 가리키는 위치까지만 출력하기 때문이므로 —all을 추가해 모든 로그가 출력되도록 한다.
$ git log --oneline --all
# b16d6a4 (testing) checkout test
# e58febc (HEAD -> master, origin/master) vscode push
# 61f892c second version
# 0f1fcf9 first commit
이를 통해 우리는 HEAD가 master 브랜치로 돌아왔고 그와 함께 Working Directory역시 master 브랜치의 상황으로 변경되었음을 확인할 수 있다.
(이미지의 커밋 ID는 무시하자)
브랜치 이름이 아닌 commit ID를 이용해 Working Directory를 되돌리는 것도 가능하다.
$ git checkout (commit ID)
돌아가고 싶은 커밋의 id를 알아내기 위해 log를 확인해본다.
$ git log --oneline --all
# b16d6a4 (testing) checkout test
# e58febc (HEAD -> master, origin/master) vscode push
# 61f892c second version
# 0f1fcf9 first commit
처음 버전인 first commit으로 가기위해 메시지 앞에 출력되어있는 commit ID (0f1fcf9)를 기억해두자
이 commit ID를 이용해 우리는 first commit의 환경으로 돌아갈 것이다.
$git checkout 0f1fcf9
log를 확인해보면 HEAD가 first commit을 잘 가리키고 있는 것을 볼 수 있다. 물론 Working Directory역시 해당 버전의 환경으로 잘 돌아가 있을 것이다.
$ git log --oneline
# 0f1fcf9 (HEAD) first commit