Day 02

.·2022년 4월 6일
0
이 글은 팀 개발을 위한 Git/Github 시작하기를 읽으며 실습한 내용을 정리한 것입니다.

Chapter 3 - 여러 명이 함께 Git으로 협업하기


01 원격저장소에서 협업하기: 브랜치(Branch)

Git이 커밋을 관리하는 방식: 줄줄이 기차

  • 새로 만든 커밋은 기존 커밋 다음에 시간순으로 쌓인다.
  • 혼자서 작업한다면 커밋을 한 줄로 쌓아가면 되지만 두 명이 협업한다면 두 줄로 갈래가 나뉜다.
  • 특정 기준에서 줄기를 나누어 작업할 수 있는 기능을 브랜치라고 한다.

브랜치

  • 브랜치는 물리적으로 '길'이 존재해서 그 길에 올리는 것이 아니라 단순히 커밋을 가리키는 '포인터'이다.
  • 커밋1 <- 커밋2 <- 커밋3

    • main 브랜치가 커밋3을 가리키고 있고, 커밋3의 상태에서 고양이 브랜치를 새로 만들면 고양이 브랜치도 커밋3을 가리킨다. 브랜치가 포인터라는 것은 그저 커밋을 가리키는 것만으로도 분기를 만들 수 있다는 장점이 있다.
    • 분기를 만들려면 프로젝트를 통째로 복사해야 해서 무겁고 시간이 많이 걸리는 SVN과 같은 버전 관리 툴과는 달리 Git은 가볍고 빠르다.
  • 브랜치 사이를 넘나들기 위해서는 어떻게 해야할까?
    • [HEAD]라는 특수한 포인터를 사용한다. (브랜치 혹은 커밋을 가리키는 포인터)
    • [HEAD]를 이용해 브랜치 사이를 넘나들 수 있다.
    • 브랜치의 최신 커밋이 아닌 과거 커밋으로도 [HEAD]를 이동시킬 수 있다.


02 브랜치 실습 기본 : 만들고 이동하기

새 브랜치 만들기

  • 보통 하나의 개발 브랜치에는 한 사람만 작업해서 올리는 것이 바람직하다.(그래야 버전이 꼬일 걱정이 없으니)
  • 여러 사람이 작업하는 원격저장소에는 미리 브랜치 규칙을 정하는 것이 일반적이다.

    ex)

    1. [main] 브랜치에는 직접 커밋을 올리지 않는다.(동시에 작업하다 꼬일 수 있으니)
    2. 기능 개발을 하기 전에 [main] 브랜치를 기준으로 새로운 브랜치를 만든다.
    3. 이 브랜치 이름은 [feature/기능이름] 형식으로 하고 한 명만 커밋을 올린다.
    4. [feature/기능이름] 브랜치에서 기능 개발이 끝나면 [main] 브랜치에 이를 합친다.

  • 소스트리에서 브랜치를 생성할 때 f'eature/detail_page'와 같이 브랜치 이름에 '/'를 넣으면 아래와 같이 'feature'가 폴더처럼 구분되어 보인다. (소스트리의 편의 기능)

  • 새 파일을 만들고 커밋을 하면

    • 예전에 했더 커밋들 위에 [feature/detail_page] 브랜치의 '디테일 페이지 추가' 커밋이 추가된 것을 확인할 수 있다.
  • 기존의 파일을 수정하고

    • 커밋할 때 '-에 바뀐 내용 즉시 푸시'에 체크를 하고 커밋을 하면 현재 브랜치인 [feature/detail_page]에 푸시까지 한 번에 된다.
  • '기능 명세 3번에 추가' 커밋이 생성되면서 [origin/feature/detail_page] 브랜치 꼬리표도 붙은 것을 볼 수 있다. [origin/]이 붙은 것으로 봐서 원격저장소에도 잘 올라갔다는 것을 알 수 있다.


브랜치 이동하기 : 체크아웃(checkout)

  • 새로운 브랜치를 생성할 때 기준이 될 브랜치로 이동해서 브랜치를 생성해야한다.

    • main 브랜치를 더블클릭 하거나 우클릭->체크아웃으로 main 브랜치로 이동 가능
  • cart라는 새로운 브랜치를 만들어서 새 파일을 만들고 기존 파일 수정

    • [main]브랜치 '소스트리 add, commit 연습' 커밋을 베이스로 [feature/detail_page] 브랜치 '기능 명세 3번에 추가' 커밋, [feature/cart] 브랜치 '장바구니 담기 기능'커밋, 두 가지(브랜치)가 뻗어 나왔다.


03 브랜치와 브랜치를 합치기 : 병합(merge)

병합이란?

  • 두 버전의 합집합을 구하는 것

    1. Merge commit(병합 커밋)
    : 꽃을 든 문어와 모자를 쓴 문어를 합치면 꽃을 들고 모자를 쓴 문어가 나올 것이다. 이는 새로운 상태니까 새롭게 저장하면 된다.
    2. Fast-forward(빨리 감기)
    : 그냥 문어와 모자 쓴 문어를 합치면 모자 쓴 문어가 될 것이다. 합친 결과물이 뒷 문어와 동일하다. 이는 새로 상태를 만들어 줄 필요 없이 뒷 문어로 상태를 바꿔주면 된다. Git에서는 이를 '빨리 감기 병합'이라고 한다.(새로 추가되거나 충돌나는 것 없이 그냥 앞으로 이동하기만 하면 되어서 '빨리 감기'라고 부름)
    3. Confilct(충돌)
    : 꽃을 들고 털모자를 쓴 문어와 다른 모자를 쓴 문어를 합치려 한다. 꽃은 겹치지 않으니 잘 합쳐졌는데 어떤 모자를 써야 할지 모르는 상태이다. Git에서는 이를 '충돌 상태'라고 한다. (충돌이 난 부분만 확인하고 무엇을 남길지 수동으로 선택해 주면 해결 가능)


브랜치 합치기 실습: 빨리 감기 병합

  • [main] 브랜치를 기준으로 [feature/detail_page] 브랜치를 합칠 것이므로 main 브랜치로 체크아웃
  • 병합하기를 원하는 커밋에서 우클릭을 한 뒤 병합 선택

  • 아래와 같은 창이 뜨는데 [fast-forward가 가능해도 새 커밋으로 생성]을 선택하면 빨리 감기 병합이 가능해도 명시적으로 병합 커밋을 만든다.(브랜치 병합 기록이 명시적으로 남기 때문에 선호하는 개발자도 있음)

  • [main] 브랜치가 [feature/detail_page] 브랜치와 같은 커밋을 가리키는 것을 알 수 있다.(빨리 감기 방식)

    • 현재 로컬저장소에서만 병합이 일어났기 때문에 [main] 옆에 숫자 2가 있다. 2개의 커밋이 로컬저장소에서만 이뤄졌고 원격저장소에는 올라가지 않았다는 뜻이다.
  • push를 해주면

    • [main]과 [origin/main] 모두 '기능 명세 3번에 추가' 커밋을 가리키고 있는 것을 볼 수 있다.


04 둘이 똑같은 코드를 고쳤을 때: 충돌 해결하기

브랜치 합치기 실습 : 병합 커밋 및 충돌 해결

  • [main] 브랜치에 병합할 때는 [main] 브랜치에 바로 병합하지 않고 나만 쓰는 브랜치에서 먼저 병합해 보고 문제가 없는지 확인해야한다.(물론 main 브랜치에 바로 해도 상관없지만)
  • [feature/cart] 브랜치로 이동하여 [main] 브랜치의 최신 커밋에서 우클릭을 한 후 병합을 선택한다.

  • 두 브랜치가 동일한 파일에서 같은 라인의 코드를 수정했기 때문에 아래와 같은 팝업 창이 뜬다.

  • 아래에서 '커밋하지 않은 변경사항'을 누르면 practice2.md 파일이 스테이지 아래에 있는 것을 확인할 수 있다. 이 파일에서 충돌이 났기 때문에 스테이지 아래에 있는 것이다.

  • 비주얼 스튜디오 코드에서 파일을 열어보면

    • 6번째 라인 '======='을 기준으로 위는 베이스 브랜치인 [feature/cart] 브랜치의 코드, 아래는 병합의 대상인 [main] 브랜치의 코드가 보인다.
    • Accept Current Change를 누르면 위의 코드만 남고, Accept Incoming Change를 누르면 아래의 코드만 남고, Accept Both Change를 누르면 위 아래 모두 코드가 남는다. (Git의 기본 기능은 아니고 비주얼 스튜디오 코드의 편의 기능임)
  • 아래와 같이 코드를 수정한 뒤 저장

  • 소스트리에서 오른쪽 미리보기 창에서 충돌이 모두 해결되었는지 확인한 후 add

  • 커밋을 누르면 아래와 같은 메시지가 자동으로 떠있다.

    • 그대로 커밋해도 되고 원하는대로 수정해도 상관없음
  • [feature/cart] 브랜치의 '장바구니 담기 기능' 커밋과 [main] 브랜치의 '기능 명세 3번에 추가' 커밋이 합쳐진 '병합 커밋'이 새로 생겨 [feature/cart] 브랜치에 올라가 있는 것을 확인할 수 있다.

  • 병합된 커밋에 문제가 없다는 것을 확인했으니 이 병합 커밋을 [main] 브랜치에도 반영하면 된다.


정리

  1. [main] 브랜치를 베이스로 [feature/detail_page]와 [feature/cart] 브랜치를 각각 만들어 작업
  2. [feature/detail_page]를 수정하고 [main] 브랜치를 기준으로 병합하면 [main]은 수정된 것이 없으므로 빨리 감기 병합이 가능(main 브랜치의 포인터가 [feature/detail_page] 브랜치의 최신 커밋을 가리키게 됨)
  3. [feature/cart] 브랜치에서 [main] 브랜치에서 수정되어 있는 파일의 같은 코드 라인을 수정
  4. [main] 브랜치에 병합하기 전 문제가 없는지 확인하기 위해 내 브랜치인 [feature/cart]를 기준으로 [main] 브랜치를 우선 병합
  5. 같은 파일의 같은 라인을 수정했기 때문에 충돌이 발생
  6. 원하는 대로 수정한 후 다시 병합
  7. 문제가 없이 병합 되었다면 이 병합된 커밋을 다시 [main] 브랜치를 기준으로 병합


05 브랜치를 합치는 예의바른 방법: 풀 리퀘스트

  • 충돌만 해결했다고 무작정 내 브랜치를 [main] 브랜치에 병합해도 될까?
  • 예를 들어 [main] 브랜치에는 완벽한 코드만 두자고 약속했다면, 내가 이 브랜치에서 무엇을 바꾸었는지 협력자가 확인할 수 있는 과정을 거쳐야 한다.
  • 이 때 필요한 것이 '풀 리퀘스트'이다.

풀 리퀘스트 만들기

  • 먼저 댓글 기능 제작을 위해 [feature/comment] 브랜치를 생성

  • 새 파일을 만들고 commit과 push를 하면 내 github에 아래와 같이 노란색 음영이 뜬다.

    • 노란색 음영의 초록색 버튼은 '니가 최근에 이 브랜치에 코드를 업데이트했으니 협력자에게 풀 리퀘스트를 보내려고 한다면 이 버튼을 클릭하라'는 의미(최근에 푸시한 브랜치가 있을 때만 보여지므로 다른 브랜치로 풀 리퀘스트를 보내고 싶거나 직접 설정을 변경하고 싶다면 pull request에서 직접 해주면 된다.
  • 풀 리퀘스트를 누르면 아래와 같은 페이지가 나온다.

    • 먼저 설정해야 할 것은 베이스 브랜치와 비교(compare) 브랜치이다. (병합한 결과물이 올라갈, 즉 기준이 되는 브랜치가 베이스 브랜치, 현재 기준 브랜치의 비교대상이 되는 브랜치가 비교 브랜치)
    • Reviewers에서 협력자 여려 명을 찝어서 이 풀 리퀘스트를 검토해 달라 요청할 수 있다. 보통 같은 팀원이나 해당 기능과 연관된 동료를 선택
    • Assignees에는 이 풀 리퀘스트를 담당하는 동료를 적어준다. 보통 자기 자신이다.
    • Labels에는 이 풀 리퀘스트에 관한 라벨을 달아준다. 예를 들어 [버그], [리뷰 필요], [백엔드] 등이 있다.
  • 풀 리퀘스트를 통해 병합을 완료한 후 소스트리를 보자

    • 아직 원격저장소의 [origin/main] 브랜치는 옛날 커밋을 가리키고 있다.
    • Git에서 새로운 이력을 업데이트하는 명령은 [패치]이다.
    • 풀이 실제 코드를 내려받는 데 비해 패치는 그래프만 업데이트한다.(코드와는 전혀 상관이 없음)
  • 패치 후

    • [origin/main]이 새롭게 만들어진 병합 커밋을 가리키고 있다.
  • 내 컴퓨터의 [main] 브랜치에도 새로운 커밋을 반영하기 위해 체크아웃 한 후 Pull을 해준다.


정리

  1. 브랜치에 병합하기 전 어떤 것을 수정했는지 협력자가 확인할 수 있는 과정을 거치는 게 풀 리퀘스트
  2. Github이나 Gitlab에서 풀 리퀘스트롤 통해 머지
  3. 내 로컬에서도 패치를 통해 새로운 이력을 업데이트
  4. 풀을 통해 원격저장소의 코드가 현재 내 버전보다 최신이라면 원격저장소의 코드를 가져와 병합


06 개발 완료, 출시하기: 릴리즈(release)

프로그램의 버전(version)이란?

  • 의미있는 특정 시점
  • 버전을 올리는 것은 크게 메이저 업그레이드와 마이너 업그레이드로 나뉜다.
  • 메이저 업그레이드 : 사용자들이 크게 느낄 변화를 적용했을 때 (v2.x -> v3.x)
  • 마이너 업그레이드 : 작은 변화 등이 생겼을 때(v.2.3 -> v.2.4)

특정 커밋에 포스트잇 붙이기 - 태그(tag)

  • 프로그램을 출시하는 것을 '릴리즈(release)'라고 한다.
  • 병합을 마친 [main] 브랜치를 서버에 올려서 사용자들이 쓸 수 있도록 배포하고, 현재 코드 상태를 버전 v1.0.0이라고 기록하려 한다. 이것을 태그를 통해 간단하게 표시할 수 있다.

  • [main] 브랜치에서 태그 아이콘을 누르고 태그를 추가한다.

  • [main] 브랜치 라벨 옆에 [v1.0.0] 라벨이 새로 붙은 것을 확인할 수 있다. (태그도 커밋을 가리키는 포인터)

  • 만든 태그는 푸시를 해줘야 원격저장소에서도 볼 수 있다.

    • 푸시할 때 밑에 모든 태그 푸시를 체크하고 푸시
  • GitHub에서 확인

    • [zip] 아이콘을 누르면 해당 태그가 가리키는 버전을 압축파일로 내려받을수 있다.

0개의 댓글