[Git] 브랜치
★용도별로 다양한 갈래의 버전을 관리해야 할때 이 기능을 사용할 수 있다.
★한 소스가 상황에 따라 두가지 소스로 분기되어 업데이트 되는경우 branch를 만든다 라고 한다. 분기된 branch는 나중에 합쳐질 수도 있다. Default는 master branch
★git branch : branch들의 목록을 조회
★git branch “branch이름” : branch를 생성, 생성하는 타이밍에는 현재 사용중인 branch의 상태를 새 branch가 복사하게 된다.
★git branch -d “branch이름” : branch 삭제
★git checkout “branch이름” : 해당 branch로 branch변경
★git checkout -b “branch이름” : branch생성 + 전환
★branch의 원리 : commit을 하면 .git폴더에 refs/heads/master파일이 생성된다 logs/HEAD의 파일은 이 파일을 가리키고 있다. 이 파일의 내용에는 해당 commit을 가리키는 내용이 있다. 즉 HEAD라는 파일을 가지고있고, 이 파일은 refs/heads/master라는 파일을 가리키고 있고, 이 파일은 가장 최근의 commit의 ID를 가지고 있기 때문에 가장 최근의 commit을 알수있다. 그래서 git log를 하면 우리에게 알려줄 수 있는 것이다. 즉 branch는 refs/heads안에있는 파일을 의미한다는것을 알 수 있다.
★git checkout exp로 branch를 전환하면 HEAD파일의 ref내용이 exp로 바뀐다. 이제 어떤 파일의 내용을 바꾼 후 commit을 하면 refs/heads/master와 refs/heads/exp가 가리키는 내용이 다르게 된다. 서로 각자 commit을 가지게 된다는 뜻.
★reset과 checkout의 원리 : git reset –hard ID로 commit을 reset시켜보면 .git폴더의 ORIG_HEAD파일의 내용이 reset된 commit을 가리키고 있다. 이 파일은 reset과 같은 위험한 명령을 실행하기전에 현재의 최신 commit을 저장해놓은뒤 해당 명령을 실행하기 위한 파일이다. 그래서 git reset –hard ORIG_HEAD를 입력하면 다시 reset을 취소할 수 있게 된다. 또 logs/refs/heads/master의 내용을 보면 reset시 해당 커밋이 삭제된게 아니라, 최신 커밋이 바뀌었을 뿐이라는 것을 알 수 있다. 즉 reset한다고 commit이 삭제되는게 아니라 최신 커밋이 바뀌었을 뿐이고, 이 파일은 이러한 사건들을 저장해 놓는 파일이다. git reflog를 입력해보면 지금까지의 사건들과 커밋들이 기록되어있다. 이를 이용해서도 복구를 할 수 있음
★git checkout 커밋ID를 이용해 HEAD가 branch가 아니라 직접 commit을 가리키게도 할 수 있다. 이 경우 detached된 상태라고 한다.
★branch 병합하기(exp를 master에 병합하기) : master로 checkout하고 git merge [병합할 브랜치 이름]한다. 그럼 새로운 commit이 만들어지고, 이 commit에 두 branch가 합쳐지게 됨
★브랜치와 Merge의 기초 문서 [참조링크][merge-link]
★Merge충돌 : Merge시 파일이 다르면 자동으로 합쳐준다. 그러나 같은 파일을 가지는 두 branch가 같은파일의 같은 부분을 서로 다르게 수정하고 merge를 하면 충돌이 생긴다. git status해보면 충돌위치를 알아낼 수 있다. 해당 파일을 열어서 충돌난 부분을 수동으로 처리해주고 git add 해주면 Merging이 완료된다
★conflict, merge의 원리 : 서로 다른 branch에서 같은 파일의 같은 부분을 수정한 뒤 merge로 branch를 병합하면 conflict(충돌)이 발생해 자동으로 병합할 수 없게 된다. 충돌이 발생하면 .git/index에 같은파일이 여러부분을 가리키게 된다. 이를 해결하기 위해 병합을 전문적으로 해주는 툴을 사용할 수 있다(예를들어 kdiff3). git config –global merge.tool kdiff3로 세팅을 한뒤 git mergetool을 입력하면 사용할 수 있다. 물론 오픈소스이므로 설치 후 사용해야 한다.
★2 way merge VS 3 way merge
Base : 두 branch가 공유하던 파일의 내용
Me : 내 branch에서 파일의 내용을 수정함
Other : 다른 branch에서 파일의 내용을 수정함
Me Base Other
A A - (Other만 A부분을 삭제)
B B B (둘다 손 안댐)
1 C 2 (나는 C를 1로, Other는 2로바꿈)
- D D (나만 D부분을 삭제)
★2 way merge
Me Base Other 2 way merge
A A - ?
B B B B(같은 부분은 내버려 둠)
1 C 2 ?
- D D ?(일치하지 않는 모든 부분에서 충돌 일어남)
★3 way merge
Me Base Other 3 way merge
A A - -(내가 수정하지 않은 경우 다른사람이 수정한것으로 덮어씌움)
B B B B(같은 부분은 내버려 둠)
1 C 2 ?(셋다 다르면 충돌)
- D D -(내가 수정했고 다른사람이 안했을 경우 내가 수정한대로 놔둠)
★stash : 하던 작업을 commit하기전에 다른 branch로 checkout해야할때 현재 branch의 상태를 일단 임시저장해놓을때 사용한다.
★git stash : 현재 작업중인 내용을 임시저장시킨다. 한번이라도 add되지 않은 파일에는 적용되지 않는다.
★git stash apply : 임시저장된 가장 최근의 stash내용을 복구시킨다
★git stash list : 임시저장된 내용들을 확인한다.
★git reset –hard HEAD : stash를 초기화 한다. list에서 사라지지는 않음
★git stash drop : 가장 최신의 stash를 삭제한다.
★git stash pop : git stash apply + git stash drop
[merge-link] : https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EC%99%80-Merge-%EC%9D%98-%EA%B8%B0%EC%B4%88