[git 교과서] 6장. 브랜치(2)

Jiseon·2021년 9월 27일
0

6.6 브랜치 공간

6.6.1 브랜치 로그

$ git log --graph --all : 로그 출력 시 브랜치 흐름까지 확인할 수 있다.

로그 출력 왼쪽 부분에 브랜치 경로와 작업들이 텍스트 그래프로 같이 출력된다.
--more 옵션으로 출력될 커밋개수를 제한할 수 있다.
$ git show-branch --more=10

6.6.2 브랜치 소스 확인


두 소스 코드에는 차이가 있다.
브랜치를 이동하면 변경된 각자 브랜치의 마지막 워킹 디렉터리 상태로 빠르게 변경된다.
footer는 한줄짜리 정보를 워킹 디렉터리에 가지고 있는 상태이고, master는 두줄짜리 정보를 워킹 디렉터리에 가지고 있는 상태이다.


6.7 HEAD 포인터

6.7.1 마지막 커밋

깃은 마지막 커밋정보를 기반으로 새로운 커밋을 생성한다.
마지막 커밋은 새로운 커밋의 부모 커밋이다.
HEAD는 작업 중인 브랜치의 마지막 커밋 ID를 가리키는 참조 포인터이다.

6.7.2 브랜치 HEAD

브랜치를 이동하면 HEAD 포인트도 이동한다.
브랜치가 여러 개면 각각의 브랜치마다 마지막 커밋이 다르기 때문에 HEAD포인터도 여러 개이다.

HEAD는 현재 작업하는 브랜치를 가리키기 때문에 HEAD 포인터는 브랜치에 따라서 위치가 변경된다.

6.7.3 소스트리 HEAD

6.7.4 상대적 위치

깃의 HEAD포인터는 내부적으로 커밋을 생성하고 브랜치를 관리하는데 유용하고 다양한 명령어를 입력할 때도 기준점으로 사용된다.
상대적 커밋 위치를 지정할 때는 캐럿(^)과 물결(~)기호를 같이 사용한다.
예) HEAD 기준으로 이전 3개를 지정하고 싶다면?

HEAD^^^
HEAD~~~
HEAD^3
HEAD~3

6.7.5 AHEAD, BHEAD

원격 저장소와 연동하여 깃을 관리한다면 로컬 저장소 브랜치의 HEAD포인터와 원격 저장소 브랜치의 HEAD포인터가 있다.
원격 저장소와 로컬 저장소는 물리적으로 서로 다른 저장소이기 때문에 마지막 커밋 위치가 일치하지 않을 수 있다.
AHEAD와 BHEAD는 서로 다른 저장소 간 HEAD 포인터의 위치 차이를 의미한다.
브랜치를 여러 개 운영한다면 다수의 AHEAD와 BHEAD가 생길 수 있다.

AHEAD

AHEAD는 서버로 전송되지 않은 로컬 커밋이 있는 것이다.
로컬 저장소에 새로운 커밋을 생성하고 새로운 커밋 정보를 서버로 전송하지 않으면 AHEAD가 발생한다.

로컬 저장소의 HEAD 포인터를 기준으로 로컬 브랜치에 있는 커밋의 서버의 커밋 개수보다 많은 경우를 의미한다.

BHEAD

BHEAD는 로컬 저장소로 내려받지 않은 커밋이 있는 것이다.
누군가 서버에 새로운 커밋을 했는데 로컬 저장소는 서버의 새로운 커밋을 내려받지 않았을 경우 BHEAD 가 발생한다.

다른 개발자가 코드를 수정하여 원격 저장소의 커밋이 자신의 로컬 저장소보다 더 최신인 상태인 것을 의미한다.


6.8 생성과 이동

6.8.1 자동 이동 옵션

$ git checkout -b 브랜치이름 : 브랜치 생성과 이동을 한번에 할 수 있다.

6.8.2 커밋 이동

브랜치는 특정한 커밋에 별명을 부여한 것과 같다.
커밋 해시 값을 지정한 별칭으로 브랜치 목록에 등록한다.
브랜치 이름은 커밋 해시키와 동일하다.
브랜치 이름 대신 커밋 해시키를 이용해서 체크아웃 할 수도 있다.
$ git checkout 커밋해시키
해시키 전체 사용하지 않고 앞의 7자리 정도만 사용해도 괜찮다.

브랜치 중간에 작업한 특정 커밋으로 직접 이동하여 상태를 확인할 수 있다.

6.8.3 HEAD를 활용한 이동

HEAD 포인터를 사용하여 체크아웃 할 수 있다.
예) 바로 이전 커밋으로 체크아웃하고 싶을 때
$ git checkout HEAD~1

6.8.4 돌아오기

커밋 해시키 또는 HEAD를 사용해서 과거의 커밋으로 체크아웃했다면 다시 현재 시점으로 돌아와야한다.
$ git checkout - : 대시(-)를 이용하면 바로 이전의 브랜치로 복귀한다.


6.9 원격 브랜치

6.9.1 리모트 브랜치

원격 저장소에 생성한 브랜치리모트 브랜치라고 한다.
원격 저장소와 연결된 로컬 저장소에서 새로운 브랜치를 생성한다고 해서 자동으로 원격 저장소에도 브랜치가 생성되는 것은 아니고 별도 명령을 실행하여 저장소를 동기화해야한다.
리모트 브랜치는 보통 별칭/브랜치이름 형태이다.

6.9.2 실습 준비

본인의 깃허브 계정에서 New repository를 클릭 > 깃허브 저장소 이름을 작성 > Create repository 클릭

원격 저장소를 등록

6.9.3 브랜치 추적

리모트 브랜치는 원격 저장소의 브랜치를 가리키는 포인터이다.
원격 저장소의 브랜치를 가리키는 것을 브랜치 추적(=트래킹 브랜치)이라고 한다.
트래킹 브랜치는 원격 브랜치를 가리키는 북마크와 같고 원격 브랜치의 마지막 커밋 해시 값을 가리킨다.
포인터의 정보는 .git/refs 폴더 안에 저장되어 있다.

로컬 저장소가 원격 저장소와 연결될 때 원격 브랜치의 트래킹 정보는 자동으로 갱신된다.
마지막으로 연결된 리모트 브랜치의 커밋 해시 값을 항상 가지고 있다.

6.9.4 브랜치 업로드

$ git remote show 원격저장소별칭 : 등록된 원격 저장소의 리모트 브랜치 확인

원격 저장소를 등록만 했기 때문에 아직 리모트 브랜치는 없다.
리모트 브랜치는 서버간의 통신을 하고 나서 생성된다.
로컬 저장소의 브랜치를 원격 저장소에 동기화 하려면 푸시 작업을 해야한다.
$ git push 원격저장소별칭 브랜치이름
로컬 브랜치를 푸시하면 원격 저장소는 로컬 저장소와 동일한 브랜치를 생성한다.

$ git push -u origin master : 선택한 브랜치(master)를 원격 서버(origin)로 전달한다는 의미이다.



6.9.5 이름이 다른 브랜치

깃은 서로 다른 로컬 브랜치와 리모트 브랜치를 수동으로 지정하여 연결할 수 있다.
브랜치를 직접 수동으로 지정할 때는 콜론(:)으로 구분한다.

$ git push origin 브랜치이름:새로운브랜치 :
현재 브랜치를 서버(origin)의 새로운 브랜치 이름으로 전송하라는 의미이다.


로컬 저장소의 feature 브랜치가 깃허브에는 새로운 function 브랜치로 등록된 것을 확인할 수 있다.

6.9.6 업스트림 트래킹

업스트림(upstream)은 브랜치 추적을 다르게 표현한 것이다.
로컬 저장소의 브랜치와 원격 저장소의 브랜치는 업로드할 수 있도록 매칭되어 있고 이를 업스트림 트래킹이라고 한다.
트래킹 브랜치(업스트림)는 리모트 브랜치와 로컬 브랜치를 연결해 주는 중간다리 역할을 한다.
clone 명령어로 저장소를 복제할 때 원격 저장소에 등록된 트래킹 브랜치들은 자동으로 함께 설정한다.

clone 명령어는 원격 저장소의 모든 브랜치 정보를 한 번에 다 가지고 오지 않는다.
$ git branch -r : 원격 저장소의 리모트 브랜치 목록을 확인할 수 있다.
$ git branch -a : 모든 브랜치 정보를 확인 할 수 있다.
$ git branch -vv : 복제 저장소의 트래킹 브랜치를 확인 할 수 있다.


ahead 1은 원격 저장소로 전송되지 않은 커밋이 하나 있다는 의미이다.
$ git push 명령어를 통해서 복제된 저장소에서 수정된 커밋이 원격 저장소로 전송된다.

원본 저장소에서 $ git pull 명령어를 실행하면 feature 브랜치 정보로 자동 병합된다.

6.9.7 원격 브랜치 복사

다른 개발자가 원격 저장소에서 새로운 리모트 브랜치를 생성할 수 있기 때문에 원격 저장소와 로컬 저장소의 브랜치 목록은 다를 수 있다.
$ git checkout -b 새이름 orgin/브랜치이름 :
원격 저장소의 리모트 브랜치를 이용해 로컬 저장소에도 새로운 브랜치를 생성하여 동기화 할 수 있다.

실습

깃 허브 저장소 브랜치 항목(Branch:master)선택 > 새이름 입력(aaa) > Create branch:aaa 클릭

원격 저장소의 브랜치 정보를 로컬 저장소로 가져온 후 확인한다.

.origin/aaa 리모트 브랜치를 기반으로 로컬 저장소에 aaa 브랜치를 새롭게 생성한다.

코드 수정후 커밋하고 확인해보면 aaa브랜치에 서버로 전송하지 않은 커밋이 있어 HEAD 1로 표시된다.
깃허브에서 확인하면 수정된 내용과 커밋을 확인 할 수 있다.

6.9.8 업스트림 연결

$ git branch -u orgin/브랜치이름 : 기존에 있는 브랜치를 업스트림으로 직접 설정할 수 있다.
-u 옵션 : --set-upstream-to의 약자로 기존 브랜치를 특정 원격 브랜치로 추적한다.

실습

깃 허브 저장소 브랜치 항목(Branch:master)선택 > 새이름 입력(ccc) > Create branch:ccc 클릭

서버의 브랜치 정보를 갱신한 후 브랜치 목록을 확인한다.
원격 저장소의 ccc브랜치와 연결할 수 있는 coffee라는 새브랜치를 로컬 저장소에 하나 만든다.
coffee 브랜치는 로컬 저장소에만 있는 브랜치이고 이 coffee 브랜치를 원격 저장소의 ccc리모트 브랜치로 업스트림 설정한다.


6.10 브랜치 전송

6.10.1 브랜치 푸시

$ git push : 로컬 저장소의 파일들뿐만 아니라 브랜치 정보와 커밋까지 원격 저장소로 전송한다.
처음에는 커밋과 브랜치를 푸시하는데 업스트림 설정이 필요하다.
원격 저장소 연결만으로 업스트림이 자동을 설정되지는 않는다
$ git push --set-upstream origin master : 수동으로 트래킹 브랜치와 업스트림 설정을 한다.
(현재 master브랜치를 origin 서버의 master로 업스트림 설정한다는 의미)

직접 서버를 운영한다면 다음과 같이 계정 권한을 변경해 줍니다.

# chmod -R g+ws *
# chgrp -R git *

6.10.2 브랜치 페치

리모트 브랜치가 페치되면 깃은 단순히 원격저장소별칭/브랜치 포인터만 생성한다.

원격 저장소에서 페치된 커밋들을 새로운 로컬 브랜치로 반영하려면 병합 명령을 실행해야 한다.
$ git merge 원격저장소별칭/브랜치이름

페치된 브랜치를 병합하지 않고 테스트만 하고 싶을 때는 원격 브랜치의 포인터를 사용하여 임시 브랜치를 생성하거나 직접 체크아웃 할 수 있다.
$ git checkout -b 임시브랜치이름/브랜치이름


6.11 브랜치 삭제

브랜치 삭제는 크게 스테이지 상태에 따라 달라진다.
현재 자신이 있는 브랜치는 삭제할 수 없다.

6.11.1 일반적인 삭제방법

$ git branch -d 브랜치이름 : -d 옵션은 스테이지 상태가 깨끗할때만 삭제를 허용한다
삭제하려면 반드시 최종 상태가 커밋되어 깨끗한 스테이지 상태여야하고 병합되지 않은 브랜치는 -d 옵션으로 삭제할 수 없다.

6.11.2 강제로 삭제하는 방법

워킹 디렉터리 또는 스테이지에 추가 커밋 작업이 남아있으면 강제로 삭제해야한다.

$ git branch -D 브랜치이름 : -D 옵션을 사용하면 강제로 브랜치를 삭제할 수 있다.

6.11.3 소스트리에서 삭제하는 방법

6.11.4 리모트 브랜치를 삭제하는 방법

원격 저장소의 브랜치를 삭제하려면 먼저 삭제 명령을 푸시해야 한다.
$ git push origin --delete 리모트브랜치이름

원격 저장소의 브랜치를 삭제하면 리모트 브랜치에 기록된 커밋도 모두 삭제 된다.


0개의 댓글