브랜치(branch) : 저장 공간 하나에서 가상의 또 다른 저장 공간을 만드는 것
커밋 : 파일의 수정 이력 관리에 사용
브랜치 : 프로젝트를 독립적으로 관리하는데 사용
깃 브랜치 특징 : 기존 폴더를 복제하는 것과 다르게 가상 폴더를 사용하여 개발 작업을 구분
깃의 브랜치는 작업 폴더를 실제로 복사하지 않고, 가상 폴더로 생성함
외부적으로는 물리적인 파일 하나만 있는 것으로 보임
생성된 작업 폴더는 물리적으로 복제된 구조보다 유연하게 처리할 수 있음
브랜치로 생성된 가상 폴더는 빠르게 공간이동이 가능
독립적인 동작
브랜치를 이용하면 원본 폴더와 분리하여 독립적으로 개발 작업을 수행할 수 이음
기존에는 소스 코드의 작업 폴더를 별도로 생성함
물리적으로 복사된 각자의 폴더에서 코드를 작업한 후 소스 코드 2개를 다시 하나로 합쳐야 했음 - 매우 힘든 작업
깃과 같은 VCS를 이용하면 분리된 코드를 좀 더 쉽게 병합할 수 있음
분리된 브랜치에서 소스 코드를 각자 수정한 후 원본 코드에 병합하는 명령만 실행하면 됨
깃의 브랜치는 규모가 큰 코드 수정이나 병합을 처리할 때 매우 유용
빠른 동작
보통 다른 VCS는 브랜치를 생성할 때 내부 파일 전체를 복사
파일 크기가 매우 크다면 브랜치를 생성하는 데 시간이 오래 걸림
깃의 브랜치 기능은 다른 VCS보다 가볍고, 브랜치 전환이 빠른것이 특징
깃은 Blob 개념을 도입하여 내부를 구조화함
브랜치를 변경할 때 포인터를 이용해서 빠르게 전환함
브랜치 명령을 사용하면 내부적으로 커밋을 하나 생성하여 브랜치로 할당함
다른 VCS는 파일 전체를 복사하지만, 깃은 41바이트를 가지는 해시(SHA1) 파일 하나만 만들면 됨 - 브랜치를 더 빠르게 생성 가능
기본 브랜치
모든 커밋과 이력은 브랜치에 기록
깃은 최소한 브랜치가 1개 이상 필요함
저장소를 처음 초기화하면 워킹 디렉터리는 master 브랜치 하나를 자동으로 생성됨
첫 번째 커밋은 master 브랜치에서 시작함
브랜치 목록 확인 명령어
$ git branch
깃은 master 브랜치를 기준으로 새로운 브랜치를 생성
브랜치는 공통된 커밋을 가리키는 지점
브랜치는 커밋처럼 SHA1 해시키를 가리킴
커밋의 SHA1 해시키는 기억하기가 어렵기 때문에 특정 커밋을 가리키는 별칭을 만드는 것임
이렇게 만든 별칭이 브랜치이다.
브랜치를 생성한다는 의미 : 기존 브랜치 또는 커밋에 새로운 연결 고리를 하나 더 만드는 것과 같음

새 브랜치를 생성하면 포인터만 있는 브랜치가 생성됨
일반적으로 브랜치 생성 명령을 실행하면 현재 커밋을 가리키는 HEAD를 기준으로 생성됨
HEAD는 현재 마지막 커밋을 가리킴
새롭게 브랜치가 생성되면 독립된 공간을 할당함
기존 브랜치의 소스 코드에 영향을 주지 않고 새로운 작업을 할 수 있음
브랜치 생성 = 사용자가 정의한 새로운 사용자 브랜치를 만듬
브랜치 : 또 하나의 개발 분기점
생성개수 제한 X
브랜치 생성 명령어
$ git branch 브랜치이름 커밋ID
branch 명령어 뒤에 브랜치 이름을 인자 값으로 추가함
브랜치 이름만 입력하면 현재 HEAD 포인터를 기준으로 새로운 브랜치를 생성함
직접 커밋 ID 인자 값을 지정하면, 지정한 커밋 ID를 기준으로 브랜치를 생성함
브랜치 이름은 슬래시(/)를 사용하여 계층적인 구조로 만들어서 사용할 수 있음
기호,마침표 - 시작 X
연속적인 마침표, 빈칸, 공백 문자, 물결, 캐럿, 물음표, 별표, 대괄호, 아스키 문자 - 포함 X
브랜치 확인 명령어
$ git branch
브랜치 해시 명령어
$ git rev-parse 브랜치이름 # 현재 브랜치가 어떤 커밋 해시값을 가리키는지 확인
브랜치 세부 사항 확인 명령어
$ git branch -v
브랜치 이동 명령어
$ git checkout 브랜치이름
깃은 하나의 워킹 디렉터리만 가지고 있다. 따라서 다른 브랜치에서 작업하고 싶다면 반드시 브랜치를 변경해서 워킹 디렉터리를 재설정해야한다.
장점 : 빠르게 포인터를 이용하여 브랜치를 이동할 수 있다는 점
원리
HEAD 정보는 항상 변경된 브랜치의 마지막 커밋을 가리킴
브랜치가 이동하면 HEAD 포인터도 함께 이동함
이전 브랜치로 이동 명령어
$ git checkout -
워킹 디렉터리 정리
체크아웃을 사용하여 브랜치를 이동할 때 주의해야 함
현재 작업하고 있는 워킹 디렉터리를 정리하고 넘어가야 함
워킹 디렉터리 안에서 작성하던 내용이 있고, 커밋을 하지 않았다면 체크아웃할 때 경고가 발생함.
워킹 디렉터리에서 작업하다 커밋하지 않고 남겨 둔 상태에서 다른 브랜치로 checkout하면 이처럼 브랜치 이동이 제한된다.
깃은 향후 충돌을 방지하려고 워킹 디렉터리에 작업이 남아 있다면 경고 메세지를 보여 주고 브랜치를 변경할 수 없게 제한한다.
브랜치 로그
로그를 출력할 때 브랜치 흐름도 같이 보려면 --graph 옵션을 함께 사용한다.
명령어, 옵션
$ git log --graph --all # 모든 로그를 출력함
깃은 마지막 커밋을 가리키는 HEAD 포인터를 부모 커밋으로 대체하여 사용
브랜치를 이동하면 HEAD 포인트도 이동됨
브랜치가 여러 개면 HEAD 포인트도 여러 개임
브랜치마다 마지막 커밋 ID를 가리키는 HEAD 포인터가 하나씩 있음
상대적 위치
HEAD를 기준으로 상대적 커밋 위치도 지정할 수 있음
상대적 커밋 위치를 지정할 때는 캐럿(^)과 물결(~) 기호를 같이 사용함
AHEAD, BHEAD
원격 저장소와 연동하여 깃을 관리한다면 브랜치마다 HEAD가 2개 있음
(로컬 저장소 브랜치의 HEAD 포인터, 원격 저장소 브랜치의 HEAD 포인터)
둘은 물리적으로 서로 다른 저장소임
두 저장소의 마지막 커밋 위치가 일치하지 않을 수 있음
AHEAD, BHEAD는 서로 다른 저장소 간 HEAD 포인터의 위치 차이를 의미함
AHEAD
서버로 전송되지 않은 로컬 커밋이 있는 것

로컬 저장소의 HEAD 포인터를 기준으로 로컬 브랜치에 있는 커밋이 서버의 커밋 개수보다 많은 경우
BHEAD
로컬 저장소로 내려받지 않은 커밋이 있는 것

다른 개발자가 코드를 수정하여 원격 저장소의 커밋이 자신의 로컬 저장소보다 더 최신 상태인 것을 의미함
자동 이동 옵션
$ git checkout -b # 브랜치 생성과 이동을 한번에!
이전 커밋으로 checkout하는 명령어
$ git checkout HEAD~1 # 현재의 한 단계 전
여러 단계 이전으로 이동하고싶으면 ~뒤의 숫자만 바꾸자.
리모트 브랜치
원격 저장소에 생성한 브랜치
로컬 저장소의 feature 브랜치를 원격 저장소의 function 브랜치로 push
$ git push -u origin feature:function # 다른 이름으로 브랜치 전송
업스트림 트래킹
업스트림(upstream) : 브랜치 추적을 다르게 표현한 것
업스트림 트래킹 : 로컬 저장소의 브랜치와 원격 저장소의 브랜치는 업로드할 수 있도록 매칭

트래킹 브랜치(업스트림)는 리모트 브랜치와 로컬 브랜치를 연결해 주는 중간다리 역할
트래킹 브랜치 목록 확인 명령어
$ git branch -vv # 트래킹 브랜치 목록 확인 명령어
업스트림 동작을 위한 트래킹 브랜치를 직접 명령어를 실행하여 생성하기
$ git checkout --track origin/브랜치이름 # 새로운 업스트림 만들기
원격 브랜치 복사 명령어
$ git checkout -b 새이름 origin/브랜치 이름
# 생성된 원격 저장소의 리모트 브랜치를 이용해 로컬에도 새로운 브랜치를 생성하여 동기화
업스트림을 직접 설정하면 원격 저장소로 트래킹 브랜치가 설정됨
$ git branch -u origin/브랜치이름
기존 브랜치를 특정 원격 브랜치로 추적함
$ git fetch # 서버의 브랜치 정보 갱신
$ git branch -r # 원격 브랜치 목록
깃의 push 작업은 로컬 저장소의 파일들을 원격 저장소로 전송함
파일뿐만 아니라 브랜치 정보와 커밋까지 모두 전송함
처음에는 커밋과 브랜치를 푸시하는 데 업스트림 설정이 필요함
원격 저장소 연결만으로 업스트림이 자동으로 설정되지는 않음
처음에는 수동으로 트래킹 브랜치와 업스트림 설정을 해야함 (명령어)
$ git push --set-upstream origin master
브랜치 페치
리모트 브랜치 페치는 일반적인 커밋 페치와 동일
리모트 브랜치가 페치되면 깃은 단순히 원격저장소별칭/브랜치 포인터만 생성
원격 저장소에서 페치된 커밋들을 새로운 로컬 브랜치로 반영하려면 병합 명령을 실행해야함
$ git merge 원격저장소별칭/브랜치이름
브랜치 삭제
해당 브랜치 내용과 커밋을 모두 삭제하면 됨
주의할 점 : 현재 자신이 있는 브랜치는 삭제 X
일반적인 삭제 방법
브랜치 삭제할때는 -d 옵션 사용
$ git branch -d 브랜치이름
-d 옵션은 스테이지 상태가 깨끗할 때만 삭제를 허용함
워킹 디렉터리에 작업한 기록이 있거나 add 명령어로 스테이지의 인덱스가 변경된 상태라면 삭제 X
병합되지 않은 브랜치는 -d 옵션으로 삭제 X
강제 삭제 방법
$ git branch -D 브랜치이름
-D 옵션으로 강제로 삭제
리모트 브랜치 삭제 방법
$ git push origin --delete 리모트브랜치이름