도서 : Do it! 지옥에서 온 문서관리자 깃&깃허브 입문
버전 관리 시스템에서 브랜치(Branch)란?
- 나무가 가지에서 새로운 줄기를 뻗듯, 여러 갈래로 퍼지는 데이터 흐름을 가리키는 말.
- 깃에서 버전관리를 시작하면 기본적으로 master라는 브랜치가 만들어짐
- 커밋할 때마다 master 브랜치는 최신 커밋을 가리킨다. 즉, 브랜치 = 커밋을 가리키는 포인터
새로운 브랜치를 만들면?
- 기존에 지정한 파일을 master 브랜치에 그대로 유지하면서 기존 파일 내용을 수정하거나 새로운 기능을 구현할 파일을 만들 수 있다.
- master 브랜치에서 뻗어 나오는 새 브랜치를 만드는 것을 분기(branch)한다고 함.
- 새 브랜치에 있던 파일을 원래 master 브랜치에 합치는 행위를 병합(merge)한다고 한다.
[실습] 브랜치 만들기
1. 사전 설정
- 새로운 디렉터리 생성 후 git init
- work.txt 생성
- 커밋
- work.txt 파일을 두번 더 커밋
2. 새 브랜치 만들기
git branch 브랜치이름
master 브랜치 앞에 * 표시는 현재 우리가 작업하고 있는 브랜치를 의미한다.
브랜치를 추가한 후 커밋 로그 화면은 위와 같다.
저장소에 master, apple 이라는 2 개의 브랜치가 있고, HEAD -> master이므로, 현재 작업중인 브랜치는 master이다.
3. google 브랜치와 ms 브랜치 추가 생성
[실습] 브랜치 사이 이동하기
각 브랜치를 오가면서 작업할 수 있어야 함.
1. git log 통해서 로그 확인
master, ms, google, apple 브랜치가 work 3 커밋 상태에서 만들어진 것을 확인 가능.
해당 브랜치들 모두 최신 커밋 상태가 work 3이다.
2. work.txt 파일 수정 후 커밋
3. 로그 확인, --oneline 옵션 추가해서 확인할 것.
--oneline 옵션: 한 줄에 한 커밋씩 나타남. 커밋 간략 확인
최신 커밋인 master content 4는 master 브랜치에만 적용.
나머지는 아직 work 3 상태이다.
4. 브랜치 이동
git checkout 브랜치이름
apple 브랜치로 이동하는 것을 "apple 브랜치로 체크아웃한다" 라고 말함.
경로 끝에 (apple)을 볼 수 있다. 현재 브랜치가 apple이라는 의미.
최신 커밋 해시에서 HEAD가 apple을 가리킨다.
[실습] 새로운 브랜치에서 커밋하기
1. apple 브랜치에 있는 work.txt 파일 수정 + 새로운 파일 생성 (apple.txt)
2. 스테이징 + 커밋
git add . # 수정된 두 개의 파일을 한번에 스테이지에 올리기 위한 명령
3. 깃 로그 확인
(HEAD -> apple): 현재 apple 브랜치에 체크아웃한 상태이고, apple 브랜치의 최신 커밋은 "apple content 4" 이다.
※ 각 브린치의 커밋을 함께 볼 수 있는 옵션 --branches
git log --oneline --branches
커밋 해시마다 오른쪽에 (HEAD -> apple), (master), (ms, google) 표시.
이 부분을 보고 어떤 브랜치에서 만든 커밋인지 구별할 수 있다.
master 브랜치의 최신 커밋은 "master content 4" 이고, ms 브랜치와 google 브랜치의 최신 커밋은 "work 3"
※ 브랜치와 커밋의 관계를 보기쉽게 그래피 형태로 표시하는 --graph 옵션
git log --oneline --branches --graph
apple 브랜치의 커밋과 master 브랜치의 커밋이 같은 부모 커밋을 가지고 있다.
=> apple과 master 브랜치는 "work 3" 커밋까지는 같고, 그 이후부터 브랜치마다 다른 커밋을 만들었다.
※ 브랜치 사이의 차이점
git log branche1..branche2 #왼쪽 브랜치를 기준으로 오른쪽 브랜치와 비교.
master 브랜치에는 없고, apple 브랜치에는 있는 커밋인 "apple content 4"를 보여준다.
이렇게 하면 apple 브랜치에는 없고, master 브랜치에는 있는 커밋인 "master content 4"를 보여준다.
[실습] 브랜치 병합하기
git init 디렉터리명 #디렉터리 만들기 + 저장소 초기화 한번에
1. 새로운 깃 저장소 manual-2 생성
- vim 통해 work.txt 생성 후 커밋
2. o2 브랜치 생성
3. master 브랜치에 mater.txt 생성 후 커밋
4. o2로 체크아웃
5. o2브랜치에 o2.txt 생성 후 커밋
6. 깃 로그로 확인
- 커밋 'work 1'은 master 브랜치와 o2 브랜치가 똑같이 가지고 있다.
- mater 브랜치는 'master work 2' 커밋이 생겼고, o2 브랜치에는 'o2 work 2' 커밋이 생겼다.
7. o2 브랜치에 작업이 다 끝났다고 가정, o2 브랜치의 내용을 mater 브랜치로 병합
- mater 브랜치로 체크아웃 후 진행
git merge 가져올브랜치이름
- 자동으로 VIM 실행. 브랜치를 병합하며 만들어질 커밋의 메시지이다. 자동메시지 or 수정하던가
8. ls -al 사용해보면, o2 브랜치에 있던 o2.txt 파일이 master 브랜치에 합쳐져있다.
9. git log 통해 어떻게 병합되었는지 확인
'o2 work 2' 커밋이 master 브랜치에 병합되면서 'Merge branch o2'라는 커밋이 새로 생겼다.
두 브랜치에서 서로 다른 파일을 병합하는 경우 이렇게 깃에서 간단히 해결 가능.
※ 브랜치 병합 시 편집기 창이 열리지 않게 하려면
git merge 브랜치명 --no-edit
git merge 브랜치명 --edit #편집기 창이 나타나지 않도록 설정했을 때. 다시 편집하려면
[실습] 같은 문서의 다른 위치를 수정했을 때 병합하기
0. 실습을 위한 사전설정
- 새로운 깃 저장소 manual-3 생성
- 파일 work.txt 생성, 중간에 두 줄 공백
- 커밋
- o2 브랜치 생성
1. master 브랜치에서 work.txt 수정 후 커밋
2. o2 브랜츠로 체크아웃한 후 work.txt 수정 후 커밋
3. master 브랜치로 체크아웃 후 병합
- 현재상태: 두 브랜치 모두 work.txt를 수정했지만, 문서 안의 수정 위치는 다르다.
4. 확인
[실습] 같은 문서의 같은 위치를 수정했을 때 병합하기
깃에서는 줄 단위로 변경 여부를 확인한다. 그래서 각 브랜치에 같은 파일 이름을 가지고 있는데.. 같은 줄을 수정했을 때 브랜치를 병합하면 '브랜치 충돌(conflict)'이 발생한다.
0. 실습을 위한 사전설정
- 새로운 깃 저장소 manual-4 생성
- 파일 work.txt 생성, 중간에 한 줄 공백
- 커밋
- o2브랜치 생성
1. 현재 브랜치(master)에서 work.txt 수정 후 커밋
2. o2 브랜치로 체크아웃 한 후 work.txt 수정 후 커밋
3. master 브랜치로 체크아웃한후 o2브랜치 병합
- 자동으로 빔이 열리는 것이 아니라 메세지 출력
- work.txt를 자동 병합하는 동안 충돌(conflict)가 발생했다는 의미.
4. 충돌이 생긴 문서는 자동으로 병합될 수 없음. 사용자가 충돌 부분을 직접 해결한 후 커밋해야 한다.
우선 work.txt를 확인해보자.
'<<<<HEAD' 와 '======' 사이의 내용은 현재 브랜지(master)에서 수정한 내용이다.
그리고 '======'과 '>>>>> o2' 사이의 내용은 o2 브랜치에서 수정한 내용이다.
빔을 켜서 내용을 원하는대로 수정 후 저장하자.
5. work.txt를 스테이징 후 커밋하면 끝.
- o2 브랜치에서 병합한 work.txt 의 충돌을 해결하고 커밋했다.
※ 병합 및 충돌 해결 프로그램
프로젝트 규모가 커질수록 브랜치가 많으므로, 브랜치에서 병합해야할 파일도 많아진다.
깃의 브랜치 병합을 자동으로 처리해주고 충돌을 해결해주는 프로그램들 또한 많다.
병합알고리즘은 2 way merge와 3 way merge가 존재, 이 중 3 way merge가 훨씬 효율적이므로, 이를 지원하는 프로그램을 사용하자.
- P4Merge: 무료이고 , 직관적. 사용이 편리. 병합 기능 뛰어남. 단축기 미지원
- Meld: 무료, 오픈소스. 파일을 비교하는 것 뿐만아니라 직접 편집 가능
- Kdiff3: 무료, 사용편리, 병합기능 뛰어남. 한글이 깨져 보일 수 있다.
- Araxis Merge: 유료. 용량이 큰 파일에서도 잘 동작
[실습] 병합이 끝난 브랜치 삭제하기
더 이상 사용하지 않는 브랜치를 깃에서 삭제하는 방법.
단, 브랜치가 완전히 지워지는 것이 아니기 때문에.. 다시 같은 이름의 브랜치를 만들면 예전 내용을 볼 수 있다.
1. master 브랜치와 o2 브랜치 존재, 여기서 o2 브랜치를 삭제할 것.
- master 브랜치로 체크아웃 한다.
2. git branch에 -d 옵션을 줘서 삭제한다.
git branch -d 삭제할브랜치명
브랜치를 삭제한다는 것은 완전이 저장소에서 없애는 것이 아니라. 흐름 속에서 감추는 것이다.
브랜치 관리하기
[실습] 브랜치가 여러개일 때 reset 명령 사용방법
- 현재 브랜치가 아닌 다른 브랜치에 있는 커밋을 골라서 최신 커밋으로 지정할 수 있다.
- EX) 현재 sub 브랜치에 있는 상태에서 master 브랜치에 있는 'c2' 커밋을 sub 브랜치의 최신 커밋으로 지정
0. 사전설정
- c1 커밋: c1.txt
- c2 커밋: c1.txt, c2.txt
- s1 커밋: c1.txt, s1.txt
1. git reset 명령 다음에 c2 커밋 해시를 입력
git reset 8c249d7
2. 결과
sub 브랜치의 최신 커밋이 master 브랜치의 최신 커밋인 c2로 바뀌었다. HEAD는 그대로 sub을 가리키고 있음.
원래 가리키고 있던 s1 커밋은 삭제됨.
sub 브랜치의 최신 커밋이 c2로 바뀌었을 뿐 작업 트리의 파일들이 삭제된게 아니다.
즉, c2 커밋에 있었던 c2.txt는 sub 브랜치에 없었기 때문에 deleted 라고 뜨고.. c2 커밋에는 s1.txt가 없었기 때문에 스테이징 하라고 뜨는 것임.
#결론
1) git checkout 명령 통해 HEAD를 제어하여 브랜치 이동 가능
2) git reset 명령 통해 HEAD가 가리키고 있는 브랜치의 최신 커밋을 원하는 커밋으로 지정할 수 있다.
[실습] 수정 중인 파일 감추기 및 되돌리기
- 브랜치에서 파일을 수정하고 커밋하지 않은 상태에서 급하게 다른 파일을 커밋해야 할 때.
- 커밋하지 않은 파일은 걍 작업트리에 둬도 ㄱㅊ지만 자꾸 커밋하라고 해서 귀찮음
- 또한 실수로 다른 파일들과 함께 커밋될 수 있다
▶ 이러한 파일들을 잠시 감춰뒀다가, 당장 해야하는 작업들 끝낸 후 다시 되돌려서 작업하기
0. 사전설정
- st 저장소 초기화
- f1.txt 생성 후 커밋
- f2.txt 생성 후 커밋
1. f1.txt, f2.txt 수정 후 깃 상태 확인
2. 두 파일을 커밋하기 전에, 다른 파일을 수정해야 하는 상황.
커밋하지 않은 수정 내용(f1.txt, f2.txt)을 어딘가에 보관하려면 git stash 명령 사용
- 이전에 나타나던 modified 메세지가 사라짐
- 파일은 그대로 있다 ㅡㅡ
git stash #숨기기
git stash list #stash 목록 확인
가장 먼저 감춘 것은 stash@{0}에 들어있다. 다른 파일이 추가되면 기존 파일은 stash@{1}로 옮겨지고 새로 추가된 파일이 stash@{0}에 채워진다.
▶ 가장 최근에 보관한 것이 stash@{0}에 보관.
▶ stash 스택
9. stash 스택에 있는 파일 꺼내기 위해 pop
got stash pop
'기타' 카테고리의 다른 글
클라우드 서비스(SaaS, PaaS, IaaS, FaaS) 개념 (0) | 2022.10.23 |
---|---|
[Git] 깃허브로 협업하는 방법, 공동작업자 추가, 협업 흐름 (0) | 2022.10.13 |
[Git] Git bash로 깃허브(Github) 연동하기, HTTPS와 SSH (0) | 2022.10.12 |
[Git] Git이란? Git 사용 방법과 명령들 (0) | 2022.10.10 |
[C#] 매개변수 ref와 out (0) | 2022.06.20 |