ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 차근 차근 살펴보는 Git
    Programming🧑‍💻/Git & Github 2024. 4. 28. 16:41

    변경사항을 추적하자

    프로젝트를 진행해 나가며 코드의 양이 점점 많아 지면
    어느 순간 내가 무언가를 바꿨는데 뭘 바꿨는지 기억이 나지 않는 상황이 벌어집니다.

     

    이와 관련된 상황들을 예방하기 위해서는 버전 관리를 해야합니다.
    그리고 git은 각 ‘커밋’(코드 덩어리)을 세이브 포인트로 하여 , 이들을 비교하며 무엇이 추가되었고 빠졌는지 변경점을 쉽게 알 수 있도록 도와주는 친구 입니다.

     

    예를 들어 첫번째 커밋(코드 덩어리)에서는 파란색으로 보이는 사과 아이콘을 빨간색으로 바꾼다면 Git은 이 변경사항을 인지하고 이 변경점들을 바탕으로 새로운 커밋(코드덩어리)를 만들 수 있게 해줍니다.

     

    개인이나 팀 내부에서 가지고 있는 룰에 따라 기준에 충족하는 코드의 변경사항이 생기는 경우 이를 커밋(별도의 커밋으로 만들어 놓으면)을 해놓으면 이후 개발 과정에서 각 커밋별로 어떤 변경사항이 있었는지를 쉽게 파악할 수 있습니다.

     

     

     

    기능을 나누어서 개발하자.

    프로젝트는 여러 feature(기능)들이 합쳐진 형태입니다. 따라서 각 기능별로 독립적으로 개발이 이루어질 수 있도록 사용하는 개념이 Branch입니다.
    가운데 있는 Branch를 Main Branch라 할 때,
    Main Branch로 부터 사용자 UI수정 Branch를 만들고 해당 branch에는 UI에 관련된 개발을 진행해 나갑니다. 이렇게 UI에 관련한 개발을 진행하던 와중에사용자 로그인 기능에 대한 요구가 생겼다고 해봅시다.
    이때 아직 완성되지도 않은 사용자 UI개발에 로그인 기능을 개발한답시고 코드를 섞으면 엉망징창이 될 수 있습니다. 따라서 기존에 개발중이던 사용자 UI수정 Branch는 그대로 나두고 MainBranch에서 사용자 로그인 기능 Branch를 따로 만들고 여기에 로그인 기능에 필요한 코드를 작성해나가면 여러 기능에 대한 작업을 중첩없이 각각 독립적으로 진행할 수 있습니다.

     

    Head : 내가 지금 어디에 위치해 있는가?

    위와 같이 각각의 기능들을 위해 별도의 Branch들을 별도로 만듬으로써 필요해지는 개념이 있습니다.
    내가 현재 지금 어느 Branch에서 개발을 하고 있느냐를 알고 있어야합니다.


    왜냐하면 새로운 커밋을 만들기 위해서는 그 이전의 커밋으로부터 변경사항을 ‘감지’해야하기 때문입니다.
    따라서 이전 커밋이 되는, 즉 기준점이 되는 커밋이 명확해야합니다. (그래야 뭐가 바뀌었는지 알 수 있음)

    Head는 현재 내가 위치한 Branch에서 가장 최근 Commit을 의미합니다.


    Git은 Head를 기준으로 하여 이와 비교를 통해 이후 생긴 코드 변경사항을 파악할 수 있습니다.

    예를 들어 현재 내가 사용자 로그인 기능을 개발하고 있다면 현재 Head는 사용자 로그인 기능 Branch의 가장 최근 커밋이 됩니다.

     

    또한 만약에 사용자 로그인 기능을 개발하던 와중 사용자 UI수정에 대한 작업이 필요한 경우 Head를 사용자 UI 수정 Branch로 옮겨아 합니다. (그래야 사용자 UI 수정 Branch)에서 작업하던 내용을 바탕으로 이후 변경사항을 감지할 수 있습니다.)

     

     

     

     

    Merge가 머징?

    각 기능별로 Branch를 나누어 하던 작업이 마무리가 된 경우 이를 하나의 Branch로 만들어주는 절차가 필요합니다. 각 기능들은 하나로 합쳐져야 하나의 앱으로써 동작할 수 있기 때문입니다. 이렇게 하나의 Branch를 다른 Branch에 합치는 것을 Merge 라고 합니다.

    Merge 기본 종류

    사용자 로그인 기능 BranchMain Branch에(Into) Merge 한다고 할때

    Fast-forward Merge

    • 병합하려는 Branch가 대상 Branch(Into)의 후속 커밋들만 가지고 있는 경우 -> 아래와 같이 사용자 로그인 기능 Branch의 첫 커밋이 Main Branchd의 최종 커밋인 경우
    • 예를 들어 Main Branch로 부터 사용자 로그인 Branch를 새로 만든 다음에 사용자 로그인 Branch에서 새로운 커밋들이 쌓이는 동안 Main Branch에서는 아무런 변경사항도 없었을 때
    • 대상 Branch에 병합하려는 Branch의 Commit들로 인한 변경사항을 반영만 해주면 됩니다.

     

     

    Three-way Merge

    • 두개의 Branch가 공통 조상으로부터 갈라진 후 독립적으로 발전한 변경 사항을 통합하는 과정
    • 예를 들어 사용자 로그인 기능 Branch사용자 UI 수정 BranchMain Branch의 같은 커밋으로부터 나왔다. 이후 각각의 기능 Branch는 별도로 개발을 완료한 후 이들을 하나의 Branch로 합치는 과정입니다.
    • 위에서 사용자 로그인 기능 BranchMain Branch로 Merge 됨으로써 사용자 UI 수정 Branch는 처음 Main Branch로 부터 갈라져 나왔을 때의 Main Branch의 Head와 현재 Main Branch의 Head가 다른 상태입니다.
    • 이때 사용자 UI 수정 BranchMain Branch로 통합하려 할때
      사용자 UI 수정 Branch의 최신 커밋과 Main Branch의 최신커밋(사용자 로그인 기능 Branch가 merge되어 만들어진 새로운 커밋) 그리고 이둘의 공통 조상 커밋 총 3개를 비교합니다.

    • 만약에 사용자 UI 수정 BranchMain Branch의 최신 커밋들을 비교했을 때 둘이 중첩되는 코드가 없는 경우 충돌이 없으므로 merge를 진행합니다.
    • 만약에 사용자 UI 수정 BranchMain Brnach의 최신 커밋들을 비교했을 때 둘이 중첩되는 코드가 있는 경우 공통 조상 커밋을 기준으로 충돌을 해결해야 합니다.

     

    Git 사용 과정 좀더 자세히 보기

    • 개발이 어느 정도 진행이 되어 아래와 같이 커밋들이 생성되어 있습니다.
    • 현재 커밋 C가 Head인 상태에서 ‘화면에 버튼을 추가’ 하고 ‘배경색을 교체’ 하고자 합니다.

    Working Directory

    • Working Directory란 Head를 기반으로 다음 작업을 진행하는 공간입니다.
    • 현재 C 커밋을 기반으로 화면에 버튼을 추가하고 배경색을 변경하기 위한 코드를 작성하고 있습니다.
    • 현재 배경 색 변경은 완료가 되었고 화면에 버튼을 추가하는 작업은 진행중인 상태입니다.

    Staging Area

    • Staging Area 란 Working Directory에서 진행한 작업중 커밋으로 만들고 싶은(변경사항을 반영하고 싶은) 작업을 선별에서 올려(Stage) 두는 공간 입니다.
    • Working Directory에서 git add 명령어를 통해 원하는 파일을 Stage ( Staging Area)에 올려 놓을 수 있습니다.
    • Staging Area에 올려 놓은 작업물들을 현재 Head 커밋인 C와 비교해서 변경사항을 감지합니다.
    • git commit 메서드를 통해 추적된 변경사항을 커밋으로 만듭니다.
    • 아직 완성되지 않은 화면 버튼 추가 작업은 Working Directory에 나두고 완료된 배경색 변경을 Statging Area에 Stage 한 뒤 commit을 통해 해당 변경사항을 커밋으로 남겼습니다.

     

    하늘 높이 내 코드를 띄워

     

    지금까지 한 것들은 모두 로컬(내 맥북 안)에서만 진행되었습니다.
    즉 맥북을 잃어버리기라도 하면 모든 작업이 맥북과 함께 사라진다는 말입니다.


    또한 협업을 위해 코드를 공유하고자 할때 직접 폴더를 복사해서 메일이나 다른 수단을 통해서 전달해야하며 이 경우 서로가 어떤 작업을 하고 있는지 , 충돌이 있지는 않은지 실제로 코드를 받아서 보기 전까지는 알 수가 없습니다. 이러한 문제점을 해결하기 위해 원격저장소라는 개념이 등장했습니다.

     

    로컬에서 한 작업을 온라인 상에 띄워서 분리하는 것을 통해 원격 저장소에 별도로 관리할 수 있으며 해당 저장소을 중앙에 매개체로 하여 다른 팀원들간의 작업을 효율적을 수행할 수 있습니다. 원격저장소 서비스를 제공하는 업체 중 대표적인 기업이 GitHub 입니다.

    원격저장소를 통해 협업이 이루어지는 과정을 다음 시나리오를 통해 단계별로 이해할 수 있습니다

     

     

     

     

    1. 따봉쥐는 자기의 맥북을 이용해 새로운 프로젝트를 시작했습니다. Main Branch에 몇개의 커밋을 한 상태입니다. 따봉쥐는 따봉도치와 협업을 위해 GitHub을 사용하고자 합니다.

    1. 따봉쥐는 Github에서 ‘Ddabbong’ Repository를 새로 만들고 Loacal에서 작업한 내용을 해당 Repository의 Origin Branchpush를 했습니다.

    1. 따봉도치는 따봉쥐에게 전달받은 Repository를 clone해서 origin의 내용을 받아왔습니다.

    1. 따봉쥐와 따봉도치는 각각 기능A와 기능 B를 담당해서 개발을 하기로 했습니다. 따라서 둘은 각각 로컬에서 Feature A BranchFeature B Branch를 만들어서 개발을 진행합니다.

    1. 성실한 따봉도치는 순식간에 기능을 완성한뒤 이를 Remote에 push 했습니다.

    1. 따봉쥐는 Github이 아닌 자신의 맥북에서 따봉도치가 한 작업을 일단은 보려고만 합니다. 이때 fetch를 사용합니다. fetch는 원격 저장소의 최신 커밋 정보를 로컬 저장소로 가지고오되 로컬의 작업 브랜치와는 합치지 않습니다.

    Local에는 직접 작업을 하고 있는 Local과 현재 Remote의 상태를 파악할 수 있는 Remote in Local(현재 Remote의 상태를 추적하는 Branch) 두가지로 구분할 수 있습니다.

    1. 따봉쥐는 featureA 개발을 완성한 뒤 이를 Remote에 Push 했습니다. 상남자인 따봉도치는 따봉쥐를 믿고 Origin으로 부터 pull을 받아 자신의 로컬 Branch에 따봉쥐가 개발한 featureA Branch에 합쳤습니다.

    pull은 fetch와 merge를 동시에 수행합니다. 즉 원격 저장소의 변경사항을 가져와서 자신의 로컬 브랜치에 즉시 반영합니다.

     

     

    댓글

Designed by Tistory.