브랜치.. 깃허브에서 가장 중요한 핵심 기능이다..
우리가 깃으로 버전 관리를 시작하면 기본적으로 master라는 브랜치가 만들어진다.사용자가 커밋할 때마다 master 브랜치는 최신 커밋을 가리키는데, 쉽게 말해서 브랜치는 커밋을 가리키는 포인터랑 비슷하다고 보면 된다.
여기에서 새로운 브랜치를 만들게 되면 기존의 master(main이라고 함) 브랜치는 유지한 채로, 지금까지의 작업에 추가로 다른 작업들을 수정하는 새로운 파일을 만들 수 있다.
이 과정을 브랜치라고 한다.
원하는 작업을 다 끝냈으면 다시 병합merge 한다.
위의 브랜치 과정을 직접 git bash에서 실습해보자.
아래는 지금까지 해왔던 과정이다.
mkdir manual로 파일을 만들어서 cd로 작업 디렉토리를 옮기고, init한다음 수정한 텍스트들을 add로 스테이징, commit으로 스테이지에 있던 파일들의 버전을 생성시키면서 repository에 저장시켰다.
(굳이 mkdir할 필요 없이 git init 뒤에 저장소 이름을 쓰는 것으로 디렉토리 만들고 초기화를 한번에 할 수 있다.
또한 $ git add . 처럼 add 뒤에 마침표를 하나 추가하는 것으로 현재 저장소에서 수정된 파일을 전부 스테이지에 올릴 수 있다.)

$ git branch 명령어를 사용하는 것으로 깃에다 브랜치를 만들 수 있다.
현재 브랜치에서 다른 브랜치로 이동하고 싶을 때
$git checkout 브랜치이름
log 명령어를 통해서 master 브랜치에서 apple 브랜치로 분기하기 전까지 작업했던 커밋들은 그대로 apple 브랜치에 복사된 것을 확인할 수 있다.
브랜치 정보 확인
여러 브랜치에서 각각 커밋이 이루어질 때 커밋끼리 어떤 관계를 하고 있는지 알기 위해서
$ git log --oneline --branches
이 명령어로 각 브랜치의 커밋을 확인할 수 있다.
현재 head가 가리키고 있는 브랜치는 apple이고, master의 최신 커밋은 work3이다.
시각적으로 보기 쉽게 그래프 형태로 표시하려면
$ git log --oneline --branches --graph
혹시 현재 브랜치에서 어떤 수정이 이루어졌는지 확인하고 싶다면 브랜치 사이에 점 두개 .. 를 찍는다.
의미는 왼쪽 브랜치를 기준으로 오른쪽 브랜치와 어떤 점이 다른지 비교한다.
(branch1에는 없고 branch2에만 있는 커밋 보여줌)
$ git log branch1..branch2
브랜치 병합
지금까지의 상황은
HEAD가 master 브랜치를 가리킴 >> master 브랜치가 work1 커밋을 가리킨다.
이 상황에서 여기에 새로운 브랜치를 만들면, 이 브랜치는 work1 커밋을 가리킨다.
하지만 오해하면 안되는게, 새로운 브랜치가 work1을 가리키는 것이지 master 브랜치에 수정을 한 것은 아니다.
지금 상황에서 새로 파일을 수정하면 master(main)브랜치는 수정된 파일 work2를 가리키고, 새로운 브랜치는 여전히 work1을 가리킨다.
이제 new branch로 checkout하고 파일을 수정(new branch work1)하고 스테이징 후 커밋해보자.
new branch로 checkout한 시점에서 HEAD는 new branch를 가리키고 있고, checkout한 new branch는 new branch work1커밋을 가리키고 있다.
master 브랜치는 여전히 work2커밋을 가리킨다.
이제 새로운 브랜치의 내용을 master브랜치에 병합시켜보자.
master에 병합하기 위해 우선 master 브랜치로 checkout 시킨다.
이 상황에서 merge명령어를 통해 브랜치를 병합시킨다.
$ git merge 브랜치이름
checkout으로 master 브랜치로 이동한 다음, master work2 커밋은 new branch work1 커밋과 합쳐졌고,
현재 master 브랜치는 merge branch work 커밋을 가리키고 있다.
대략 이런 과정으로 merge가 일어나는데..
merge의 경우를 두 가지로 나눠볼 수 있다.
첫 번째는 같은 문서에서 다른 위치를 수정했을 때 병합하는 경우.
두 번째는 같은 문서에서 같은 위치를 수정했을 때 병합하는 경우가 있다.
첫 번째의 경우는 무리 없이 문서 안에서 자동으로 합쳐진다.
하지만 두 번째의 경우 CONFLICT 메세지가 나타난다. 병합하는 동안 충돌이 발생했다는 뜻이다.
충돌이 생긴 문서는 자동으로 합쳐질 수 없기 때문에 사용자가 직접 충돌 부분을 해결한 후에 커밋해야 한다.
문제를 해결하기 위해 work.txt 파일을 열어보자.
그럼 우리가 기존에 txt있던 내용과 조금 달라진 것을 확인할 수 있다.
HEAD 밑의 내용은 현재 master 브랜치에서 수정한 내용이고, 그 밑에 있는 내용은 병합할 브랜치에서 수정한 내용이다.
원하는 내용을 수정했으면, HEAD나 o2표시, 꺾쇠표시랑 가로줄 == 은 삭제하고 저장 후 편집기를 종료한다.
이렇게 문제를 해결했으니, 수정한 파일을 다시 스테이지에 올리고 커밋하면 된다.
병합이 끝난 브랜치 삭제하기
이제 필요없어진 브랜치를 삭제할 수 있지만, 삭제한 후에도 이 브랜치와 같은 이름의 브랜치를 만들면 예전 내용을 다시 볼 수 있다. 로컬 저장소에서 완전히 없애는 것이 아니라 깃의 흐름에서 잠시 감추는 것이라고 생각하면 된다.
브랜치를 삭제하기 위해서는 현재 브랜치를 master 브랜치로 checkout한 후에 -d 옵션을 써서 삭제한다.
$ git branch -d 삭제할 브랜치
reset과 checkout으로 프로그램 관리하기
이전 포스팅에서 reset 명령은 master 브랜치에 있던 여러 커밋 중 하나를 골라서 되돌아갈 수 있었다.
https://guhonga.tistory.com/89
간단하게 git이랑 명령어 소개
처음 깃허브를 접해봤을 때가 게임 개발 동아리였는데.. 그 땐 git이 뭔지도 정확히 몰랐고 github desktop이랑 git bash랑 너무 달라서 다른 사람이 말하는 것이 이게 맞나 많이 당황했던 기억이 있다..
guhonga.tistory.com
이제는 상황이 달라졌다. 아까 브랜치의 경우를 다시 보자.
브랜치가 여러 개일 때 reset 명령은 현재 브랜치가 아닌 다른 브랜치에 있는 커밋을 골라서 최신 커밋으로 지정할 수 있다.
예를 들어 위 그림의 new branch에 있는 상태에서 master 브랜치에 있는 커밋을 new branch의 최신 커밋으로 지정할 수 있다.
사용 방법은 log에서 나오는 커밋의 커밋 해시를 reset 명령어 뒤에 입력한다.
$ git reset 커밋해시
이렇게 하면 위 그림의 경우, new branch의 최신 커밋이 master 브랜치의 최신 커밋 master work2 커밋으로 바뀌었다.
그리고 HEAD는 여전히 new branch를 가리키고 있다.
이 경우, new branch work1은 연결이 끊어지면서 삭제된다.
정리하자면 checkout 명령은 HEAD를 제어해서 브랜치를 이동할 수 있고,
reset 명령은 HEAD가 가리키고 있는 브랜치의 최신 커밋을 원하는 커밋으로 지정할 수 있다.
수정중인 파일 감추고 되돌리기
파일을 수정한 채 커밋하지 않은 경우, 다른 파일들과 함께 커밋일 될 수도 있고 계속 경고 메세지가 나타나기 때문에 커밋하지 않고 잠시 감춰둘 수 있다.
그리고 필요한 작업들을 끝낸 후, 다시 감춰둔 파일들을 꺼내오면 된다.
이와 같은 작업은 git stash 명령어를 통해서 이루어진다.
그 전에, 이 명령을 사용하려면 우선 파일이 tracked 상태여야 한다. 즉, 한 번은 커밋한 상태여야 한다.
이렇게 여러 파일을 수정한 후 따로 보관할 수 있으며, 감춘 파일들은 $ git stash list에서 확인할 수 있다.
가장 최근에 담긴 파일은 stash@{0}에 담기고 이전 파일들은 한칸씩 뒤로 밀려난다.
급한 작업을 마친 뒤, 파일을 꺼내오고 싶다면 stash 명령 뒤에 pop을 추가하면 stash list에서 가장 최근 항목을 되돌린다.
$ git stash pop
이외에 git stash apply 명령어는, stash list에서 가장 최근 항목을 되돌리지만 저장했던 내용은 그대로 남겨둔다.
git stash drop 명령은 stash list에서 가장 최근 항목을 삭제한다.