본문 바로가기
깃 & 깃허브

[깃 & 깃허브] 3. 깃과 브랜치 - 우당탕탕 개발자 되기 프로젝트

by 우당탕탕 개발자 2024. 1. 23.
728x90
반응형

 

1. 브랜치란

브랜치(branch) : 버전 관리 시스템에서는 여러 갈래로 퍼지는 데이터의 흐름을 가리키는 말로 사용

main 브랜치 : 깃으로 버전 관리를 시작하면 기본적으로 만들어지는 브랜치

master 브랜치 : main 브랜치와 이름만 서로 다를 뿐, 깃을 사용할 때 기본이 되는 브랜치 (개념 동일)

 

브랜치 기능

1. 사용자가 커밋할 때마다 main 브랜치는 어떤 게 최신 커밋인지 정보를 가진다.

브랜치커밋을 가리키는 포인터와 유사하다.

 

2. 새 브랜치를 만들면 기존 파일은 main 브랜치에 그대로 유지되고, 새 브랜치에 기존 파일 내용을 수정하거나 새로운 기능을 추가할 수 있다.

분기(branch) : main 브랜치에서 새 브랜치를 만드는 것

 

3. 새 브랜치에서 원하는 작업을 끝낸 후, 새 브랜치에 있던 파일을 원래 main 브랜치에 합칠 수 있다.

병합(merge) : 분기했던 브랜치를 main 브랜치에 합치는 것

 

4. 기본 파일은 main 브랜치에 그대로 둔 상태에서 새로운 브랜치를 분기한 후 수정이나 추가 작업을 하고 별문제 없이 완성되었다면, 새 브랜치의 내용을 main 브랜치와 병합하는 것

 

2. 브랜치 만들기 및 이동하기

브랜치 분기가 필요한 상황을 만들기 위해 우선 홈 디렉터리에서 manual 새 디렉터리를 만들고 해당 디렉터리로 이동한다.

 

git init 명령으로 manual 디렉터리를 저장소로 만들고

ls -al 명령으로 .git 디렉터리가 만들어졌는지 확인한다.

 

work.txt 파일을 만들어 content 1 내용을 적고 저장한다.

 

work.txt 파일을 스테이지에 올리고 커밋한다.

커밋 완료 후 git log 명령으로 커밋 내역을 확인한다.

커밋 내역을 보면 HEAD가 현재 master 브랜치를 가리키고 있고 (HEAD → master)가 붙은 커밋이 가장 최신 커밋이므로 현재는 work 1이 가장 최신 커밋이라고 알려주고 있다.

 

work.txt 파일에 각각 content 2와 content 3을 추가하여 각 메시지와 함께 커밋한다.

 

두 번의 커밋 이후 git log 명령으로 커밋 내역을 확인하면 총 3개의 커밋이 만들어졌고, 가장 최신 커밋인 work 3에 (HEAD → master)가 표시되어 있다.

 

git branch 명령 : 깃에서 브랜치를 만들거나 확인하는 명령

git branch 명령으로 현재 저장소의 브랜치를 확인한다.

*가 표시된 브랜치는 여러 브랜치 중 현재 작업하는 브랜치를 나타낸다.

 

git branch 명령 뒤에 만들려는 브랜치 이름을 적으면 해당 이름의 브랜치가 새롭게 만들어진다.

git branch 명령으로 현재 저장소의 브랜치를 확인하면 master 브랜치 위에 apple 브랜치가 추가된 것을 볼 수 있다.

 

브랜치를 추가한 후 git log 명령으로 커밋 내역을 확인해 보면 커밋 로그 화면도 다르게 나타난다.

(HEAD → master)라고 표시되던 곳에 apple 브랜치가 추가되어 (HEAD → master, apple)로 표시된다.

 

google 브랜치와 ms 브랜치를 추가한 후 git branch 명령으로 저장소 안에 있는 모든 브랜치를 확인해 본다.

 

git log 명령으로 커밋 내역을 확인하면 work 3 커밋 해시의 오른쪽에 master 브랜치를 포함해 모든 브랜치가 함께 표시된 것을 볼 수 있다.

이것은 master 브랜치뿐만 아니라 ms와 google, apple 브랜치에도 최신 커밋이 work 3라는 뜻이다.

 

이후 work.txt 파일에 main content 4 내용을 추가하고 main work 4 메시지와 함께 커밋한다.

커밋 후 git log 명령에 --oneline 옵션(한 줄에 한 커밋씩 보여줌)을 추가해 확인해 보면 최신 커밋인 main work 4는 master 브랜치에만 적용되어 있고 ms와 google, apple 브랜치는 아직 work 3 커밋 상태이다.

즉, 새로 만든 커밋은 현재 브랜치에만 적용되고 나머지 브랜치에는 적용되지 않는다.

 

git switch 명령 : 현재 브랜치에서 다른 브랜치로 이동하는 명령 (브랜치를 전환한다)

git switch apple 명령으로 현재 master 브랜치에서 apple 브랜치로 전환한다.

브랜치를 전환하고 나면 $ 커서 바로 위에 나타나는 파일 경로 끝에 (apple)이라고 바뀌어 나타나는 것을 볼 수 있다.

이는 현재 작업하고 있는 브랜치가 apple 브랜치라는 것을 의미한다.

 

git log --oneline 명령으로 현재 브랜치의 커밋 로그를 확인하면 apple 브랜치를 만들기 전까지 master 브랜치에 있던 커밋들은 그대로 apple 브랜치에도 적용되어 있다.

하여 work 3 커밋까지만 표시되는 것을 볼 수 있다.

또한 커밋 해시에서 HEAD가 apple을 가리키고 있는 것도 확인할 수 있다.

 

cat work.txt 명령으로 work.txt 파일의 내용을 확인하면 최신 커밋이 work 3이기 때문에 content 1부터 content 3까지 3개의 행만 나타나게 된다.

master 브랜치에서 입력했던 main content 4가 없는데 main content 4는 apple 브랜치를 분기한 후에 main 브랜치에 추가된 커밋이기 때문에 apple 브랜치에 영향을 미치지 않는다.

3. 브랜치 정보 확인하기

브랜치를 전환하면 브랜치마다 서로 다른 커밋을 처리할 수 있다.

브랜치마다 만들어진 커밋이 서로 어떤 관계가 있는지 확인하는 방법과 브랜치 사이의 차이점을 확인하는 방법을 알아본다.

 

우선 apple 브랜치를 분기할 때 가져온 work.txt 파일에 apple content 4 텍스트를 추가하고 apple 브랜치만의 파일로 apple.txt 파일을 새로 만들어 동일하게 apple content 4 텍스트를 입력하여 저장한다.

 

이후 두 파일을 커밋해 보면 각각 커밋할 수도 있지만 git add 명령 뒤에 한 칸 공백을 만들고 점(.)을 입력하면 현재 저장소에서 수정 내용이 있는 파일을 스테이지에 한꺼번에 올릴 수 있다.

커밋 후 git log 명령으로 커밋 로그를 확인하면 첫 번째 줄에 (HEAD → apple)이라고 되어 있는 것으로 보아 현재 apple 브랜치로 전환한 상태이고 apple 브랜치의 최신 커밋이 방금 커밋한 내용이라는 것을 확인할 수 있다.

 

git log 명령을 사용할 때 --branches 옵션을 추가하면 브랜치마다 최신 커밋을 한눈에 확인할 수 있다.

결과 화면을 보면 커밋 해시마다 오른쪽에 해당 커밋이 어떤 브랜치에서 만든 것인지 구별할 수 있다.

제일 먼저 현재 브랜치인 apple의 최신 커밋, 이후 master 브랜치의 최신 커밋, ms 브랜치와 google 브랜치의 최신 커밋을 각각 확인할 수 있다.

 

git log 명령에 --graph 옵션을 추가하면 브랜치와 커밋 관계를 보기 쉽게 그래프 형태로 표시할 수 있다.

커밋 내역 왼쪽에 수직선(|)으로 나타낸 부분이 커밋과 커밋의 관계를 보여준다.

apple 브랜치의 최신 커밋인 apple work 4에서 수직선을 따라 커밋의 부모를 찾아가 보면 work 3 커밋을 만나게 된다.

즉, apple 브랜치에서는 work 3 커밋 이후에 apple work 4 커밋이 만들어졌다는 뜻이다.

 

master 브랜치를 살펴보면 대각선을 따라 부모 커밋을 찾아보면 역시 마찬가지로 work 3 커밋을 만나게 된다.

즉, master 브랜치나 apple 브랜치는 work 3 커밋까지는 같고 그 이후부터는 브랜치마다 다른 커밋을 만들었다는 것을 알 수 있다.

 

git log 명령브랜치 이름 사이마침표 2개(..)를 넣는 명령으로 브랜치 간의 차이를 쉽게 확인할 수 있다.

브랜치 이름과 마침표 사이에는 공백 없이 입력해야 하며, 마침표 왼쪽에 있는 브랜치를 기준으로 오른쪽 브랜치와 비교한다. (브랜치 이름..브랜치 이름)

 

master 브랜치를 기준으로 apple 브랜치 사이의 차이점을 나타내보면 master 브랜치에는 없고 apple 브랜치에만 있는 apple work 4 커밋을 보여준다.

 

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

반응형

4. 브랜치 병합하기

브랜치마다 각자 커밋할 수 있더라도 어느 시점에서는 브랜치 작업을 마무리하고 기존 브랜치와 합쳐야 하는데 이를 브랜치 병합(merge)라고 한다.

브랜치 병합은 까다롭기 때문에 우선 새로운 저장소를 만들어 필요한 브랜치와 커밋만 하는 사용 해 연습해 본다.

 

우선 홈 디렉터리로 이동하여 git init 명령으로 해당 디렉터리 이름의 새로운 디렉터리를 만들고 저장소를 초기화하는 과정을 한꺼번에 처리할 수 있다.

이후 manual-2 디렉터리로 이동하여 ls -al 명령으로 .git/ 디렉터리가 만들어졌는지 확인한다.

 

빔에서 work.txt 파일을 만들고 1을 입력한 후 저장한다.

 

그리고 work 1 메시지와 함께 커밋한다.

 

그러면 현재 상태를 그림으로 나타내면 위 그림과 같다.

 

이후 gir branch 명령으로 o2라는 브랜치를 만든다.

 

브랜치를 만든 뒤 현재 상태를 그림으로 나타내면 위 그림과 같이 o2가 work 1 커밋을 가리키게 된다.

 

현재 master 브랜치에 있는 상태에서 main.txt 파일을 하나 더 만들어 main 2라고 입력한 후 저장한다.

그리고 main work 2라는 메시지와 함께 커밋한다.

 

위 그림은 지금까지 master 브랜치에서 work 1 커밋과 main work 2 커밋을 만든 현재 상태를 나타낸 그림이다.

 

그럼 git switch 명령으로 o2 브랜치로 전환하고 o2 브랜치에서 o2.txt 파일을 만들어 2를 입력한 후 저장한다.

이어 o2.txt 파일을 o2 work 2 메시지와 함께 커밋한다.

 

git log 명령으로 현재 커밋 상태를 확인해 보면 work 1 커밋은 master 브랜치와 o2 브랜치가 똑같이 가지고 있다.

이어서 master 브랜치에는 main work 2 커밋이 생겼고 o2 브랜치에는 o2 work 2 커밋이 생겼다.

master 브랜치 입장에서는 work 1 → main work 2 순으로 커밋이 생겼고, o2 브랜치 입장에서는 work 1 → o2 work 2 순으로 커밋이 생겼다.

 

이제 o2 브랜치에서 작업이 모두 끝났다고 가정하고 o2 브랜치의 내용을 master 브랜치로 병합하려면 우선 master 브랜치로 전환해야 한다.

 

브랜치를 병합할 때는 git merge 명령 뒤에 가져올 브랜치 이름을 입력하면 된다.

현재 브랜치인 master 브랜치를 기준으로 o2 브랜치를 가져와 병합한다.

병합 후 ls -al 명령으로 확인해 보면 o2 브랜치에 있던 o2.txt 파일이 master 브랜치에 합쳐진 것을 볼 수 있다.

 

git log 명령으로 브랜치와 커밋이 어떻게 합병되었는지 확인할 수도 있다.

o2 work 2 커밋이 master 브랜치에 병합되면서 Merge branch o2 커밋이 새로 생겼다.

이렇게 두 브랜치에서 서로 다른 파일을 병합하는 경우 해당 방법으로 깃에서 간단히 해결할 수 있다.

 

그렇다면 2개의 브랜치에서 같은 문서를 수정한다면 어떻게 병합하는지 알아본다.

같은 문서의 다른 부분을 수정할 때와 같은 문서에서 같은 부분을 수정했을 때의 병합 과정은 다른데 우선 같은 문서에서 서로 다른 부분을 수정했을 때 병합하는 과정을 살펴본다.

우선 홈 디렉터리로 이동한 후 git init 명령으로 manual-3 깃 저장소를 만들고 manual-3 디렉터리로 이동한다.

 

work.txt 파일을 만들고 위의 사진과 같이 입력한 후 저장한다.

work.txt 파일을 스테이지에 올리고 work 1 메시지와 함께 커밋한다.

 

git branch 명령으로 o2 브랜치를 새로 만들어준다.

그러면 master 브랜치와 o2 브랜치에는 모두 work 1 커밋이 있게 된다.

 

양쪽 브랜치 모두 work.txt 파일이 있는 상태에서 우선 master 브랜치에서 문서를 수정해 보면, vim 편집기에서 work.txt 파일을 열고 내용을 수정한 후 저장한다.

수정한 work.txt 파일을 main work 2 메시지와 함께 커밋한다.

 

master 브랜치의 work.txt 파일을 수정했으니 o2 브랜치의 work.txt 파일을 수정해 보면, 우선 o2 브랜치로 전환하고 work.txt 파일을 불러와 내용을 수정한 후 저장한다.

수정한 work.txt 파일을 o2 work 2 메시지와 함께 커밋한다.

 

master 브랜치o2 브랜치 양쪽에서 work.txt 파일을 수정했지만 파일 안의 수정 위치는 다르다.

이 상태에서 브랜치를 병합해 보면, 우선 o2 브랜치를 master 브랜치에 합치기 위해 master 브랜치로 전환한다.

 

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

빔이 자동을 실행되며 커밋 메시지가 나타나는데 메시지를 수정할 수도 있고 그대로 사용할 수도 있다.

원하는 메시지를 작성하고 저장한 후 편집기를 종료한다.

이후 cat 명령으로 work.txt 파일을 확인해 보면 master 브랜치의 수정 내용과 o2 브랜치의 수정 내용이 하나의 파일에 합쳐진 것을 볼 수 있다.

이렇게 깃은 같은 문서로 서로 다른 위치를 수정했을 경우 자동으로 합쳐 주는 기능이 있어 더욱 강력한 도구가 된다.

 

하지만 깃에서는 줄 단위로 변경 여부를 확인하기 때문에 서로 다른 브랜치에서 같은 문서의 같은 줄을 수정했을 경우, 브랜치를 병합하면 브랜치 충돌(conflict)이 발생한다.

master 브랜치와 o2 브랜치에서 같은 파일의 같은 위치를 수정한 후 병합해 보면서 브랜치 충돌이 생기는 경우를 살펴보고 이를 해결하는 방법도 알아본다.

우선 홈 디렉터리로 이동 후, git init 명령으로 manual-4 깃 저장소를 만들고 manual-4 디렉터리로 이동한다.

 

이후 빔에서 work.txt 파일을 만들고 위 사진과 같이 내용을 입력하고 저장한다.

work.txt 파일을 스테이지에 올리고 work 1 메시지와 함께 커밋한다.

 

다음으로 git branch 명령을 사용해 o2 브랜치를 만든다.

 

master 브랜치와 o2 브랜치 양쪽에 work.txt 파일이 있는 상태에서 우선 master 브랜치의 work.txt 파일을 수정한다.

수정한 work.txt 파일을 main work 2 메시지와 함께 커밋한다.

 

다음으로 o2 브랜치의 work.txt 파일도 수정하기 위해 o2 브랜치로 전환한다.

그리고 work.txt 파일을 열어 내용을 수정하고 저장한다.

수정한 work.txt 파일을 o2 work 2 메시지와 함께 커밋한다.

 

이렇게 master 브랜치와 o2 브랜치 양쪽에서 work.txt 파일의 같은 위치를 수정한 경우 두 브랜치를 병합해 보면, 우선 o2 브랜치를 master 브랜치에 병합하기 위해 master 브랜치로 전환한다.

전환 후 git merge 명령을 사용해 o2 브랜치를 병합한다.

두 브랜치를 병합해 보면 이전 병합 때처럼 빔이 자동으로 열리지 않고 경고 메시지가 나타난다.

이는 work.txt 파일을 자동 병합하는 동안 충돌이 발생했다는 뜻이다.

 

충돌이 생긴 문서는 자동을 병합될 수 없으므로 사용자가 충동 부분을 직접 해결한 후 커밋해야 한다.

충돌이 생긴 work.txt 파일을 열어보면 master 브랜치에서 수정한 내용과 o2 브랜치에서 수정한 내용이 한꺼번에 나타난 것을 볼 수 있다.

 

해당 work.txt 파일의 내용을 원하는 형태로 새롭게 수정한 후 파일을 저장하고 편집기를 종료한다.

 

수정한 work.txt 파일을 merge o2 branch 메시지와 함께 커밋한다.

이렇게 하면 o2 브랜치에서 병합한 work.txt 파일의 충돌을 해결하고 커밋을 끝낸다.

git log 명령으로 지금까지 만든 브랜치와 커밋의 관계를 한눈에 확인할 수 있다.

 

브랜치를 병합한 후 더 이상 사용하지 않는 브랜치깃에서 삭제할 수 있다.

하지만 이렇게 브랜치를 삭제하더라도 완전히 지워지는 것은 아니며 같은 이름의 브랜치를 만들면 예전 내용을 다시 볼 수 있다.

git branch 명령으로 현재 저장소에 있는 브랜치를 확인하면 master 브랜치와 o2 브랜치가 있는 것을 확인할 수 있다.

저장소의 기본 브랜치는 master 브랜치이므로 브랜치를 삭제하려면 master 브랜치에서 해야 한다.

만약 현재 브랜치가 master 브랜치가 아니면 master 브랜치로 전환해야 한다.

 

브랜치를 삭제할 때는 git branch 명령-d 옵션을 추가한 후 뒤에 삭제할 브랜치 이름을 입력하면 된다.

실행 후 위 사진과 같은 메시지가 나오면 브랜치 삭제를 성공한 것이다.

 

깃에는 방금 브랜치를 병합하는 방법 이외에도 "cherry-pick"이라는 또 하나의 병합 방법이 있다.

cherry-pick은 브랜치를 합치긴 하는데 브랜치 전체를 합치는 것이 아니라, 브랜치 중 특정 버전의 변경 내용만 합치려고 할 때 사용하는 기능이다.

 

topic 브랜치가 만들어진 상태
main 브랜치에 topic 브랜치를 merge 했을 때
main 브랜치에서 topic 브랜치를 cherry-pick 했을 때

브랜치의 특정 버전에서 변경된 것만 master 브랜치에 합칠 수 있는데 해당 경우에는 새로운 버전이 만들어지지 않고 그냥 master 브랜치에 해당 버전이 합쳐진다.

또한 브랜치의 다른 버전들은 합쳐지지 않는다.

 

cherry-pick를 실습해 보기 위해 우선 홈 디렉터리로 이동한 후, cherry-pick 깃 저장소를 만들어 cherry-pick 디렉터리로 이동한다.

 

새로운 브랜치를 만들기 전 버전을 만들어 준다.

touch 명령으로 init.txt 파일을 만든다.

이후 init.txt 파일을 스테이지에 올리고 init 메시지와 함께 커밋한다.

 

해당 상태에서 새로운 브랜치 topic을 만든다.

그리고 깃 로그를 확인해 보면 init 버전이 master 브랜치와 topic 브랜치 양쪽에 있는 것을 확인할 수 있다.

 

master 브랜치에 m1 버전과 m2 버전을 더 만들어 준다.

터미널에서 세미콜론(;)으로 구분여러 개의 명령을 한꺼번에 입력하여 처리할 수 있다.

2개의 새로운 버전을 만들고 git log 명령으로 확인해 보면 master 브랜치를 최신 버전 m2를 가리키고 있고, topic 브랜치는 init 버전 상태인 것을 볼 수 있다.

 

topic 브랜치로 전환한 후 이전과 같은 방법으로 t1, t2, t3 버전을 만들어 준다.

 

git log 명령으로 확인해 보면 master 브랜치는 init 버전부터 시작해 m1, m2 버전으로 연결되어 있고, topic 브랜치는 init 버전부터 시작해서 t1, t2, t3 버전으로 연결된다.

 

여기서 topic 브랜치의 t2 버전에서 적용했던 내용을 master 브랜치에도 적용하고 싶을 때 사용하는 것이 바로 cherry-pick이다.

cherry-pick을 사용하려면 우선 병합될 브랜치인 master 브랜치로 전환해야 한다.

 

topic 브랜치의 t2 버전만 병합하려면 cherry-pick 명령 다음에 t2에 해당하는 커밋 해시를 입력하면 된다.

cherry-pick 이후에 ls 명령으로 master 브랜치에 어떤 파일이 있는지 확인해 보면 기존에 master 브랜치에 있던 init.txt, m1, m2 다음에 t2가 합쳐진 것을 볼 수 있다.

 

git log 명령으로 깃 로그를 확인해 보면, topic 브랜치에 t2가 있고, main 브랜치에도 t2가 추가되어 있는 것을 확인할 수 있다.

728x90
반응형