[생활코딩] 형상관리/GIT3 branch & conflict

GIT3 branch & conflict - 병합(merge) {다른 파일 병합, 같은 파일 다른 곳 수정 병합, 같은 파일 같은 곳 수정 병합}

Ben의 프로그램 2023. 5. 14. 22:17
728x90

병합이 필요한 이유

  • 여러분이 commit 을 하면 버전이 만들어집니다. 이 버전들은 기본 branch 인 main branch 에 속해 있습니다. 
  • 그 후에 여러분이 apple branch 를 만들고, 해당 branch 로 체크아웃 하고 나서 commit 을 통해 새로운 버전을 만들면 apple branch 소속이 됩니다. 

  • 아주 환상적인 기능입니다. 저장소를 여러 개 만들어서 고객사를 관리하던 것과 비교하면 아주 환상적입니다. 
  • 그런데, 사람의 욕심은 끝이 없습니다. apple branch 에서 만들었던 기능이 master 에서도 유용할 것 같은 겁니다. 이럴 때 여러분은 merge, 즉 합치는 작업을 하고 싶을 겁니다. 

base commit 과 merge commit 

  • 우리는 master 에서 작업한 내용도 가지고 있고 apple branch 에서도 작업한 내용을 동시에 가지고 있는 새로운 버전을 만들고 싶다는 꿈을 꾸게 되는 겁니다. 그리고 얘가 새로운 main branch 가 되는 것이죠.
  • 이렇게 하기 전에 우리가 알아야 하는 용어 두 가지가 있습니다. apple branch 와 main branch 의 공통된 부모 클래스를 우리는 "base" brach 라고 합니다. 
  • 즉, 합치려고 하는 버전들의 공통된 버전을 base 라고 합니다. 
  • 그리고, 새로이 만들어지는 버전을 "merge commit" 이라고 합니다. 
  • 이렇게 두 버전을 합쳐서 새로운 버전을 만들 때 일일이 하려고 한다면 정말 힘든 일입니다. 하지만 git 은 자동으로 파일들을 합쳐서 새로운 버전을 만들어주는 강력한 기능을 제공해줄 뿐만 아니라 논리적으로 사용자가 직접 관여해야 하는 부분은 사전에 알려주기 까지 하는 아주 놀라운 도구입니다. 
  • Merge 에 대해서 자세히 알아봅시다.

merge 하기 위한 사전 작업 

  • git init manual-merge 라고 입력해서 manual-merge 라는 폴더를 만듦과 동시에 git 에게 관리하도록 만듭니다.
  • 그런 다음 work.txt 라는 파일을 하나 만들겠습니다. 

  • 1이라는 내용을 입력한 후 'work 1' 이라는 버전으로 만들겠습니다.

  • 새로 만든 파일이니 git add . 을 통해 Staging Area 에 우선 등록을 해준 뒤 
  • git commit -m "work 1" 으로 버전을 하나 만들었습니다. 

  • 성공적으로 main branch 를 만들었습니다. 이제는 다른 branch 를 만들어 보겠습니다.
  • 그리고 나서 해당 branch 를 main branch 와 병합하는 과정을 통해서 여러 가지 실험들을 해볼 예정입니다. 

  • 새로운 버전을 만들기 전에 main branch 안에 master.txt 라는 파일을 만들고 2라고 적어 놓겠습니다.
  • 그리고 work 2 라는 새로운 버전을 main branch 안에 만들어 놓겠습니다. 

  • 어, 그런데, 방금 work 2 라고 만든 commit 의 이름에 master work 2 라고 수정을 주고 싶으면 git commit --amend 라고 하면 editor 가 실행되고, 해당 editor 안에서 내용을 수정할 수 있습니다. 

  • commit 의 이름이 바뀐 것을 알 수 있습니다. 
  • 이번에는 o2 라는 branch 에서 o2.txt 라는 파일을 만들어 보겠습니다.

  • o2.txt 파일에는 o2 2 라는 내용을 입력해놓았습니다.

  • 그리고 o2 work 2 라는 버전으로 commit 을 해놓았습니다. 
  • 현재 상황은 이렇습니다. main branch 는 현재 master work 2 라는 버전이 최신버전이고, 해당 버전에서는 master.txt 라는 파일을 추가했습니다. 반면 o2 branch 는 현재 o2 work 2 라는 버전이 최신버전이고, 해당 버전에서는 o2.txt 파일을 추가했습니다.

 

서로 다른 파일을 수정한 버전들 병합하기

  • 이제 병합을 해보겠습니다. 
  • 저는 지금 main branch 에 o2 branch 를 병합시켜주고 싶습니다. o2 brnach 의 내용을 master branch 로 합쳐주고 싶다는 뜻입니다.
  • 그렇게 해주기 위해서 가장 먼저 해주어야 하는 일은 main branch 상태로 옮겨가야 합니다. (checkout)
  • 그런 다음, 병합하고 싶은 branch 를 merge 명령을 통해 지정하면 됩니다. 

  • HEAD가 main 을 향해 있는 상태에서 git merge o2 를 해주면 merge 가 자동으로 진행됩니다.

 

서로 같은 파일, 다른 부분을 수정한 버전들 병합하기

  • 서로 같은 파일, 다른 부분을 수정한 버전들을 병합하는 연습을 해봅시다. 그것을 하기 위해서 우선 저장소를 하나 다시 만들겠습니다. 전에 만들었던 manual-merge 폴더를 삭제했습니다. 

  • 그 다음 git init manual-merge 로 저장소를 만들고 git 에게 관리하도록 시켰습니다. 

  • work.txt 라는 파일을 만들고 위와 같이 구분되는 두 부분에 내용을 작성했습니다. 같은 파일, 다른 부분을 수정하는 버전들을 우선 만들 것이기 때문에 위와 같이 만들었습니다.

  • 현재까지의 변경사항을 "1" 이라는 commit 으로 만들었습니다.

  • 그리고 o2 라는 branch 도 만들었습니다.

main branch 에서 수정한 work.txt 파일과 o2 branch 에서 수정한 work.txt 파일

  • main branch 에서는 work.txt 의 윗 부분을 수정하고 o2 branch 에서는 work.txt 의 아랫부분을 수정할 겁니다. 

main brach 는 master work 2 로 커밋, o2 branch 는 o2 work 2 로 커밋

  • main branch 에서 수정한 버전은 master work 2 버전으로 커밋하고 o2 branch 에서 수정한 버전은 o2 work 2 버전으로 커밋합니다.

  • main 을 기준으로 o2 를 병합하고 싶다면 우선 main 커밋으로 HEAD 를 이동시켜 주어야 합니다. 

  • git merge o2 명령으로 main branch 에 o2 branch 를 merge 해줍니다. 

  • work.txt 파일이 어떻게 변했나 살펴보면 main 과 o2 내용이 모두 들어간 work.txt 파일이 되었습니다. 이것은 git 이 제공해주는 정말 환상적인 기능입니다.
  • 만약 우리가 두 버전에서 작업한 파일이 다르다면 그냥 병합하면 되겠죠. 그러나, 같은 파일에서 다른 부분을 수정한 것을 자동으로 병합해주는 것은 git 에서만 가능합니다.

 

서로 같은 파일, 같은 부분을 수정한 버전들 병합하기

  • 같은 파일, 같은 부분을 수정한 부분을 git 은 자동 병합 시켜주지 못하고 이러한 상황을 conflict 충돌이라고 합니다. 
  • conflict 에 익숙하지 않으신 분들은 conflict 가 사고라고 느낍니다. 하지만 conflict 에 익숙해지면 conflict 는 다음과 같이 느껴집니다. git 이 우리에게 이렇게 얘기하는 겁니다. "주인님 제가 다 알아서 병합해줄 것인데요. 이 부분은 양쪽 다 동시에 수정했기 때문에 제가 병합할 수 없습니다. 여기만 주인님이 처리해주시면 나머지는 제가 처리할게요" 라고 얘기하는 겁니다. 그래서 기능입니다. 가장 빛나는 기능입니다. 

  • 우선 이전과 같이 git init manula-merge 로 디렉터리를 만듦과 동시에 init 시켜줍니다. 

  • 그리고 이전에 했던 것과 동일하게, work.txt 라는 파일에 위와 같은 내용을 적었고, 해당 변경사항을 "work 1" 이라는 버전으로 commit 했습니다. 그리고 o2 라는 branch 도 만들었습니다. 

  • 그 결과 main 과 o2 모두 work 1 이라는 커밋에 기반하고 있는 상태가 되었습니다. 이 상태에서 main 과 o2 의 branch 에서 같은 부분을 다른 내용으로 수정하겠습니다.

main, o2 branch 에 각각 같은 위치에 다른 내용으로 work.txt 파일을 수정했다. 

  • main 과 o2 branch 에 있는 work.txt 파일안에 같은 부분을 다른 내용으로 수정하고 각각을 main work 2 , o2 work 2 버전으로 commit 했습니다.

  • o2 의 수정사항을 main branch 에서 병합해보겠습니다. 
  • 우선 main branch 로 checkout 을 해야 하고, 그 다음 git merge o2 라고 명령하면 됩니다.
  • 그런데, conflict 가 발생했다는 메시지가 나오게 됩니다. 

  • git status 를 통해서 현재 상황을 보면, both modified: work.txt 로 work.txt 파일이 양쪽에서 수정되어서 conflict 충돌이 발생했다고 알려주고 있습니다.

  • work.txt 파일로 들어가보면 위와 같이 내용이 수정된 것을 확인할 수 있습니다. 
  • 복잡한 내용들이 있는데, 혼돈과 혼란스럽습니다. 이제 공부를 하면 질서로 바뀌게 됩니다. 
  • ======= 이 부분은 구분자입니다. 
  • 구분자를 중심으로 윗 부분은
    <<<<<<< HEAD
    main
    현재 branch 로 main 에서 수정된 내용을 의미합니다.
  • 구분자를 중심으로 아랫 부분은
    o2
    >>>>>>> o2
    로 현재 브랜치인 main 에 병합되는 버전인 o2 에서 수정된 내용을 의미합니다.
  • git 은 현재 두 버전에서 같은 파일 같은 부분을 다르게 수정했으므로, 이 부분을 어떻게 할지 정해주세요! 라고 말해주고 있는 겁니다. 
  • 여기서 main 이 내가 원하는 내용이었다라고 하면 main 을 제외한 나머지 내용들을 모두 지워주면 됩니다. 그리고 반대로 o2가 내가 원하는 내용이었다면 o2를 제외한 나머지 내용들을 모두 지워주면 됩니다. 반대로, 둘다 살리고 싶다면 둘다 남기고 나머지를 다 지워주면 되겠습니다. 즉, 내가 원하는 내용으로 수정하고 나머지 내용들은 지우면 됩니다.

  • 이렇게 우리가 git 에게 main, o2 이렇게 병합해줘! 라고 알려주는 것입니다.

  • 그 다음에, git add work.txt 명령을 해주면 git 에게 "내가 충돌을 해결했어" 라고 말해주는 것과 마찬가지입니다.

  • git status 로 현재 상태를 보면 modified: work.txt 파일이 Staging Area 로 올라온 것을 알 수 있습니다. 

  • git commit -m 을 하지 않고 git commit 명령으로 editor 로 들어가 봅시다.

  • 그러면 충돌 conflicts 가 발생을 했었고, 사용자가 수정을 마친 상태인 것 같다 라고 알려줍니다. 
  • 이 상태에서 ctrl x + Y + Enter 를 통해 commit 을 실행합니다.

  • git log 를 실행해 보면 새로운 버전이 생성된 것을 볼 수 있습니다. 
  • 그리고 merge 된 해당 버전은 o2 의 최신 버전과 main 의 최신 버전을 부모로 갖고 있다라는 것을 손쉽게 파악할 수 있습니다. 

  • 또한 work.txt 파일에 들어가보면 우리가 원하던 대로 파일이 잘 수정된 것을 확인할 수 있습니다.
  • 여러분 축하드립니다. 여러분은 이제 conflict 가 정말 유용한 도구라는 것을 알게 되었고 느끼게 되었습니다. 
 출처 : https://opentutorials.org/course/3840