Keep going

깃과 브랜치 본문

Records/Git Hub

깃과 브랜치

코딩천재홍 2021. 2. 13. 15:01

◆ 브랜치란?

모든 버전 관리 시스템에는 '브랜치'라는 개념이 있다.

브랜치는 원래 나뭇가지라는 뜻으로,

버전 관리 시스템에서는 나무가 가지에서 새 줄기를 뻗듯이 여러 갈래로 퍼지는 데이터 흐름을 가리키는 말로 사용한다.

 

브랜치 기능 살펴보기

- 깃으로 버전 관리를 시작하면 기본적으로 master라는 브랜치가 만들어진다.

- 사용자가 커밋할 때마다 master 브랜치는 최신 커밋을 가리킨다.

- 즉, 브랜치는 커밋을 가리키는 포인터와 비슷하다고 생각하면 된다.

- 새 브랜치를 만들면 기존에 저장한 파일을 master 브랜치에 그대로 유지하면서 기존 파일 내용을 수정하거나 새로운 기능을 구현할 파일을 만들 수 있다.

- 이렇게 master 브랜치에서 뻗어 나오는 새 브랜치를 만드는 것을 분기라고 한다.

[출처] https://miiingo.tistory.com/260

- 새 브랜치에서 원하는 작업을 다 끝냈다면 새 브랜치에 있던 파일을 원래 master 브랜치에 합칠 수 있다. 

- 이렇게 분기했던 브랜치를 master 브랜치에 합치는 것을 '병합 한다'고 한다.

[출처] https://miiingo.tistory.com/260

 


◆ 브랜치 만들기

 

실습 상황 설정하기

- 먼저 디렉터리를 만들고 그 안에 사용 설명서라고 생각하고 텍스트 파일을 하나 만들겠다.

 

1. 터미널 창을 열어 홈 디렉터리에 manual이라는 새 디렉터리를 만들고 해당 디렉터리로 이동한다.

 

2. manual 디릭터리를 저장소로 만들고 ls -al 명령을 사용해서 .git 디렉터리가 만들어졌는지 확인해 보겠다.

 

3. manual 디렉터리 안에 work.txt 파일을 만들고 'content 1'이라는 내용을 입력 후 저장하겠다.

 

4. 방금 만든 work.txt 파일을 스테이지에 올리고 커밋한다. 커밋 메시지는 간단히 'work 1'이라고 하겠다.

 

5. 커밋이 완료되면 다음과 같이 입력해서 커밋 내역을 확인해 보자.

 

6. work.txt 파일을 두 번 더 커밋해 보겠다. 먼저 work.txt 파일에 'content2' 를 추가한 후 'work 2'라는 메시지와 함께 커밋한다.

 

7. 그리고 work.txt 파일에 'content3'를 추가한 후 'work 3'라는 메시지와 함께 커밋한다.

 

8. 커밋이 끝나면 'git log'를 입력해서 커밋 내역을 확인해 보자. 커밋 메시지가 'work 1', 'work 2', 'work 3'인 커밋들이 보인다. master 브랜치가 가장 최신 커밋인 'work 3'를 가리키고 있고, HEAD가 master 브랜치를 가리키고 있다. HEAD는 여러 브랜치 중에서 현재 작업 중인 브랜치를 가리킨다.

여기까지가 초기 사용 설명서를 만드는 작업이었다고 가정하겠다.

이제부터 여러 고객사에게 서로 다른 내용의 사용 설명서를 제공해야 하는 상황이다.

브랜치를 사용하지 않는 다면 각 고객사 디렉터리를 난들고 manual 디렉터리를 복사해서 사용해야 할 것이다.

그러나 브랜치를 사용한다면 간단하게 처리할 수 있다.

 

 

새 브랜치 만들기

직접 브랜치를 만들면서 위와 같은 문제를 어떻게 처리하는지 알아보겠다.

여기에서는 apple.google.ms 라는 고객사가 있다고 가정해 보자.

 

1. 깃에서 브랜치를 만들거나 확인하는 명령은 git branch 이다.

 

2. master라고 나타난다. master는 특별한 브랜치다. 저장소를 만들 때 기본적으로 master 브랜치가 만들어진다.

 

3. 새로운 브랜치를 만들려면 git branch 명령 다음에 만들려는 브랜치 이름을 적는다. 고객사인 apple의 브랜치를 만들어 보겠다.

 

4. apple 브랜치가 만들어져도 화면에는 아무것도 나타나지 않는다. apple 브랜치가 제대로 만들어졌는지 확인하기 위해 git branch를 입력한다.

 

5. master 브랜치 위에 apple 브랜치가 추가된 것을 확인할 수 있다. master앞에 * 표시는 아직 우리가 master 브랜치에서 작업하고 있다는 뜻이다.

 

6. 브랜치가 추가된 후에는 커밋 로그 화면도 다르게 나타난다. git log 명령을 사용해 커밋을 확인해 보자. 그동안 커밋 로그를 확인할 때 (HEAD ->master)라고 표시되던 곳에 apple 브랜치가 추가되면서 (HEAD ->master,apple)로 바뀌어 있다. 이 표시는 저장소에 master, apple 2개의 브랜치가 있고, HEAD -> master이므로 현재 작업 중인 브랜치는 master 브랜치라는 의미다.

 

7. 앞에서와 같은 방법으로 google 브랜치와 ms 브랜치를 만들어 보자. 그리고 git branch 명령으로 저장소 안에 있는 모든 브랜치를 확인해 보겠다.

 

 

브랜치 사이 이동하기 - git checkout

1. git log로 확인해보면 master 브랜치를 비롯해 ms, google, apple 브랜치가 'work 3' 커맷 상태에서 만들어진 것을 알 수 있다. 즉 이것은 master 브랜치 뿐만 아니라 ms와 google, apple 브랜치에도 최신 커밋이 'work 3'라는 뜻이다.

 

2. 현재 우리는 master 브랜치에 있다. 커밋을 하나 만들어서 어떻게 달라지는지 확인해 보자. work.txt 파일 안에 'master content 4'라는 내용을 추가한 후 'master work4'라는 메시지와 함께 커밋해 보겠다.

 

3. master 브랜치에 새로운 커밋이 추가되었는데 로그가 어떻게 바뀌었을가? git log 명령에 --oneline 옵션을 추가해서 확인해 보겠다. --oneline 옵션은 한 줄에 한 커밋씩 나타내 주기 때문에 커밋을 간략히 확인할 때 편리하다.

 

4. 최신 커밋인 'master work 4'는 master 브랜치에만 적용되어 있따. ms와 google, apple 브랜치는 아직 'work3' 커밋 상태이다.

현재 브랜치는 master

master 브랜치의 최신 커밋은 master content 4

ms, google, appple 브랜치의 최신 커밋 work 3

 

5. 현재 브랜치에서 다른 브랜치로 이동하면 어떻게 변하는지를 살펴보겠다. 다른 브랜치로 이동하려면 git checkout 명령 다음에 브랜치 이름을 사용한다. 그래서 apple 브랜치로 이동하는 것을 'apple 브랜치로 체크아웃한다'고 말한다.

6. &위에 나타난 파일 경로 끝에 (apple)이라고 표시될 서이다. 현재 브랜치가 apple 이라는 뜻이다.

 

7. 작업 브랜치를 apple 브랜치로 바꿨을 때 어떤 변화가 생기는지 확인해 보겠다. git log 명령을 사용해서 현재 브랜치의 커밋 로그를 확인한다.

 

8. master 브랜치에서 apple 브랜치를 분기하기 전까지 master 브랜치에 있던 커밋들은 그대로 apple 브랜치에 복사도니 것을 확인할 수 있다. 그리고 최신 커밋 해시에서 HEAD가 apple 을 가리키고 있다.

즉 apple 브랜치의 최신 커밋은 처음 분기될 때인 'work3' 커밋 그대로이다. 그렇다면 work.txt 파일에는 무엇이 있을까? cat 명령을 사용해 work.txt 파일의 내용을 확인해 보자.

 

9. 최신 커밋이 work 3 이기 때문에 content 1 부터 content 3 까지 세 개의 행만 있을 것이다. master 브랜치에서 입력했던 'master content 4' 가 없다. 이를 통해 apple 브랜치가 master 브랜치에서 분기된 이후에 master 브랜치에 추가된 커밋은 apple 브랜치에 영향을 미치지 않았단 것을 알 수 있다.

 

 


◆ 브랜치 정보 확인하기

 

새 브랜치에서 커밋하기

apple 브랜치에 새로운 커밋을 만들어 보겠다. 현재는 apple 브랜치로 체크아웃한 상태이다.

 

1. apple 브랜치에는 work.txt 파일이 있다. 빔에서 이 파일을 열고 'apple content 4'라는 텍스트를 추가하고 저장한다.

 

2. 실제 업무에서는 apple 고객사만을 위한 내용이 담긴 파일도 필요하겠다. apple.txt 라는 새로운 파일도 만든다. 빔에서 apple.txt 문서를 만들고 여기에도 똑같이 'apple content 4'라는 텍스트를 입력하고 저장한다.

 

3. 수정된 2개의 파일을 각각 스테이지에 올릴 수도 있지만 git add 뒤에 마침표(.)를 추가하면 현재 저장소에서 수정된 파일을 한꺼번에 스테이지에 올릴 수 있다. 그리고 'apple content 4'란ㄴ 메시지와 함께 커밋한다.

 

4. 커밋이 어떻게 저장되었는지 git log 명령을 사용해 확인해보겠다.

 

5. 첫 번째 줄에 (HEAD -> apple)이라고 되어 있으니 현재 apple 브랜치에 체크아웃한 상태이고, apple 브랜치의 최신 커밋은 'apple contetnt 4' 이다.

 

6. git log 명령을 사용할 때 다음과 같이 --branches 옵션을 사용하면 각 브랜치의 커밋을 함께 볼 수 있다.

 

7. 결과 화면을 보면 커밋 해시마다 오른쪽 (HEAD -> apple), (master), (ms, google)이라고 표기되어 있다. 이 부분을 보고 어떤 브랜치에서 만든 커밋인지 구별할 수 있다. 즉 master 브랜치의 최신 커밋은 'master content 4'이고, ms 브랜치와 google 브랜치의 최신 커밋은 'work3'이다.

 

8. 브랜치와 커밋의 관계를 좀 더 보기 쉽게 그래프 형태로 표시하려면 git log 명령에 --graph 옵션을 함께 사용한다.

 

9. 커밋 내역 왼쪽에 수직선이 보인다. 이 점선이 커밋과 커밋의 관계를 보여주는 것이다. 그래프를 살펴보면 apple 브랜치의 최신 커밋은 'apple content 4'인데, 점선을 따라 'apple content 4' 커밋의 부모를 찾아가 보면 'work 3' 커밋을 만나게 된다. 즉 apple 브랜치에서는 'work 3' 커밋 다음에 'apple content 4' 커밋이 만들어졌다는 뜻이다.

 

10. master 브랜치도 살펴보면 master 브랜치의 최신 커밋은 'master content 4' 이다. 그리고 수직선을 따라가 부모 커밋을 찾아 보면 'work 3' 커밋이다. apple 브랜치의 커밋과 master 브랜치의 커밋이 같은 부모 커밋을 가지고 있다. 즉 master 브랜치나 apple 브랜치는 'work 3' 커밋까지는 같고 그 이후부터 브랜치마다 다른 커밋을 만들었다는 사실을 알 수 있다.

 

 

브랜치 사이의 차이점 알아보기

브랜치마다 커밋이 점점 쌓여 갈수록 브랜치 사이에 어떤 차이가 있는지 일일이 확인하기 어려워진다. 이럴 때는 브랜치 이름 사이에 마침표 두 개(..)를 넣는 명령으로 차이점을 쉽게 확인할 수 있다. 브랜치 이름과 마침표 사이는 공백없이 입력하며, 마침표 왼쪽에 있는 브랜치를 기준으로 오른쪽 브랜치와 비교한다. 

예를 들어 master 브랜치와 apple 브랜치 사이의 차이점이 무엇인지 확인하려면 다음과 같이 입력한다.

이렇게 하면 master 브랜치에는 없고 apple 브랜치에만 있는 커밋, 즉 'apple content 4' 커밋을 보여준다.

 

 

반대로 apple 브랜치를 기준으로 master와 비교하면 apple 브랜치에는 없고 master 브랜치에만 있는 'master content 4' 커밋을 보여준다.

 


◆ 브랜치 병합하기

만들어진 각 브랜치에서 작업을 하다가 어느 시점에서는 브랜치 작업을 마무리하고 기존 브랜치와 합해야 한다. 이것을 '브랜치 병합' 이라고 한다. 브랜치와 브랜치를 병합 하다 보면 여러 상황이 생길 수 있는데 각 상황마다 병합하는 방법을 알아보겠다. 그리고 병합하면서 브랜치 사이에 충돌이 있을 때 해결하는 방법도 함께 살펴보겠다.

 

서로 다른 파일 병합하기

브랜치 병합은 처음에 공부하기 까다롭기 때문에 새로운 저장소를 만들어서 필요한 브랜치와 커밋만 사용해 연습해 보겠다.

 

1. 터미널 창을 열고 홈 디렉터리로 이동한다. manual-2 라는 깃 저장소를 만들텐데, git init 다음에 디렉터리 이름을 입력하면 새로운 디렉터리를 만들고 저장소를 초기화하는 과정을 한꺼번에 처리할 수 있다. manual-2 디렉터리로 이동한 후 ls-al 명령을 사용하면 .git/ 디렉터리가 만들어진 것을 확인할 수 있다.

 

2. 빔에서 work.txt 파일을 만들고 '1' 이라는 내용을 입력한 후 저장한다. 그리고 'work 1'이라는 커밋 메시지와 함께 커밋한다.

 

3. 이제 'o2'라는 브랜치를 만들어 보겠다.

 

4. 현재 master 브랜치에 master.txt 라는 파일을 하나 더 만들겠다. 빔에서 'master 2'라는 내용을 입력하고 저장한다. 그리고 'master work 2'라는 메시지와 함께 커밋한다.

 

5. 이제 o2 브랜치로 체크아웃한다.

 

6. o2 브랜치에서 o2.txt라는 파일을 만들고 'o2 2' 라는 내용을 저장한다. o2.txt는 'o2 work 2' 라는 메시지와 함께 커밋한다.

 

7. git log 명령을 사용해서 현재 커밋의 상태를 확인해 보자. 커밋 'work 1'은 master 브랜치와 o2 브랜치가 똑같이 가지고 있다. 그 다음으로 master 브랜치에는 'master work 2' 커밋이 생겼고 o2 브랜치에는 'o2 work2' 커밋이 생겼다.

 

8. o2 브랜치에서 작업이 다 끝났다고 가정하고, o2 브랜치의 내용을 master 브랜치로 병합해 보겠다. 브랜치를 병합하려면 먼저 master 브랜치로 체크아웃해야 한다.

 

9. 브랜치를 병합하려면 git merge 명령 뒤에 가져올 브랜치 이름을 적는다. master 브랜치에 o2 브랜치를 가져와 병합하려면 다음과 같이 입력한다.

 

10. 자동으로 빔이 실행되면서 'Merge branch o2' 라는 커밋 메시지가 나타난다. 브랜치를 병합하면서 만들어지는 커밋의 메시지이다. 커밋 메시지를 수정할 수도 있고, 자동 메시지를 그대로 사용해도 된다. 

 

11. ls -al 명령을 사용해 확인해 보면 o2 브랜치에 있던 o2.txt 파일이 master 브랜치에 합쳐졌을 것이다.

 

12. git log --oneline --branches --graph 명령으로 브랜치와 커밋들이 어떻게 병합되었는지 확인할 수 도 있다. 'o2 work 2' 커밋이 master 브랜치에 병합되면서 'Merge branch o2'라는 커밋이 새로 생겼다. 두 브랜치에서 서로 다른 파일을 병합하는 경우 이렇게 깃에서 간단히 해결할 수 있다.

 

# 빨리 감기 병합

master 브랜치에서 브랜치를 분기한 후에 master 브랜치에 아무 변화가 없다면(새로운 커밋을 만들지 않았다면) 분기한 브랜치를 병합하는 것은 간단하다. 분기한 브랜치에서 만든 최신 커밋을 master 브랜치가 가리키게만 하면 되기 때문이다. 이 경우에는 화면에 커밋 해시가 업데이트되었다는 내용과 함께 fast-forward라는 메시지가 나타난다. 이런 병합을 빨리 감기 병합(fast-forward merge)이라고 부른다. git merge 명령의 결과가 단순히 포인터를 움직인 것이기 때문에 따로 커밋 메시지 창은 열리지 않는다.

 

# 브랜치를 병합할 때 편집기 창이 열리지 않게 하려면

앞에서 브랜치를 병합할 때 자동으로 편집기가 실행되면서 커밋 메시지를 추가 작성할 수 있었다. 만약 편집기 창을 열지 않고 깃에서 지정하는 커밋 메시지를 그대로 사용하겠다면 다음과 같이 --no-edit 옵션을 추가한다.

$ git merge o2 --no-edit

 

브랜치를 병합할 때 편집기 창이 나타나지 않도록 설정한 경우, 커밋 메시지를 추가하거나 수정하고 싶다면 병합 명령에 --edit 옵션을 사용한다.

$ git merge o2 --edit

 

 

같은 문서의 다른 위치를 수정했을 때 병합하기

master 브랜치와 o2 브랜치에는 똑같이 work.txt 파일이 있다. 양쪽 브랜치에서 work.txt 문서를 수정하되 서로 다른 위치를 수정한 후 브랜치를 병합했을 때 어떤 결과가 나오는지 확인해 보겠다.

 

1. 홈 디렉터리로 이동한 후 manual-3라는 깃 저장소를 만들고, manual-3 디렉터리로 이동한다.

 

2. 빔에서 work.txt 파일을 만들고 다음과 같이 입력한다. 나중에 work.txt 문서를 수정하고 병합할 것이기 때문에 내용 사이에 두 줄의 공백을 두었다.

 

3. 방금 만든 work.txt를 스테이지에 올리고 커밋한다. 커밋 메시지는 'work 1'이라고 하겠다.

 

4. 'work 1'이라는 커밋을 만들었으므로 o2 라는 새로운 브랜치를 만들어 보겠다. 이제 master 브랜치와 o2 브랜치에는 모두 'work 1' 커밋이 있게 된다.

 

5. 양쪽 브랜치 모두에 있는 work.txt를 먼저 master 브랜치에서 수정하겠다.

 

6. work.txt 문서에는 #title과 content 가 2개씩 있다. 그중에서 첫 번째 content 다음 줄에 master content 2라고 입력한 후 저장한다.

 

7. 수정한 work.txt 를 커밋한다. 커밋 메시지는 'master work 2'라고 하겠다.

 

8. 이제 o2 브랜치의 work.txt 파일도 수정해 보겠다. 먼저 o2 브랜치로 체크아웃하고 work.txt 파일을 불러온다.

 

9. 이번에는 두 번째 'content' 다음 줄에 'o2 content 2'라고 입력하고 저장한다. 

 

10. 수정한 work.txt 파일을 커밋해 보겠다. 커밋 메시지는 'o2 work 2'라고 하겠다.

11. master 브랜치와 o2 브랜치 양쪽에서 work.txt 파일을 수정했지만 문서 안의 수정 위치는 다르다. 이럴 경우 어떻게 해야 할까? o2 브랜치를 master 브랜치에 합치기 위해 master 브랜치로 체크아웃한다.

 

12. git merge 명령을 사용해 o2 브랜치를 master 브랜치로 끌어온다.

 

13. 자동으로 빔이 실행되면서 커밋 메시지가 나타난다. 메시지를 수정할 수도 있고 그대로 사용할 수도 있다. 

 

14. 터미널 창에는 'Auto-merging work.txt'로 시작하는 병합 완료 메시지가 나타난다. o2 브랜치의 work.txt가 master 브랜치의 work.txt와 어떻게 병합되었을까? cat 명령을 사용해 work.txt 파일을 확인해 보자.

 

15. master 브랜치의 수정 내용과 o2 브랜치의 수정 내용이 자연스럽게 하나의 파일에 합쳐진 것을 볼 수 있다. 이렇게 브랜치를 자동으로 합쳐주는 기능이 있어 깃은 더욱 강력한 도구가 된다.

 

 

같은 문서의 같은 위치를 수정했을 때 병합하기

깃에서는 줄 단위로 변경 여부를 확인한다. 그래서 각 브랜치에 같은 파일 이름을 가지고 있으면서 같은 줄을 수정했을 때 브랜치를 병합하면 브랜치 충돌이 발생한다. master 브랜치와 o2 브랜치에서 같은 파일의 같은 위치를 수정한 후 병합해 보면서 어떤 경우에 브랜치 충돌이 생기는지, 그리고 어떻게 충돌을 해결하는지 알아보겠다.

 

1. 홈 디렉터리로 이동한 후 manual-4 라는 깃 저장소를 만들고, manual-4 디렉터리로 이동한다.

 

2. 빔에서 work.txt 파일을 만들고 다음과 같이 입력한다. 나중에 work.txt 문서와 같은 위치를 수정하기 위해 두 내용 사이에 빈 줄을 하나만 두었다.

 

3. 방금 만든 work.txt를 스테이지에 올리고 커밋한다. 커밋 메시지는 'work 1'이라고 하겠다.

 

4. 이제 o2 라는 브랜치를 만든다. o2 브랜치는 만들어 지면서 master 브랜치의 최근 커밋을 가져온다. 즉 브랜치 양쪽에 work.txt가 있다.

 

5. 아직 체크아웃은 하지 않았으므로 현재 브랜치는 master 이다. 먼저 master 브랜치에서 work.txt를 수정하겠다.

 

6. work.txt 문서에는 '# title'과 'content'가 2 개씩 있습니다. 그중에서 첫 번째 'content' 다음 줄에 'master content 2'라고 입력한 후 저장한다.

 

7. 수정한 work.txt 를 커밋한다. 커밋 메시지는 'master work 2'라고 하겠다.

 

8. 이제 o2 브랜치의 work.txt 파일도 수정해 보겠다. 먼저 o2 브랜치로 체크아웃한다. 그리고 work.txt 파일을 연다.

 

9. master 브랜치에서 추가 내용을 입력했던 위치와 같은 곳에 'o2 content 2'라고 입력하고 저장한다.

 

10. 수정한 work.txt 파일을 커밋해 보겠다. 커밋 메시지는 'o2 work 2'라고 하겠다.

 

11. master 브랜치와 o2 브랜치 양쪽에서 work.txt 파일을 수정했지만 문서 안의 수정 위치가 같다. 이럴 경우 어떻게 병합될까? o2 브랜치를 master 브랜치에 병합하기 위해 먼저 master 브랜치로 체크아웃한다.

 

12. git merge 명령을 사용해 o2 브랜치를 master 브랜치로 끌어온다.

 

13. 이전에 git merge 명령을 실행했을 때처럼 자동으로 빔이 열리지 않고 메시지가 나타난다. 이 메시지는 work.txt 를 자동 병합하는 동안 충돌이 발생했다는 뜻이다.

 

14. 충돌이 생긴 문서는 자동으로 병합될 수 없으므로 사용자가 직접 충돌 ㄹ부분을 해결한 후 커밋해야 한다. 충돌이 생긴 work.txt 는 어떻게 되어 있을까? 빔에서 work.txt 를 열어보겠다.

 

15. work.txt의 내용이 좀 특별하게 되어있다. master 브랜치에 있떤 내용과 o2 브랜치에 있던 내용이 한꺼번에 나타났기 때문이다. '<<<<<HEAD'와 가운데 가로줄(=====)사이의 내용은 현재 브랜치, 즉 MASTER 브랜치에서 수정한 내용이다. 가로줄(=====)과 '>>>>> o2'사이의 내용은 o2 브랜치에서 수정한 내용이다. 양쪽 브랜치의 내용을 참고 하면서 직접 내용을 수정해야 한다.

 

16. 내용을 원하는 대로 수정했으면 문서에 나타나 있던 '<<<<< HEAD'나 '>>>> o2', 가로줄(=====)은 삭제한다. 다 했으면 문서를 저장하고 편집기를 종료한다.

 

17. 이제 수정한 work.txt를 스테이지에 올리고 커밋하면 된다. 커밋 메시지는 'merge o2 branch'로 하겠다. 이렇게 해서 o2 브랜치에서 병합한 work.txt의 충돌을 해결하고 커밋했다.

 

18. git log 명령에 --oneline과 --branches, --graph 옵션을 사용하면 지금까지 만든 브랜치와 커밋의 관계를 한눈에 확인할 수 있다.

 

# 병합 및 충돌 해결 프로그램

프로젝트의 규모가 클수록 브랜치가 많으므로 브랜치에서 병합해야 할 파일도 많아진다. 그만큼 충돌이 많이 생기겠다. 그래서 깃의 브랜치 병합을 자동으로 처리해 주고 충돌을 해결해 주는 프로그램이 많다. 병합 알고리즘에는 2 way merge 와 3 way merge 가 있는데 3 way merge 가 훨씬 효율적이므로 3 way merge 를 지원하는 프로그램을 선택하는 것이 좋다.

프로그램 이름 설명
P4Merge 무료이고 직관적이며 사용이 편리하고 병합 기능이 뛰어나다. 단축키가 지원되지 않는 단점이 있다.
Meld 무료이며 오픈 소스다. 파일을 비교하는 것뿐만 아니라 직접 편집할 수 있다.
Kdiff3 무료이고 사용이 편리하고 병합 기능이 뛰어나지만 한글이 깨져 보일 수 있다.
Araxis Merge 유료지만 용량이 큰 파일에서도 잘 동작한다.

 

병합이 끝난 브랜치 삭제하기

브랜치를 병합한 후 더 이상 사용하지 않는 브랜치는 깃에서 삭제할 수 있다. 단, 이렇게 브랜치를 삭제하더라도 이 브랜치가 완전히 지워지는 것이 아니라 다시 같은 이름의 브랜치를 만들면 예전 내용을 다시 볼 수 있다.

 

1. git branch 명령을 사용하면 현재 저장소에 어떤 브랜치가 있는지 확인할 수 있다. 

 

2. 저장소의 기본 브랜치는 master 이므로 브랜치를 삭제하려면 master 브랜치에서 해야 한다. 현재 브랜치가 master 브랜치가 아니라면 master 브랜치로 체크아웃한다.

 

3. 브랜치를 삭제할 때는 git branch 명령에 -d 옵션을 사용한다. 다음과 같이 o2 브랜치를 삭제한다.

 

4. 'Deleted branch o2' 처럼 메시지가 나타나면 성공적으로 브랜치가 삭제된 것이다. 삭제한 브랜치는 같은 이름으로 다시 브랜치를 만들면 예전에 작업했던 내용이 그대로 나타난다. 즉, 브랜치를 삭제한다는 것은 완전히 저장소에서 없에는 것이 아니라 깃의 흐름 속에서 감추는 것이라고 생각하면 된다.

 


◆ 브랜치 관리하기

 

브랜치에서 checkout 과 reset 의 작동 원리

1. 홈 디렉터리로 이동한 후 test라는 깃 저장소를 만들고, test 디렉터리로 이동한다.

 

2. 빔에서 c1.txt 파일을 만들고 숫자 '1' 을 입력하고 저장한다. 여기에서는 내용이 중요한 것이 아니기 때문에 어떤 내용을 입력해도 된다. 그리고 방금 만든 c1.txt를 스테이지에 올리고 커밋한다. 커밋 메시지는 'c1'이라고 하겠다.

 

3. git log 명령을 실행해보자. 커밋 로그 첫 번째 줄에 (HEAD -> master)표시가 있다.

여기에서 HEAD 는 현재 작업 트리가 어떤 버전을 기반으로 작업 중인지를 가리키는 포인터이다. HEAD 는 기본적으로 master 브랜치를 가리킨다. 그리고 브랜치는 기본적으로 브랜치에 담긴 커밋 중에서 가장 최근의 커밋을 가리킨다.

예를 들어 저장소에 c1 커밋을 만들면 HEAD는 master 브랜치를 가리키고 master 브랜치는 c1 커밋을 가리킨다.

 

4. 이제 sub라는 브랜치를 만들겠다. sub 브랜치 또한 c1 커밋을 가리킨다.

 

5. 다시 한 번 빔에서 c2.txt 파일을 만들고 숫자 '2'를 입력한 후 저장한다. 그리고 방금 만든 c2.txt를 스테이지에 올리고 'c2'라는 메시지와 함께 커밋한다. 이제 master는 c2 커밋을 가리키게 된다. HEAD는 그대로 master 브랜치를 가리킨다.

 

6. 이제 sub 브랜치에 커밋을 만들어 보겠다. master 브랜치에서 sub 브랜치로 이동하려면 git checkout 명령을 사용한다. 앞에서도 자주 사용했던 git checkout 명령은 HEAD가 가리키는 것을 제어할 수 있다. 그래서 아래 명령을 실행하면 HEAD가 sub 브랜치를 가리키게 된다.

 

7. sub 브랜치에서 빔을 사용해 s1.txt 문서를 만들고 내용은 's1' 이라고 입력하고 저장한다. s1.txt 문서를 스테이지 올리고 's1' 이라는 메시지와 함께 커밋한다. 이제 HEAD는 sub 브랜치를 가리키고 sub는 s1 커밋을 가리키고 있다.

 

 

8. 브랜치가 여러 개 일 때 reset 명령은 어떻게 사용할 수 있는가? 브랜치가 여러 개 일때는 현재 브랜치가 아닌 다른 브랜치에 있는 커밋을 골라서 최신 커밋으로 지정할 수 있다. 예를 들어 sub 브랜치에 있는 상태에서 master 브랜치에 있는 c2 커밋을 sub 브랜치의 최신 커밋으로 지정할 수 있다. 먼저 git log 명령을 사용해 c2 커밋의 커밋 해시를 확인한다.

 

9. git reset 명령 다음에 c2 커밋의 커밋 해시를 입력한다. 

 

10. 결과를 git log 명령을 사용해 확인해 보겠다.

 

11. sub 브랜치의 최신 커밋이 master 브랜치의 최신 커밋인 c2 로 바뀌었다. 그리고 HEAD 는 그대로 sub 브랜치를 가리키고 있다. 이렇게 git reset 명령을 사용하면 현재 브랜치가 가리키는 커밋을 여러 브랜치 사이를 넘나들면서 제어할 수 있다. 이제 sub 브랜치는 c2 커밋을 가리키고 있기 때문에 원래 가리키고 있던 s1 커밋은 연결이 끊기면서 삭제 된다.

 

git checkout 명령을 사용하면 HEAD를 제어해서 브랜치를 이동할 수 있다. git reset 명령을 사용하면 HEAD가 가리키고 있는 브랜치의 최신 커밋을 원하는 커밋으로 지정할 수 있다. 이때 어떤 브랜치에 있는 커밋이든 지정할 수 있으며, 명령을 수행한 뒤 브랜치와 연결이 끊긴 커밋은 삭제된다.

 

 

 

수정 중인 파일 감추기 및 되돌리기 - git stash

브랜치에서 파일을 수정하고 커밋하지 않은 상태에서 급하게 다른 파일을 커밋해야 할 경우가 있다. 아직 커밋하지 않은 파일들을 그냥 두어도 상관없지만 계속 커밋하라는 메시지가 나타나기 때문에 번거롭다. 실수로 다른 파일과 함께 커밋이 될 수도 있다. 이럴 때 아직 커밋하지 않고 작업중인 파일들을 잠시 감춰둘 수 있다. 그리고 당장 필요한 작업들을 끝낸 후 다시 감춰둔 파일들을 꺼내오면 된다.

 

1. 홈 디렉터리로 이동한 후 st라는 저장소를 만들고 st 디렉터리로 이동한다.

 

2. git stash 명령을 사용하려면 파일이 tracked 상태여야 한다. 즉 한 번은 커밋한 상태여야 한다. 먼저 빔을 사용해 f1.txt 파일을 작성한다. 아무 내용이나 간단하게 입력해서 저장한 후 스테이지에 올리고, 'f1'이라는 메시지와 함께 커밋한다.

 

3. f2.txt 파일도 만들고 내용을 입력한 후 저장한다. f2.txt 파일도 스테이지에 올린 후 'f2' 라는 메시지와 함께 커밋한다.

 

4. 빔에서 f1.txt 파일을 연 후 내용을 아무렇게나 수정하고 저장한다. f2.txt 파일도 수정하고 저장한다.

 

5. git status 명령을 실행해 보면 현재 브랜치에서 f1.txt 와 f2.txt 가 수정되었다고 나타난다.

 

6. 이제 f1.txt 파일과 f2.txt 파일을 커밋하기 전에 다른 파일을 수정해야 한다고 가정하고 커밋하지 않은 수정 내용을 어디엔가 보관하려면 git stash 명령을 사용한다. git stash save 또는 간단히 git stash라고만 해도 된다.

 

7. 다시 한번 git status 명령을 실행해 본다. 조금 전에 나타나던 modified 메시지가 사라졌다.

 

8. 같은 방법으로 여러 파일을 수정한 후 따로 보관할 수 있으며, 이렇게 감춘 파일들은 stash 목록에서 확인할 수 있다. 가장 먼저 감춘 것은 stash@{0} 에 들어있는데, 앞으로 다른 파일이 추가되면 기존 파일은 stash@{1}로 옮겨지고 새로 추가된 파일은 stash@{0}에 담긴다. 즉 가장 최근에 보관한 것이 stash@{0}에 담긴다. 먼저 감춘 것을 아래에, 가장 최근에 감춘 것을 위에 쌓기 때문에 stash 스택이라고도 표현한다.

 

9. 급한 작업을 모두 마쳤다면 감춰둔 파일을 꺼내와 계속 수정하거나 커밋할 수 있다. git stash 명령 뒤에 pop를 추가하면 stash 목록에서 가장 최근 항목을 되돌린다. 여기에서는 f1.txt와 f2.txt 가 수정된 상태로 되돌아간다.

 

 

# stash apply 와 stash drop

stash 목록에 저장된 수정 내용을 나중에 또 사용할지도 모른다면 git stash apply 명령을 사용한다. stash 목록에서 가장 최근 항목을 되돌리지만 저장했던 내용은 그대로 남겨둔다.

 

git stash drop 명령은 stash 목록에서 가장 최근 항목을 삭제한다.

 

 


출처 : Do it! 지옥에서 온 문서 관리자 깃&깃허브 입문 [고경희, 이고잉 (이지퍼블리싱)]

'Records > Git Hub' 카테고리의 다른 글

깃허브로 협업하기  (0) 2021.02.15
깃허브로 백업하기  (0) 2021.02.15
깃으로 버전 관리하기  (0) 2021.02.08
깃 시작하기  (0) 2021.02.07
Comments