CodeGym /행동 /JAVA 25 SELF /안전한 실험: 브랜치로 작업하기

안전한 실험: 브랜치로 작업하기

JAVA 25 SELF
레벨 25, 레슨 2
사용 가능

1. 브랜치란 무엇이며 왜 필요한가?

Git에서 브랜치로 작업하는 것은 버전 관리를 구성하는 핵심 요소 중 하나로, 하나의 저장소에서 여러 개발 라인을 병렬로 진행할 수 있게 해줍니다. 브랜칭은 협업, 실험, 프로젝트의 다양한 버전 관리를 위해 Git을 강력한 도구로 만들어 줍니다.

            gitGraph
            commit id: "Initial setup"
            commit id: "Add base features"
            branch feature/new-idea
            checkout feature/new-idea
            commit id: "Implement new logic"
            commit id: "Refactor the logic"
            checkout main
            commit id: "Urgent bugfix on main"
            merge feature/new-idea
            commit id: "Prepare for release"
        
기본 브랜치 main에서 새 브랜치 feature/new-idea가 갈라져 안전하게 개발합니다. 작업이 끝나면 다시 main으로 병합합니다.

프로젝트에서 대대적인 변경을 하거나 위험한 실험을 해 보고 싶다고 가정해 보세요. Git이 없다면 어떻게 했을까요? 아마도 프로젝트 전체를 새 폴더에 복사해 그곳에서 작업했을 겁니다. 결과가 마음에 들면 원본 폴더로 옮기고, 아니면 복사본을 그냥 삭제했겠죠.

Git의 브랜치는 같은 원리를 훨씬 우아하게 구현합니다. 책 집필에 비유해 보겠습니다:

  1. 완성된 원고가 있습니다(이것이 기본 브랜치 main입니다).
  2. 대안적인 결말을 쓰고 싶습니다(예: feature/new-idea라는 새 브랜치를 만듭니다).
  3. 새 결말을 작성하되, 기존 원고 본문에는 영향을 주지 않습니다(새 브랜치에서 작업).
  4. 새 결말이 더 낫다면 예전 것을 교체합니다(브랜치를 병합 — merge).
  5. 불필요한 예전 초안은 삭제할 수 있습니다(브랜치를 삭제).

2. 새 브랜치 만들기와 그 안에서 작업하기

단계 1. 브랜치 관리 메뉴를 엽니다.

IDE 상단 패널에는 현재 브랜치 이름을 표시하는 위젯이 있습니다(기본값은 — main). 이를 클릭하고 + New Branch를 선택합니다.

단계 2. 새 브랜치 이름.

좋은 관례는 해결하려는 작업에 맞게 브랜치 이름을 짓는 것입니다. 예를 들어, feature/add-usage-examples.

브랜치를 만들면 IDE가 자동으로 그 브랜치로 전환합니다. 같은 위젯에서 새 이름을 확인할 수 있습니다.

단계 3. 변경을 만들고 커밋합니다.

이제 여러분은 자신의 "샌드박스"에 있습니다. 파일 README.md에 사용 예시 섹션을 새로 추가해 봅시다. 변경을 가하고 지난 강의에서 배운 대로 commit을 수행하세요.

3. 브랜치 간 전환

사용 예시가 담긴 여러분의 변경 사항은 이제 feature/add-usage-examples 브랜치에 안전하게 저장되었습니다. 기본 브랜치 main으로 돌아가서 상태를 확인해 봅시다.

단계 1. 현재 브랜치 이름이 표시된 위젯을 다시 클릭합니다.

단계 2. 목록 Local 또는 Recent에서 브랜치 main을 선택하고, 나타나는 하위 메뉴에서 Checkout을 클릭합니다.

단계 3. 결과를 확인합니다.

전환하자마자 파일 README.md를 열어 보세요. 사용 예시 섹션이 보이지 않을 것입니다! 그 섹션은 다른 브랜치에 남아 있습니다. 이렇게 하면 새 기능을 개발하면서 main 브랜치의 안정적인 버전에는 영향을 주지 않을 수 있습니다.

4. 브랜치 병합(Merge)

명령 merge는 브랜치 feature/add-examples의 모든 커밋(이 경우 커밋 C3)을 가져와 현재 브랜치 main에 합치면서 새 머지 커밋을 만듭니다.

            gitGraph
            commit id: "C1"
            commit id: "C2"
            branch feature/add-examples
            checkout feature/add-examples
            commit id: "C3: Add new section"
            checkout main
            merge feature/add-examples
        

이제 여러분은 feature/add-usage-examples 브랜치에서의 작업을 마쳤고, 그 변경을 기본 프로젝트에 반영하고 싶습니다.

단계 1. 대상 브랜치로 전환합니다.

변경을 추가하려는 브랜치, 어디로 추가할지의 대상 브랜치에 있는지 확인하세요. 우리 예에서는 main입니다.

단계 2. 병합을 수행합니다.

브랜치 관리 위젯을 다시 클릭합니다. 목록에서 변경을 어디에서 가져올지(feature/add-usage-examples)를 선택하고, 하위 메뉴에서 Merge feature/add-usage-examples를 main으로 선택합니다.

단계 3. 결과를 확인합니다.

이제 main 브랜치의 README.md 파일에 여러분의 새 예시 섹션이 나타납니다. 여러분의 작업이 프로젝트의 기본 버전과 성공적으로 병합되었습니다!

5. 병합 충돌: 두려워하지 마세요, 정상적인 일입니다!

가끔 브랜치를 병합할 때 충돌이 발생합니다. 이는 두 브랜치에서 같은 파일의 동일한 줄을 서로 다르게 수정한 경우에 일어납니다. Git은 어느 버전이 옳은지 스스로 결정할 수 없어서 여러분의 도움이 필요합니다.

            gitGraph
            commit id: "C1: 공통 기반"
            branch feature/new-title
            checkout main
            commit id: "C2: main의 변경"
            checkout feature/new-title
            commit id: "C3: feature의 변경"
        
두 브랜치, main과 feature/new-title 모두 공통 조상(C1)을 기반으로 하는 새 커밋(C2, C3)을 가지고 있습니다. 이는 병합 시 충돌을 초래합니다.

충돌을 시뮬레이션해 봅시다:

  1. main 브랜치에 있으며 저장되지 않은 변경 사항이 없는지 확인합니다.
  2. 곧바로 새 브랜치 feature/new-title를 만들되, 아직 그 브랜치로 전환하지 마세요. Checkout branch 체크가 해제되어 있는지 확인합니다.
  3. 이제 main 브랜치에 있는 상태에서 README.md의 첫 줄을 "My Awesome Project"로 바꾸고 commit합니다.
  4. feature/new-title 브랜치로 전환합니다. 여기서는 README.md의 첫 줄이 여전히 예전 상태일 것입니다. 이는 브랜치 생성 시점의 파일 상태입니다. 같은 줄을 "My Super Project"로 바꾸고 commit합니다.
  5. 다시 main 브랜치로 돌아가 feature/new-title과 병합합니다.

이제 Git은 두 브랜치가 공통 조상에서 서로 다른 방향으로 진행된, 분기된 이력을 가지고 있음을 확인합니다. 양쪽 이력에서 같은 줄이 변경되었기 때문에, Git은 어느 쪽이 맞는지 결정할 수 없어 충돌 해결 창을 보여 줄 것입니다.

Merge Revision

여기에서 보이는 것:

  • 왼쪽 (Your changes): 현재 브랜치(main)의 파일 버전.
  • 오른쪽 (Changes from branch...): 병합 대상 브랜치의 파일 버전.
  • 가운데 (Result): 여러분이 만들어 내야 할 최종 파일 버전.

>> 또는 << 화살표를 눌러 한쪽 변경을 통째로 채택할 수 있습니다.

가운데 패널의 결과가 만족스럽다면 Apply를 클릭하세요. IDE가 자동으로 머지 커밋을 만들고, 충돌이 해결됩니다.

왜 충돌이 발생하지 않았을까요?

모든 단계를 따라 했는데도 충돌이 발생하지 않는 경우가 있습니다. 대개는 Git이 fast-forward merge를 수행할 수 있었기 때문입니다. 한 브랜치의 이력이 다른 브랜치의 이력을 그대로 이어 받았기 때문이죠. 충돌을 확실히 보려면 두 브랜치의 이력이 공통 조상에서 서로 다른 방향으로 갈라져야 합니다.

예:

  1. main에 어떤 커밋이 하나 있습니다(가령 C1).
  2. main에 "My Awesome Project"라는 내용으로 새 커밋을 만듭니다. 브랜치 main은 이제 커밋 C2를 가리킵니다 (main -> C1 -> C2).
  3. feature/new-title 브랜치를 현재 main의 위치에서 만듭니다. 즉, 새 브랜치도 커밋 C2에서 시작합니다.
  4. feature/new-title에 "My Super Project"라는 내용으로 커밋을 만듭니다. 이 브랜치는 "앞으로 나아가" 이제 커밋 C3를 가리킵니다 (feature/new-title -> C1 -> C2 -> C3).
  5. main으로 돌아와(여전히 커밋 C2에 있음) feature/new-title을 병합하라고 지시합니다.

Git은 상황을 보고 브랜치 main이 브랜치 feature/new-title의 직계 조상임을 알아냅니다. 다른 브랜치에서 작업하는 동안 main의 이력에는 새로운 커밋이 없었습니다. Git은 이렇게 생각합니다: "아, 여기서는 main을 커밋 C3까지 앞으로 감기만 하면 되네. 아무런 모순이 없네". 그리고 단순히 main의 포인터를 커밋 C3으로 옮깁니다.

            gitGraph
            commit id: "C1"
            commit id: "C2"
            branch feature/new-title
            checkout feature/new-title
            commit id: "C3"
            checkout main
            merge feature/new-title
        

6. 변경 이력 보기

프로젝트에서 무슨 일이 일어나고 있는지 더 잘 이해하려면 이력을 살펴보는 것이 유용합니다.

IDE 하단의 Git 탭을 열고 Log를 선택하세요. 모든 브랜치와 커밋을 그래픽으로 볼 수 있습니다. 어떤 브랜치가 어디서 갈라졌고 어디서 병합되었는지를 한눈에 추적할 수 있습니다.

여기서 아무 커밋이나 클릭해 그 안에 포함된 변경 사항과 작성자, 시점을 확인할 수 있습니다. 말 그대로 코드의 타임머신입니다!

1
과제
JAVA 25 SELF, 레벨 25, 레슨 2
잠금
건축 사무소: 도형 면적 계산 🧱
건축 사무소: 도형 면적 계산 🧱
1
과제
JAVA 25 SELF, 레벨 25, 레슨 2
잠금
고급 메일 클라이언트: 이메일 작성 📦
고급 메일 클라이언트: 이메일 작성 📦
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION