Branch

Git 과 Github의 브랜치전략 차이에대해 알아야 한다.

Git Flows

Git Flow 는 로컬중심 브랜치전략이다.
일반적으로 사용되는 브랜치는 main(master), develop, release, feature, hotfix 등이 있다.

  • main(master)
    배포의 기준이되는 브랜치로 , Release Tag를 기록한다.
    배포용이기 때문에 main에 직접 커밋하거나 머지하면 안되지만 예외적으로 hotfix 브랜치는 main에 바로 머지할수도 있다.

  • develop
    개발이 이뤄지는 브랜치로 동시에 작업하게되면 conflict가 발생할 수 있다.
    그래서 실제로는 feature브랜치에서 작업 후 develop 에 머지하는 방식으로 개발프로세스가 진행된다.

  • release
    실제 배포를 하기위해 준비하는 브랜치로 develop 브랜치에서 다음 릴리즈를 위한 개발이 끝나면 여기로 분기하여 버그픽스와 리팩토링을 진행한다.
    배포준비가 완료되면 그떄 main 브랜치로 머지한다.

  • hotfix
    배포가 완료된 main 브랜치에서 심각한 버그가 발생했을 때 사용하는 브랜치다.
    기본적으로 main에는 직접 커밋을 할 수 없으므로 핫픽스 브랜치에서 문제를 해결 후 main,develop에 머지한다.

  • feature
    개발 작업의 중심이 되는건 develop이지만, 실제 기능을 구현하는 브랜치는 feature다.
    이슈에 등록된 기능을 구현하거나 버그픽스,리팩토링 작업을 develop에서 분기된 feature에서 작업 후 머지한다.

Github Flows

Github Flow 는 remote 중심 브랜치전략이다.
중심이되는 main 브랜치와 각각의 feature 브랜치로 구성된다.
Git flow와 비교하면 main은 main,develop,release / feature는 feature,hotfix가 합쳐진 형태라고 보면 된다.

작업한 내용을 수시로 remote로 push 하여 항상 최신상태를 유지한다. 이 부분이 리모트중심 브랜치전략의 핵심이다.
develop이나 release 브랜치처럼 배포준비를 위한 브랜치가 따로 없기 때문에 main 브랜치에 머지하는 작업을 엄격하게 관리해야 한다.



Commit

커밋시에 커밋컨벤션에 따라 커밋메세지를 남겨야 협업과 유지보수가 원활해진다.
Git 에서 공부했던 커밋메세지와 거의 동일하지만, 만약 혼자 공부하거나 정리하는 목적이라면 한글로 정리한내용이 무엇인지 한줄로 적는것도 좋다.
기본적으로 header, body, footer를 선택적으로 작성하지만 footer는 꼭 작성하는것을 추천한다.

Header

커밋로그의 제목을 나타내는 부분으로 50자를 넘기지않고 대문자로 작성하며, 마침표도 붙이지 않는다.
일반적으로 Header에는 Tag를 붙이며 Tag에는 새로운기능(feat), 리팩토링(refactor), 버그수정(fix), style(코드포맷팅,주석처리), chore(빌드수정, 패키지관리자수정) 등 을 사용한다.

Body

작업에대한 상세기록을 나타내는 본문으로 특별한 format은 없고 헤더와 한칸 공백을 만드는것이 좋다.
72자를 넘지않게하며 Header에서 한줄로 설명가능하다면, 굳이 Body를 작성하지 않아도 된다.

Footer

Footer 는 해당 작업과 관련된 이슈의 Tag가 붙는다.
이슈Tag를 추가하면 Github에서 자동으로 해당태크를 인식하여 이슈와 관련된 커밋을 연결해준다.
이슈Tag 는 #{이슈번호} 로 적는다.



Issue

개발의 작업이되는 작은 단위
작업의 히스토리를 관리하기 위해 작성하는것이 좋다. 이슈도 커밋컨벤션과 비슷하게 제목의 맨 앞에 Tag를 붙인다.
작업 할 내용이 있다면 이슈로 내용을 등록하고 그 이슈에 맞는 feature브랜치를 생성해 작업을 생성한다.
이때 feature 브랜치명에 이슈태그를 붙이면 로컬에서 브랜치를 식별하기 편하다.
(feat-3 의 브랜치명은 3번이슈를 해결하는 브랜치라는것을 쉽게 알 수 있다.)

Issue Template

이슈에는 왜 이 작업을 해야하는지, 어떤 작업을하는지, 관련된 다른 이슈는 없는지를 기록한다.
이 내용을 매번 작성하기에는 생산성이 떨어지므로 이슈템플릿을 사용한다.

깃헙 레포설정에서 Features에 issues-> Set up templates를 선택하면 이슈를 등록 할 수 있다.
(실제 프로젝트의 .github 경로에 추가됨)

Feature/ Bug /Custom 기본 템플릿이 존재하며 이것을 기반으로 수정해서 작성도 가능하다.
Issue Tag, Label, Assignee를 설정 하고 커밋 형태로 이슈를 추가한다.

보통 왜 해야하는지 ## background , 뭘 할건지 ## To do 체크박스리스트 형태로 작성한다.
처음엔 번거롭지만 Tag나 Label을 깔끔하게 작성하는것이 매우 중요하다.



Pull request

머지 작업을 진행하기 전 팀원에게 코드를 받는 단계이다.
reviewr, assignee를 반드시 지정하고, 가능하다면 Label도 붙여야 한다.


PR Template

대략적인 내용(overview), 변경된 부분(change log), 리뷰어가 참고할 사항(to reviewer), 관련된 이슈(issue tag)를 기록한다.

이슈태그에 특정 키워드를 적어두면, 해당 PR이 default branch에 머지될 때 연관된 이슈가 자동으로 닫히도록 할 수 있다. (close, fix, resolve 등)
단, PR은 .github 경로에 가서 직접 md 파일을 주가해줘야 한다.

## Overview

## Change log

## To Reviewer

## Issue Tags
Closed | Fixed: #이슈번호
See also: #읽는대상

PR 체크

files chaged 에 들어가면 코드 왼편의 숫자부분에 마우스를 올려 코멘트를 남길 수 있다.
이후 코드리뷰가 마무리되면 Finish your review 버튼을 클릭해 리뷰를 끝낼 수 있다.

코드리뷰에서 approve 를 받으면 코드를 대상 브랜치로 머지할 수 있다.
이때 세가지 옵션이 있다.

  • create a merge commit : 머지 커밋을 추가로 남기고 머지
  • Squash and merge : 커밋로그를 하나로 합치면서 머지
  • Rebase and merge : 머지 커밋을 남지기 않고 기존 커밋로그를 유지한 채로 머지


Git tag

특정 커밋에 버전을 기록할 때 사용하는 기능으로 릴리즈 버전을 기록할 때 주로 사용된다.

  • Lightweight Tag : 버전만 기록하는 태그
  • Annotated Tag : 태그를 생성한 유저,이메일,태그생성날짜,태그메세지를 함께 기록하는 태그

Release

생성한 태그를 기반으로 Github에서 release 버전을 기록 할 수 있다.
레포화면의 우측 Releases -> Create a new release를 클릭해 생성 한다.

여기서 원하는 버전의 태그와 태그 설명을 설정 할 수 있고 pre-release 기능으로 임시 릴리즈상태로 만들기도 가능하다.

결국 다른 사람이 이 레포를 들어왔을 때 한눈에 어떤 버전인지 알 수 있다.


Git tag 생성

Github 의 repository의 Release 에서도 편하게 생성, 설정이 가능하지만, 터미널에서도 생성,푸시하는 법을 알고있어야 한다.

  • git tag <tag name> : 태그를 생성 (-a 옵션으로 Annotated 태그도 생성 가능)
  • git tag : 생성된 태그 확인 (git log 로도 커밋에 태그가 등록된것을 확인할 수 있음)
  • git show <tag name> : 태그 상세내용 확인
  • git push origin <tag name> : 생성한 태그 깃헙에 등록

'백엔드 > Git, Github' 카테고리의 다른 글

[Git] branch merge 방법  (1) 2022.09.22
[Git] 기초와 명령어  (0) 2022.09.22

Git 심화

브랜치를 merge 하는 다양한 심화방법이 있다.


Fast-forword

커밋이 공통이고 대상 브랜치의 커밋만 증가한 경우, HEAD 만 옮겨지는 상황
쉽게말해 main 에서 떨어져나온 f 브랜치에서 커밋을 생성한 후에 main에 merge 시키는것이 아니라,
f 브랜치를 main으로 변경시켜(HEAD를 main->f로 바로 이동) 별도의 merge없이 바로 수정내역이 추가되는것을 fast-foword 방식이라 한다.


3-way merge

협업시 가장 많이 이뤄지는 merge 방식
main 브랜치와 수정하려는 f 브랜치, main에서 새로운내용을 추가한 hotfix 브랜치가 있을때, hotfix는 이미 main에서 변경점이 생겼기 때문에 f 에서 hotfix로 바로 merge 할 수 없다. 이때 main,f,hotfix 간의 차이를 커밋으로 만들고 merge라는 새로운 커밋을 생성한다. 3way라는것은 이렇게 세개의 다른점을 커밋으로 저장한다는 의미다.
이후 이 merge라는 커밋에 main을 옮김으로써 병합이 완료된다.


rebase

기준이되는 브랜치의 커밋을 base 라고 한다.
rebase를 사용하여 merge 시점기준 브랜치의 가장 최신 커밋시점으로 base를 변경시키면, fast-foword 방식으로 별도의 커밋을 남기지 않고 병합시킬 수 있다.
(여러개의 중간의 중복되는 커밋을 하나로 압축하는 느낌이다.)

rebase 사용 시 -i 옵션을 주면 대화형 모드로 가독성 좋게 사용할 수 있다.
'git rebase -i main'

-p,pick : 해당 커밋을 수정하지 않고 그냥 사용(두개의 커밋이 있을때 둘다 pick 하면 두 커밋 그대로 rebase 됨)
-r,reword : 커밋메세지 수정
-e,edit : 커밋메세지와 작업내용을 수정할 수 있음(중간에 커밋추가도 가능)
-s,squash : 커밋여러개를 한개로 합치는 옵션으로 특별히 분기로 나눠야하는 커밋이 아니라면 히스토리를 간결하게 만듬
-f,fixup: 스쿼시와 같지만 fixup은 기준이되는 이전커밋메세지만 남기는 차이가 있고, 나머지 커밋메세지는 무시

브레이크 과정에서 rebase를 중단해야될경우?
--abort : rebase 중단
--continue : break 지점에서 다시 rebase 진행
--skip : 해당 커밋지점의 break상황을 건너뜀

stash

modified 상태의 작업을 임시 저장하는 명령어
브랜치에서 작업도중 다른 브랜치로 변경해야 할때, 커밋을 원하지않는경우 사용한다. (LIFO 로 작동 like stack)
stash,pop을 많이 사용한다.

stash (save) : 임시저장 (save 생략가능)
stash pop : 가장 최근 stash 사항을 적용하고 stash list에서 삭제
stash -p : 선택해서 stash
stash -m : 커밋처럼 메세지 남기기
stash list : 목록확인
stash apply : 가장 최근것을 적용하거나, 특성 순서를 지목해 적용
stash drop : 이름대로 삭제 (특정 순서를 지목해 삭제 가능)
stash clear : 누적된 stash를 전부 삭제

log

커밋 히스토리를 보여주는 명령어

log -p : 각 커밋마다 변경사항 같이보기
log -(갯수) : 원하는 n개의 커밋 보기
log --stat : 통계도 같이 보기
log --oneline : 한줄로 간략히 보기
log --oneline --graph : 그래프로 로그보기
log -S "검색어" : 변경사항 내 검색어 찾기
log -grep "검색어" : 커밋메세지내 검색어 찾기

reflog

그동안의 모든 작업내역을 확인하는 명령어
rebase, reset --hard 를 사용하면 변경내용을 되돌아갈 수 없어서 위험하지만 reflog는 작업내용을 확인할 수 있다.
원하는 시점의 커밋 넘버를 복사할 수 있고, git reset --hard"커밋넘버" 로 되돌릴 수 있다.


blame

어떤코드를 누가 작성했는지 알 수 있는 명령어

git blame 파일명 : 해당파일의 코드내역 확인
blame -L 원하는시작라인넘버,끝 '파일명' : 파일의 특정 코드라인을 확인

추가로 git summary, git lens 플러그인으로 변경내역을 자세히 볼 수 있다.

'백엔드 > Git, Github' 카테고리의 다른 글

[Github] 기초개념  (0) 2022.09.23
[Git] 기초와 명령어  (0) 2022.09.22

GIT

버전관리 시스템으로 가장 많이 사용되는것이 GIT

lifecycle - status

git에서 파일은 정해진 status에 따라 분류, 관리된다.

  1. untracked
    아직 파일은 생성되어있지만, Git에서는 상관없는 상태.
    add 전까지는 Git에서 관리할 수 없음.
    add를해서 Staged 된 파일을 제거하려면 restore --staged <파읾명> 으로 untracked 상태로 전활 할 수 있음.
  2. unmodified
    코드 저장이 완료된 상태. (Staged에서 commit시 Unmodified)
    status 명령상에서 눈에 보이진 않고 git으로 관리되는 파일이 잇지만 아직 변화되지 않은 상태이다.
  3. Modified
    Git 으로 관리되고있는 파일을 수정하여 변경이 일어난 상태.
    Unmodified 상태인 파일을 수정하면 Modified가 된다.
    이 상태로는 commit할 수 없으며, 변경사항을 add시켜 Staged상태로 만들어야 한다.
  4. Staged
    변경사항이 모두 git에 적용되었고 commit 가능한 상태.
    untracked, Modifed 파일을 add 하면 staged상태가 됨.
    한마디로 저장할 준비가 된 상태이다.

Commit

파일을 커밋할때 'git commit -m "메세지" ' 형태로 간단하게 커밋 메세지를 작성할 수 있지만, 정해진 커밋컨벤션을 활용하면 체계적으로 관리할 수 있다. (컨벤션은 회사에따라 다를 수 있다)

  1. 제목열
    맨 윗부분인 제목열에는 작업의 종류를 적는다.
  • feature : 기능의 생성작업
  • refactor: 리팩토링
  • bugfix: 버그픽스
  • env: 환경설정 변경
  • remove: 제거
  • 등등 이외의 정해진 네이밍
  1. 본문
    보통 전체 요약을 72자 이내로 정리하고, 추가적인 세부사항은 리스트형태로 나열하여 기록한다. 무엇을 왜 변경하였는지 설명하는것이 best.
  2. 꼬리말(footer)
    잘 사용하진 않지만 Githun Issue ID를 적음으로써 이슈트랙킹을 할 수 있다.

Git log

커밋 히스토리를 조회하는 명령어
커밋 단위로 히스토리가 쌓이고 브랜치를 병합할때 머지방향과 순서를 이해하기위해 반드시 로그를 읽을 줄 알아야 한다. 최신정보가 상단에 위치한다.
로그에서 나갈땐 'q'를 입력한다.
tig 를 사용하는것도 찾아보면 좋다.

reset

상태를 이전커밋으로 리셋하는 명렁어
옵션에 따라 이전 어느단계까지 리셋할지 (Staged, Modified, Unmodified) 까지 정할 수 있다.

  • --soft : 커밋 명령만 되돌려 staged상태로 리셋 (HEAD만 해당 커밋으로 돌림)
  • --mixed : 커밋과 add 를 되돌려 Modified상태로 리셋
  • --hard : 커밋,add,워킹 디렉토리까지 모두 리셋하여 Unmodified상태로 리셋

show

Git에서 커밋 정보를 보여주는 명령어
Git에는 시점을 가리키는 단축 기호가 있다. 현재시점을 나타내는 HEAD,@ 와 이전시점을 나타내는 ~,^ 를 이용하여 정보를 확인할 수 있다.
'HEAD~, HEAD^, @~, @^ ' 모두 바로 한 커밋이전을 뜻한다.

revert

되돌릴 커밋을 찾아 명령어 뒤에 hash 값을 전달하는 명령어( Git revert "hash" )
Revert 커밋이 기록되며 --no-commit 옵션으로 커밋 직전상태에서 추가작업을 진행하고 커밋할 수 있다.
Reset은 HEAD를 바꿔 시점을 이동하지만, revert는 되돌리려는 커밋에대해 revert하는 커밋을 남기고 제외시킨다는 차이가 있으며 주로 배포되어 공유된 커밋을 되돌릴때 사용한다.

branch

브랜치는 메인코드에서 뻗어나온 가지를 의미하며 특정 시점에 여러개의 브랜치를 만들 수 있다.

-m : 브랜치 이름변경
-d : 브랜치를 삭제하지만, 만약 커밋 내역이 존재하고 원격저장소에 머지되지않으면 실패
-D : 커밋 머지와 상관없이 강제 삭제
-v : 브랜치의 상세정보 확인
--merged : 현재 브랜치기준 이미 머지한 브랜치 목록 확인
--no-merged : 머지하지 않은 브랜치를 확인
- checkout "브랜치명" : 브랜치 이동
- checkout-b "브랜치명" : 브랜치를 생성하고 이동
- switch "브랜치명" : 브랜치를 이동(checkout이 역할이 많아 혼동을 피하기위해 사용)
- switch-c "브랭치명" : 브랜치를 생성하고 이동

merge

브랜치간 병합하는 명령어
병합하려는 브랜치의 commit을 모두 마쳤다면 기준 브랜치로 이동가능.
기준 브랜치에서 git merge <대상브랜치> 로 사용한다.

단, 브랜치를 병합하는 과정에서 conflict 가 생길 수 있다.
파일의 같은위치에 다른내용을 입력할 경우 발생하며 병합 전 파일을 잘 확인해야 한다.

push

로컬에서 진행한 작업을 원격 저장소로 업로드하는 명령어
저장할 원격 저장소에 쓰기 권한이 있어야 하며, 같은 브랜치로 여러명이 작업하는 경우 누군가 push 했다면 이후 작업자는 push 불가능.
다른 사람이 push한 내용을 가져와 merge 한 후에 변경하여 다시 push 해야한다.

git push origin main : 일반적인 push 커맨드

--force(-f) 옵션을 push 뒤에 붙이면 강제로 push 가능
로컬 브랜치에 내용을 덮어씌우기 때문에 main 브랜치에 적용시 치명적일 수 있음
만약 한사람이라도 main의 원본파일을 가지고있다면 force push로 다시 복구!

pull, fetch

pull 로 원격저장소의 데이터를 가져오고, 대상 브랜치에 자동으로 merge 가능.
fetch 는 원격저장소에서 데이터를 가져오지만, merge는 하지 않음( 원격 저장소의 변경내역을 확인할 때 사용)

'백엔드 > Git, Github' 카테고리의 다른 글

[Github] 기초개념  (0) 2022.09.23
[Git] branch merge 방법  (1) 2022.09.22

+ Recent posts