본문 바로가기
컴퓨터 & IT (Computer & IT)/Github

[Github] 브랜치

by UltraLowTemp-Physics 2021. 4. 6.
728x90

아래는 "git 교과서" 내용을 정리한 글입니다.


1. 브랜치란? 

1) 저장 공간 하나에서 가상의 또 다른 저장공간을 만드는 것
2) 브랜치를 사용하는 이유? 
  프로젝트를 독립적으로 관리하는데 사용함 

   브랜치를 사용함으로써, 항상 안정된 코드를 유지할 수 있음 
  기존의 안정적인 코드와 개발 중인 작업을 구분하여 관리할 수 있음 

※ Git 브랜치의 특징 
- 새로운 기능 추가 -- 새로운 기능을 추가할 때는 최신 커밋으로부터 브랜치를 생성해서 개발 후, 리뷰 및 테스트를 끝내면 원래 브랜치로 다시 병합 
- 보그 수정 -- 버그가 발생한 브랜치로부터 새로운 브랜치를 생성 후, 버그 수정이 끝나면 원 브랜치로 병합 
                  -- 이때 브랜치의 이름은 BugFix와 같은 이름을 사용 함 
- 이전 코드 개선 
    -- 이전 코드의 함수의 로직 등을 수정할 때, 기존 코드를 주석 처리 후 사용하는 것이 아니라 브랜치를 사용함으로써 이전 코드를 삭제 후, 새 코드를 작성할 수 있다. 
    -- 이전 커밋에서는 이전 함수 및 이전 코드들에 정보가 있으니 걱정할 필요 없음 

협업 과정 중에서의 Branch
- 보통 하나의 개발 브랜치에는 한 사람만 작업해서 올리는 것이 바람직 -- 버전이 꼬일 걱정을 줄이기 위함 
- 여러 사람이 함께 작업을 하는 원격 저장소에서는 브랜치 규칙을 정하는 것이 일반적 
ex) -- master 브랜치에는 직접 커밋을 올리지 않음 ( 동시에 작업을 하다 꼬일 가능성이 존재하기 때문)
     -- 기능 개발을 하기 전 master 브랜치를 기준으로 세로운 브랜치를 작성 
     -- 브랜치의 이름은 [feature/기능이름] 형식으로 하며 한 명만 커밋을 올림
     -- 해당 브랜치에서 기능 개발이 끝나면 master 브랜치와 병합 

2. 깃 브랜치의 특징 

특징 설명
가상 폴더 ▪ 작업 폴더를 실제로 복사하지 않고 가상 폴더를 생성함
▪ 외부적으로 물리적인 파일 하나만 있는 것처럼 보임 
독립적인 동작 ▪ 브랜치를 이용하여 원본 폴더와 분리하여 독립적으로 개발작업을 수행할 수 있음
▪ 깃과 같은 버전 관리 시스템을 이용하면 쉽게 분리된 코드를 병합할 수 있음
▪ 깃의 브랜치는 규모가 큰 코드의 수정이나 병합을 처리할 때 유용 
빠른 동작  ▪ 다른 버전 관리 도구보다 가볍고 브랜치 전환이 빠름
▪ 깃은 Blob(일종의 포인터)를 도입하여 내부를 구조화하고, 이를 통해서 빠른 브랜치 전환이 가능함 
▪ 브랜치 명령을 사용하면 내부적을 커밋 하나를 생성하여 브랜치로 할당함 

 

3. 브랜치의 생성, 삭제 및 구조 

1) 기본 브랜치 (master branch) 
   ▪ 모든 커밋과 변경 이력은 브랜치에 기록됨 
   ▪ 깃은 최소한 1개 이상의 브랜치가 필요함 
   ▪ 깃을 처음 초기화할 때, master branch가 생성됨 

2) Branch 생성 및 이동 
   ▪ 브랜치를 생성하기 위해선 기준이 되는 브랜치 또는 커밋이 하나 있어야 하며, 깃은 이 커밋을 기준으로 새로운 브랜치를 생성함 
   ▪ 브랜치를 생성하거나 이동을 하기 위해선 반드시 워킹 디렉토리가 정리되어있어야 함. 
     ※ 워킹 디렉토리에 커밋되지 않은 내용이 있다면, 브랜치를 변경할 수 없음 
     ※ 워킹 디렉토리에서 커밋을 하지 않았다면, 체크아웃 (브랜치 이동)을 할 때, 경고가 발생하며 브랜치 이동이 제한됨 
     ※ 워킹 디렉토리를 커밋하지 않고 브랜치 이동을 할 시, "스태시 기능"을 이용할 수 있음 
   ▪ 브랜치를 이동한 후: HEAD 정보는 항상 변경된 브랜치의 마지막 커밋을 가리킴 
     - HEAD: 브랜치의 마지막 커밋을 의미
     - 브랜치가 이동하면 HEAD 포인터도 함께 이동 

    (a) 브랜치 생성: $git branch <branch_name> <commit_ID> 
      ▪ 브랜치 이름만 입력을 하는 경우, 현재 HEAD 포인터를 기준으로 브랜치를 생성 
      ▪ commit ID를 입력할 경우, 지정한 커밋 ID를 기준으로 브랜치를 생성

     (b) 브랜치 삭제
      ▪ 브랜치를 삭제하는 것: 해당 브랜치의 모든 커밋과 내용을 삭제하는 것
      ▪ 현재 자신이 있는 브랜치는 삭제할 수 없으며, 해당 브랜치를 삭제하기 위해선 다른 브랜치로 이동해야 한다. 
      ▪ 브랜치 삭제 명령어 1: $ git branch -d <branch 이름> 

          - -d 옵션은 스테이지 상태가 깨끗할 때만 삭제를 허용함 
          - 만일 워킹 디렉토리에서 작업한 흔적이 있거나 add 명령어로 스테이지의 인덱스가 변경된 상태라면 삭제하지 않음
      ▪ 브랜치 삭제 명령어 2 (강제 삭제) : $ git branch -D <branch 이름>
      ▪ 리모트 브랜치 삭제: $ git push origin --delete <리모트 브랜치 이름>

    (c) 브랜치 이름과 관련된 제약 사항
      ▪ 브랜치 이름은 슬래쉬(\)를 이용하여 계층적인 구조로 만들어서 사용할 수 있음
      ▪ 브랜치 이름은 기호(-), 마침표(.) 및 연속적인 마침표(..)로 시작할 수 없음 
      ▪ 빈칸, 공백 문자, 물결, 캐럿 (^), 물음표, 별표(*), 대괄호([]) 등을 포함할 수 없음 
      ▪ 브랜치 이름은 아스키 제어 문자를 포함할 수 없음 
      ▪ 브랜치 이름은 중복될 수 없음

3) 브랜치의 생성 및 이동과 관련된 명령어 정리 

목적 명령어 및 설명 
브랜치 생성 $ git branch <branch_name> <commit_ID>
브랜치 목록 출력 $ git branch
브랜치의 세부사항 및
목록 확인
$ git branch -v 
 브랜치 이름, 커밋 ID, 커밋 메시지를 확인 가능 
모든 브랜치의 정보를
확인하고자 하는 경우
$ git branch -a 
브랜치 이동 1) $ git checkout <이동할 브랜치 이름>
  ▪ 해당 브랜치의 마지막 커밋 위치인 HEAD 포인터로 이동
2) $ git checkout <commit hash key> 
  ▪ 커밋 해쉬 키로 이동하는 경우, 전체 40자리 해쉬키를 사용하지 않고 앞의 7자리만 사용해도 무리가 없다
  ▪ 앞의 7자리만 사용하더라도 중복될 확률이 작음 
3) HEAD를 이용한 이동 
  ▪ $git checkout HEAD~n: 현재 커밋으로부터 n번째 이전의 커밋으로 이동 
4) $ git checkout -
  ▪ 바로 이전의 브랜치로 복귀 
브랜치 생성 및 생성된
브랜치로 이동
$ git checkout -b <생성할 브랜치 이름>
브랜치 로그 ▪ $ git log <options> 
  a. --graph: 로그 출력시, 브랜치 흐름을 같이 보여줌 
  b. --all: 모든 브랜치 로그를 출력 
▪ $ git show-branch --more=10 
  : --more 옵션으로 출력될 커밋의 갯수를 제한함

 


4. 원격 브랜치 

원격 브랜치(Remote Branch)란: 원격 저장소에 생성한 브랜치 혹은 브랜치를 가리키는 포인터 
※ 리모트 브랜치의 형태: <원격 저장소의 별칭>/<브랜치 이름>

원격 저장소와 연결된 로컬 저장소에서 새로운 브랜치를 생성한다고 해서 자동으로 원격 저장소에도 브랜치가 생성되는 것이 아니며, 원격 저장소에서 등록된 브랜치가 자동으로 로컬 저장소에 만들어지지 않는다. 별도의 명령어를 통해 저장소를 동기화 해야한다. 

4.1 브랜치 추적 (Tracking Branch) 및 브랜치 업로드 

1) 브랜치 추적(업스트림)이란? 원격 저장소의 브랜치를 가리키는 것 
  ▪ 일종의 원격 브랜치를 가리키는 북마크와 같음 
  ▪ 추적 브랜치는 원격 브랜치의 마지막 커밋 해시 값을 가짐 
  ▪ 브랜치 추적의 포인터 정보: .git/ref에 저장됨 
  ▪ 로컬 저장소가 원격 저장소와 연결될 때, 원격 브랜치의 트래킹 정보는 자동으로 갱신됨 
  ※ 업스트림 트래킹 : 로컬 저장소의 브랜치와 원격 저장소의 브랜치를 매칭하는 것
     - 리모트 브랜치와 로컬 브랜치를 연결해주는 중간 다리 역활을 함 
     - 업스트림 브랜치: 로컬 저장소와 연결된 원격 저장소 
     - 업스트림 브랜치 설정: $git push --set-upstream <원격 저장소 별칭> <브랜치> / $git push -u <원격 저장소 별칭> <브랜치>

2) 브랜치 업로드
  ▪ 로컬 저장소의 브랜치 정보는 원격 저장소에 자동으로 등록되지 않음 

  ▪ 로컬 저장소의 브랜치를 원격 저장소에 동기화"push 명령어"를 이용
      - $git push -u <원격 저장소의 별칭> <로컬 저장소의 브랜치 이름> 
      - 명령어를 입력 후, 원격 저장소에는 로컬 저장소와 동일한 브랜치를 생성
  ▪ 로컬 저장소의 브랜치 이름을 원격 저장소에 다른 이름으로 변경하여 푸시하는 경우 
      - $ git push -u <원격 저장소의 별칭> <브랜치 이름>:<새로운 브랜치 이름> 
      - 다른 사람들과 협업을 하는 경우, 서로 같은 이름의 브랜치를 생성한 후, 푸시를 하게 되면 충돌이 발생할 수 있음.
        따라서 수동으로 서로 다른 로컬 브랜치와 리모트 브랜치를 지정하여 연결할 수 있음
      - 브랜치를 직접 수동으로 지정하는 경우 ":"를 이용함 

※ 원격 브랜치와 관련된 명령어 

목적 명령어 및 설명
등록된 원격 브랜치 확인 $ git remote show <원격 브랜치 이름>
원격 저장소의 리모트 브랜치 목록 확인 $ git branch -r 
Tracking Branch 확인 $ git branch -vv 
원격 브랜치 복사 $ git checkout -b <새이름> origin/<브랜치이름>
업스트림 연결 $ git branch -u origin/<브랜치이름>

 

4.2 브랜치 전송 

1) 로컬 저장소의 브랜치를 원격 저장소로 전송하는 방법

전송 방법 설명
push ▪ 깃의 Push 작업들은 로컬 저장소의 파일뿐만 아니라 브랜치 정보와 커밋까지 모두 원격 저장소로 전송한다
▪ 처음에는 커밋과 브랜치를 푸시하는 하기 위해선, 수동으로 트래킹 브랜치와 업스트림을 설정해야 함
 - 원격저장소 연결만으로 업스트림이 자동으로 설정되지 않음 
 - $ git push --set-upstream <원격저장소 별칭> <로컬 저장소의 브랜치> 
 ex) 로컬 저장소의 master 브랜치를 origin 서버의 master로 업스트림을 설정 
   $ git push --set-upstream origin master
Branch fetch ▪ 일반적인 커밋 페치와 동일 
  - 리모트 브랜치를 fetch한다고 자동으로 로컬 저장소에 새로운 브랜치가 생기지 않음 
  - fetch: 원격저장소에서 리모트 브랜치 내용을 받기만 할 뿐, 자동으로 병합하지 않음 
▪ Remote branch가 fetch가 되면, 단순히 원격저장소별칭/브랜치 포인터만 생성함
  - 원격 저장소에서 fetch된 커밋들을 병합시키기 위해선 merge 명령을 사용함 

  - $ git merge <원격저장소별칭>/<브랜치이름>




HEAD 포인터 

Git은 마지막 커밋을 쉽게 확인할 수 있도록 HEAD 포인터라는 특수한 포인터를 제공한다. 
 ▪ HEAD 포인터: 작업 중인 브랜치의 마지막 커밋을 가리키는 마지막 포인터 
   a. 깃은 마지막 커밋을 기반으로 새로운 커밋을 생성한다. 이때, 마지막 커밋은 새롭게 생성된 커밋의 부모 커밋이다.  
   b. HEAD 포인터를 부모 커밋으로 대체하여 사용 
   c. HEAD 포인터를 사용하여 빠르게 스냅샷을 생성할 수 있음 

1) 브랜치와 HEAD 포인터
 ▪ 각각의 브랜치들은 각 브랜치에 대응되는 HEAD 포인터를 가진다. 

   - 각각의 브랜치마다 마지막 커밋이 다르기 때문에 각 브랜치마다 브랜치의 마지막 커밋 ID를 가리키는 HEAD 포인터를 하나씩 가짐 
   - 브랜치를 이동시키면 HEAD 포인터도 이동된다. 

2) HEAD 포인터의 종류 
 ▪ 로컬 저장소 브랜치의 HEAD 포인터와 원격 저장소 브랜치의 HEAD 포인터가 존재 
 ▪ 두 HEAD 포인터들 간의 차이를 나타내기 위해, AHEAD 및 BHEAD 포인터라는 것이 생김 
   (a) AHEAD

       - 서버로 전송되지 않은 로컬 커밋이 있는 경우 
       - 로컬 브랜치에 있는 커밋이 서버의 커밋 갯수보다 많은 경우 
   (b) BHEAD
       - 로컬 저장소로 내려받지 않은 커밋이 있는 것 
       - 원격 저장소의 커밋이 자신의 로컬 저장소보다 최신인 경우 
 
 

 

 

 

728x90

댓글