지옥에서 온 관리자 git #3-1

Kyubo Sim·2025년 3월 28일
0

이제 브랜치와 충돌에 대한 것을 알아보겠다.

brach는 가지라는 뜻이다. 일을 하다 보면 복제본이 필요한 경우들이 있다.
만약 내가 개발하던 소프트웨어를 출시 하였는데 고객사 마다 요구사항이 다르다면?

이렇게 다 복사해서 각 고객사 마다 다르게 만들어줘야 할것이다.
만약 구글에 추가한 기능을 애플에도 추가해야하는 상황이 뒤늦게 벌어진다면.

이렇게 복사 붙여넣기를 하게 될것이다.
이렇게 되면 코드를 병합하는 과정에서의 수많은 충돌을 우리가 다 다루어야하고 GF와 GE에 관한 기록은 애플에는 남지 않을것이다.
brach란 같은 뿌리에서 나왔지만 서로 다른 역사를 써가고 있는 버전들을 이야기 한다.

barch와 barch를 병합할때 우리가 해결해야 할 일이 confilct이다.

같은 파일의 같은 부분이 수정되었다면 수동으로 수정을 해야한다 이것이 바로 병합과정에서 일어나는 conflict이다.


우리의 고객사가 애플, 구글, MS라고 가정하고 브랜치 실습을 진행하겠다.
master는 아주 특별한 브랜치이다. 우리 저장소를 만드는 순간 master가 생겨난다.
여기서 apple이라는 브랜치를 추가하고 싶다면
git brach apple이라고 쓰면 된다

master앞에 * 이 있다는것은 현제 마스터 브랜치에 있다는 것이다.

마찬가지로 ms와 goolgle을 만들어준다.

이후 문서를 수정한뒤 master work4라는 메세지와 함께 커밋을 하면

위와 같이 마스터와 다른 브랜치들이 가르키는 버전이 달라진다.
git checkout apple을 입력하면 아래 그림과 같이

문서가 다시 work3의 시절로 돌아가게 된다.

애플 브랜치에서 apple.txt를 추가하고 work문서도 바꾼뒤 커밋하면 아래처럼 log에서 그래프가 생기게 되고 마스터와 애플의 공동조상이 work3임을 확인할 수 있다.


같은 작업을 google에게도 해준뒤
git log --all --graph --oneline을 입력하면

다음과 같은 그래프를 볼 수 있다.
마지막으로 ms에도 같은 작업을 해주면

이런 그래프가 생기는것을 볼수 있다.
우리는 checkout을 통해서 다른 브랜치로 언제든지 접근할 수 있다.


merge


이 상태에서 처음에 말한 애플에 있는 유용한 기능을 마스터에도 적용을 시키고 싶을때 우리는 Merge를 사용하게 된다.

합치려고 하는 브랜치들의 공통 조상을 base라고 한다. 그리고 합쳐진 버전은 merge commit이라고 한다.

이제 병합에 대한 실습을 해보도록 하자

서로 다른 파일 병합

git commit --amend : 이미 커밋한 버전의 메세지를 수정할 수 있다.
master에서 o2라는 브랜치를 만들고 서로 다른 작업을 한뒤 각각 커밋을 하면

이렇게 된다.
이때 o2브랜치에 있는것을 마스터에 병합을 하고 싶다면 우선 마스터 브랜치로 가야한다.
git merge o2를 마스터에서 입력하면 o2브랜치가 마스터로 변합된다.

이때 머지를 취소하고 싶다면
git reset --hard [아이디]

머지가 취소된다.

같은 파일, 다른 부분 병합

master에서는 aoooooa -> boooooa, o2에서는 aoooooa -> aoooooc 로 수정했다고 가정하자. 두 브랜치는 공통 조상의 문서에서 각각 다른 부분을 수정하였다.
이때 git merge o2를 하면 boooooc라는 파일이 생성된다.

같은 파일, 같은 부분 병합

이때 conflic가 일어난다.
이번에서 마스터에서 aoooooa -> aoobooa, o2에서는 aoooooa -> aoocooa로 수정했다고 가정하자. 이때 git merge o2를 하게 되면

conflict가 나게 된다.

문서 안에서 일어난 이 이상한 기호들과 상황들에 대해서 설명해 보겠다.
===== 는 구분자이다. 구분자를 중심으로 HEAD까지는 현제 브랜치의 내용이고 O2까지는 o2브랜치의 내용이다.
직접 수작업으로 <<<<<<<, >>>>>>>> 사이의 내용을 수정하고 <<<와 >>>도 지워준다음 문서를 다시 저장하고 git add를 해주면 충돌을 해결한뒤 다시 커밋을 할 수 있게 된다.


3 way merge


하나의 버전을 here과 there라는 브랜치로 만들고

각각 두 브랜치를 이렇게 변경한뒤 병합을 해야한다면 어떤것이 자동 병합이 일어나고 어떤것이 충돌이 날까? 이경우에는

변경한 세 군데가 모두 충돌이 나게 된다 이것이 2 way merge이다.

하지만 이때 공통조상인 base까지 병합에 참조하는것이 3 wat merge이다.

base와 비교하여 변경되지 않은 코드는 자동 머지가 가능하도록 해주는 것이다.



위에 설명한 상황을 실습하면 이렇게 base와 모두 달라진 마지막 문자만 충돌이 난다. 이때 수동으로 충돌을 수정할 수도 있지만 병합을 도와주는 외부도구들을 쓸 수 있다.

대표적으로 p4merge 등이 있다.

이 툴을 쓰는 방법을 알아보고 싶다면 구글에 p4merge git config을 검색하여 명령어를 알아낸다. git config --global merge.tool p4mergetool을 입력하게 되면 깃의 디폴트 머지 툴이 p4merge로 바뀌게 된다. 그리고 머지 툴의 경로 정보도 깃에게 알려주어야 한다.
설정이 끝난뒤 git mergetool을 입력하면

이러한 p4머지 툴이 뜨게 된다.
.orig파일은 백업해둔 오리지널 파일이다.


git 브랜치의 이모저모

git work flow, git flow : 사람들이 쓰는 방법론


cherry pick : 필요한 버전만 병합


rebase : b2와 b3를 순차적으로 a3에 병합시켜서 a4와 a5를 만드는 매우 어려운 기능

HEAD, Branch, Commit 에 대해서

저장소를 만들면 해드가 만들어지고 그 해드는 마스터를 가르킨다. 그리고 버전을 새로 생성을 하면 마스터 브랜치가 새로운 버전을 가르키게 된다.

프로그램마다 해드를 나타내는 방법은 다르다.

이런식으로 또 새로운 버전을 만들면 마스터가 다음 버전을 가르키게 되고 해드는 아직도 마스터를 가리키고 있다.
2번전에서 구글이라는 브랜치를 만들면

이런 상태가 되고 이때 checkout google을 입력하게 되면 해드는 구글을 가르키게 되고 이제 그 상태에서 문서를 수정한뒤 3번 버전을 만들면
이런 상태가 된다.
이때 다시 master로 checkout하면 버전 2로 돌아가게 된다.
또 checkout하고 버전의 아이디를 작성하면 (1)
위 처럼 버전을 해드가 직접 가르킬수도 있게 된다. 즉, checkout이라는 것은 우리가 HEAD를 제어하는 것이다.

checkout vs reset


checkout은 HEAD를 제어하고 reset은 해드가 브랜치를 가르키고 있는 동안은 브랜치를 제어한다고 하자. (정확한 설명은 아니나 이해를 돕기 위해서)
checkout master를 하면 HEAD는 마스터를 가르키게 된다. 버전은 2번으로 바뀐다.
reset master를 하면 구글 브랜치가 마스터 브랜치가 가르키고 있는 버전을 가르키게 된다.

reset 1을 하게 되면 google이 1번 버전을 가르키게 되며 2번 3번은 구글에서는 지워지게 된다.

profile
나의 정리 공간

0개의 댓글