github branch는 프로젝트에서 이전 기록을 관리하고 여러가지 겹치는 내용을 분리해서 관리하다가 내용을 합쳐야 하면 합칠 수 있는 기능들을 가지고 있다. git이 branch라는 기능을 가지고 있기 때문에 혼자(Local 영역)에서 프로그래밍을 할 때도 유용하고, 팀원들과 코드를 공유하면서 코드를 수정할 때도(Remote 영역) 유용하다.
우선 git은 branch 마다 각각의 snapshot을 가리키는 포인터 역할을 해서 만약 내가 수정한 내용을 다시 이전내용으로 돌리고 싶으면 해당 branch로 checkout(이동) 하면 된다. 아래는 각각의 Tree Data가 어떤 snapshot을 가리키는지 보여준다. 참고로 Tree Data는 이전의 Tree Data를 기록해주는 기능 즉 자신의 조상(Ancestor)을 가리키는 포인터를 가지고 있다. 그래서 가장 오른쪽에 있는 Tree data가 최근의 데이터이다. 이러한 Tree Data는 commit을 완료했을 경우 생겨난다. (staged 상태에서는 아직 생성 안된거다.)

위와 같은 구조를 가진 Tree Data를 가리키는 포인터를 만들어 주면 해당 상황의 데이터를 저장하는 셈이 되는 것이다. 따라서 그 포인터의 역할을 하는 branch는 우리가 만들어 주어야 한다.(기록된 데이터를 쉽게 이동할 수 있도록 만든 것)
이때 우리는 HEAD와 Branch pointer을 구별해야 한다.

HEAD는 실제 작업공간, master는 하나의 branch다. HEAD는 branch를 이동하면서 작업 공간을 바꿀 수 있다. master을 HEAD와 헷갈리지 않았으면 좋겠다.
이제 Local 영역과 Remote 영역을 나누어 Branch를 설명해 볼 것이다.
branch를 만들어 보자.
git branch testing
아래와 같이 만든거다.

Tree data의 주소는 임의로 설정한 것이다. 참고로 지금 HEAD는 master을 가리키고 있다. 이때의 testing branch는 master와 같은 위치에 있기 때문에 어떤 branch를 HEAD로 설정해도 작업공간이 같다.
자, 이제 HEAD를 testing branch를 가리키도록 바꿔보자.
git checkout testing
만약
git branch testing과git checkout testing을 동시에 하고 싶다면 checkout에 옵션 -b를 넣은 git checkout -b testing을 하면 된다.
그런다음 git의 project에 새로운 파일을 생성하고 commit하자!
git commit -m "made a change"
다음과 같이 master branch는 이전의 data를 가리키고 testing branch만 하나 앞서 있다. (1 ahead)

그림으로 나타내면 다음과 같다.

그리고 master branch를 HEAD로 이동 시키면 저장소 데이터가 이전으로 돌아갔다는 것을 확인할 수 있을 것이다. (만든 파일이 없었던 상태)
git checkout master
그리고 그 상태에서 다른 파일을 만들어보자! 그다음 commit을 시키면 아래와 같은 상태가 될 것이다.

위 그림과 같은 상태를 bash에서 확인하려면 다음의 명령어를 입력하라.
git log --oneline --decorate --graph --all
git log --oneline --decorate
# graph로 표현되지 않고 HEAD가 가리키는 Branch 까지만
# 데이터 구조가 출력됨

이 상태에서 갈라진 두 branch를 merge 해보자.
merge는 branch로 만든 두 파일을 합쳐버린다. 각각의 branch는 지금 만든 파일이 각각 한 개가 있는 경우이다. 현재 HEAD가 master을 가리키고 있으므로 다음과 같은 코드를 작성한다.
git merge testing

합쳐져서 작업공간에 두 파일이 공존한다.
FAST Forwarding->merge하는 대상이child일 경우
근데 대부분 수정할 때 같은 파일을 수정하면 어떻게 되냐는 질문이 생긴다. 이 경우를 Conflict라고 한다.

Conflict를 설명하기 위해change1, change2 branch를 만들었다. 두branch는 각각 같은 파일의 내용을 다르게 수정하였다. (내용을 같게 수정하면conflict는 발생하지 않는다.) 이후에master branch로checkout해서change1과merge(fast_forwarding)시켰다. 따라서master은change1을 가리킨다.
이때는 merge되지 않고 git status를 이용해 conflict난 파일을 확인할 수 있다. 그래서 우리는 이런 파일들을 수동으로 수정해야 한다. 그 해당 파일을 열면 다음과 같이 나온다.

====을 경계로 <<<<[HEAD] 아래 부분은 Head pointer가 가리키는 부분의 파일에서 쓴 내용이고 >>>> change2부분은 branch change2에서 수정한 내용이다. 따라서 이를 합쳐서 다음과 같이 수정한 후,

다시 commit 하면 다음과 같이 나타난다.

이제 change2 branch가 쓸모 없어졌으니 삭제하자.
git branch -d change2

git을 관리하면서 branch의 정보를 알고 싶다면 아래의 명령어를 직접 입력해서 어떤 정보가 나오는지 확인하라.
git branch -v
git branch --merged
git branch --no-merged
참고로 현재 checkout(HEAD)한 branch에 merged 되지 않은 branch는 -d 옵션으로 삭제가 불가능하고, 강제로 삭제하려면 -D 옵션을 이용해야 한다.
우리는 사람들과 결국 코드를 공유하기 때문에 remote 저장소를 이용해서 코드를 공유해야 한다.
git remote show [remote]
위 명령어는 모든 remote된 branch를 나타낸다.
중요한 것은 remote branch와 local branch는 서로 다르다는 것이다. git에서 원래는 없었던 branch를 fetch해서 받아오면 local의 branch랑 연결해주는 일련의 명령어를 수행해야 한다는 사실을 기억하라.
remote branch는 다음과 같이 표현된다.
[remote]/[branch]
ex ) origin/master
우리는 local영역에서 수정하고 remote 저장소로 push하게 된다. 만약 local영역에서 수정을 여러번 하고 commit 후에는 아래와 같은 구조로 branch를 갖게 될 것이다.

어, 근데 이때 다른 팀원도 같은 branch를 수정해서 내가 git fetch origin으로 그 정보를 받아왔다면 아래 그림과 같은 상황이 온다.

만약 git remote add로 다른 저장소가 추가되었고, 이를 fetch한다면 다음과 같은 구조가 될 것이다.

수정한 내용을 push 하고 싶다면 이미 배운 내용을 적용하면 된다.
git push [remote] [branch]
ex ) git push origin master
이를 보면 다른 저장소에 다른 branch를 push할 수 있다는 것을 알 수 있다.
만약 다른 팀원이 branch를 수정해서 내가 그 내용을 fetch해서 받아오는 상황이라면, remote branch가 생겨날 것인데, 이 remote branch를 바로 받아와서 local영역 branch로 생성하는 방법은 여러가지가 있다.
이를 Tracking Branch 라고 한다.
참고로 만약
git을clone하게 되면 자동으로origin/master branch가local영역의master branch를tracking하게 된다.
git checkout -b serverfix origin/serverfix
git checkout --track origin/serverfix
# 두 명령어는 같은 역할을 한다. serverfix라는 branch를 만들어 tracking 한다.
git checkout -b sf origin/serverfix
# 위 명령어는 sf라는 이름으로 local branch를 생성한다.
git checkout serverfix
# 위 명령어는 remote가 딱 하나 있고 해당 branch가 없을 때
# 자동으로 맨 위 두 명령어와 같은 역할을 해준다.
원래 local에 있던 branch가 remote branch를 출력하게 하려면 다음 명령어를 이용하라.
git branch -u origin/serverfix
이러한 local branch 내용이 remote된 것과 몇 개의 data commit이 앞서 있거나 뒤쳐져 있고 연결되어 있는지 확인하려면 아래의 명령어를 이용한다.
git branch -vv
ex result)
iss53 7e424c3 [origin/iss53: ahead 2] forgot the brackets
master 1ae2a45 [origin/master] deploying index fix
* serverfix f8674d9 [teamone/server-fix-good: ahead 3, behind 1] this should do it
testing 5ea463a trying something new
이는 마지막 fetch된 결과와 비교하므로 최신과 비교하려면 fetch --all이후에 명령어를 이용하라.
git push에 delete명령어를 사용하여 해당 이용이 끝나고 쓸모없어진 branch는 삭제시킬 수 있다.
git push origin --delete serverfix
다음으로는 Branch의 Workload 2가지를 알아볼 것이다.