22.03.31 TIL

Branch

  • 분기점을 생성하여 독립적으로 코드를 변경할 수 있도록 도와주는 모델

ex) <master> =>메인 branch

print('hello' + ' ' + 'world')

<develop> =>서브 branch

words = ['world' , 'hello']
print(' '.join(words[:-1])) 
* 추가적으로 알게 된 내용 : python에서 음수 인덱스는 거꾸로(오->왼)를 의미!
즉, -1은 'hello'를 나타냄

Branch 명령어

$ git branch : local쪽 branch 보여줌
$ git branch -r : remote쪽 branch 보여줌
$ git branch -a : 양쪽 다 보여줌
$ git branch [branch명] : 새로운 branch 생성
$ git shift(checkout) [branch명] : 해당 branch로 이동
$ git checkout -b [branch명] : 새로운 branch만들고 이동
$ git branch -d [branch명] : 해당 branch 삭제
$ git merge [branch명] : 현재 위치한 branch에서 해당 branch를 합병하는 (끌어오는) 것
$ git push [origin] [branch명] : 작업한 branch에서 remote저장소로 push하는 것

cf) origin은 remote쪽 저장소 별명이라 언제든 바꿀 수 있음.

$ git diff [master] [branch명] : 두 branch 사이에서의 변화(차이)를 알려줌

Branch 작업 예시

  • commit을 먼저 해주고 branch를 생성하면 최신 commit을 기준으로 branch(분기점)가 생성되는 것!
  • branch 이름은 해당 branch에서 어떤 행동을 할 것인지 명시적으로 알 수 있게 지어줘야함.

    ex) - branch.py를 만들어 commit한 뒤에, hello 브랜치를 생성한다.

    # 변경 전
    $ git branch 
    * main
    $ git branch hello 
    # hello라는 branch를 만듬
    $ git branch
    hello
    * main
    $ git switch hello 
    Switched to branch 'hello'
    # branch를 바꿔주는 키 (switch) => hello branch로 이동

    - hello 브랜치 위에서 branch.py를 vim으로 작업한 후 commit한다면 main 브랜치에는 영향이 없다! ( $ cat branch.py로 확인 가능)
    - $ git merge [branch명]을 통해 병합해준다.

    - Merge할 때 주의!!
    : hello 브랜치에서 작업한 내용을 가져오기 위해서는 main브랜치에서 merge해야한다.

    82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
    $ git branch 
    hello
    * main
    	# 브랜치 현 위치
     82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
    $ git merge hello
    Updating a9cf26b..66fdd24
    Fast-forward
    branch.py | 1 +
    1 file changed, 1 insertion(+)
    	# hello 브랜치 내용을 main 브랜치로 가져오는 것(땡겨오는 것).
    82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
    $ cat branch.py 
    print 'hello'
    	# merge전까지는 내용이 없었지만 합병하고 cat해보면 내용이 뜨는 것을 확인 할 수 있다!
  • 정리 : commit -> 새로운 branch 생성 -> vim 작업 -> commit(새로 만든 branch에만 내용 저장됨) -> main branch로 나와서 merge(새로운 branch에서 한 작업 끌어오기)

Branch 지우기

  1. 생명을 다했을 때
  2. 실패 했을 때
    => 쌓아두면 헷갈릴 수 있기 때문에, 바로바로 지우는 게 좋음!
  • 서브 branch에서 실험적 개발을 할 수 있고 만약 실패한다면, 그 branch만 지우면 된다.
    만약 성공한다면 메인 branch에서 서브 branch내용을 가져와서 merge하면 된다.
    ex) 서브 branch인 hello 삭제
82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
$ git branch -D hello
Deleted branch hello (was 66fdd24).

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
$ git branch
* main

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
$ cat branch.py 
print 'hello'
# hello 브랜치에서의 내용은 이미 병합했기 때문에 main에도 반영되어있음.

branch 충돌

ex) 시나리오
: repeat-hello라는 서브 브랜치 만들기 -> main 브랜치에서 branch.py에 조건문(if문) 추가 -> (add, commit) -> repeat-hello 브랜치에서 branch.py에 반복문(for문) 추가-> (add, commit) -> main 브랜치에서 repeat-hello 브랜치를 merge -> 충돌! merge conflict 발생 -> 충돌 내용 수정 -> (add, commit) -> push해서 github에서 확인

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main)
$ git merge repeat-hello 
# 충돌 발생!
Auto-merging branch.py
CONFLICT (content): Merge conflict in branch.py
Automatic merge failed; fix conflicts and then commit the result.

* 위의 내용처럼 충돌 부분을 수정해준다.

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/second-repo (main|MERGING)
$ git status
On branch main
Your branch is ahead of 'mask/main' by 4 commits.
  (use "git push" to publish your local commits)
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)
Unmerged paths: 
# 아직 완벽히 merge되지않았음! add, commit해줘야함!
  (use "git add <file>..." to mark resolution)
        both modified:   branch.py
no changes added to commit (use "git add" and/or "git commit -a")
  • 주의할 점 : $ git commit -m 으로 바로 커밋 입력 시, 이미 제목이 있는 경우 덮여쓰여지기 때문에 주의해야함!
  • Q. github에서는 repeat-hello branch가 없는게 맞나요?
    A. 그렇다. main에서 푸쉬하고 repeat-hello는 하지 않았기 때문!

실무적 branching models

# git flow(중요)

  • (hotfix)- master -(release)- develop - feature
    - pros: 가장 많이 적용, 각 단계가 명확히 구분
    - cons: 복잡
  • masterdevelop이라는 큰 두 branch를 두는 시스템.
    ( hotfix : 치명적인 결함이 있을 때 작업해서 바로 master에 적용
    develop : 큰 결함 아니면 feature에서 작업한 뒤 develop에 담아두는 것.
    release : 그러다가 어느정도 주기가 되면 release에 넣고 master에 올리는 것.)

    ★TIP = git flow cheatsheet

# github flow

  • master - feature
    - pros: 브랜치 모델 단순화, master 의 모든 커밋은 deployable
    - cons: CI 의존성 높음. (pull request로 실수 방지)
  • main 브렌치가 master이고, feature브랜치에서 수정해서 빠르게 main에 적용)

# gitlab flow

  • production - pre-production - master - feature
    - pros: deploy, issue에 대한 대응이 가능하도록 보완
    - cons: git flow와 반대 ( master -develop, production -master)

# git flow 연습

최우영 강사님의 git flow 설명 영상

  1. github에서 repo만들고 dev에 clone한 뒤, 폴더 들어가기
  2. $ git flow init 입력 후 branch 이름들 저장(기본값 권장)
=> 여기서 $ git branch해보면 develop 브랜치가 생성되고 전환되는 것 확인 가능!
  1. 새 기능 시작하기 : $ git flow feature start [기능이름]
ex) $ git flow feature fizzbuzz입력
=> 그러면 develop에 기반한 새 기능 'feature/fizzbuzz 브랜치'가 생성되고 전환됨.
  1. 이제 작업 시작하면 됨!
ex) $ touch fizzbuzz.py로 작업 파일 만들고 vi로 수정 후 add commit (-> 같은 방식으로 두-세번 수정하고 add commit 반복)
  1. 개발이 끝난 경우 : $ git flow feature finish [기능이름]
    • 주의 !! : 작업 마무리할 때 commit되지 않은 파일이 없도록 하기!
82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (feature/fizzbuzz)
$ git flow feature finish fizzbuzz 
# 기능 개발 완료할 때 finish해주기! (merge커밋은 그냥 저장하고 나가기)
Switched to branch 'develop'
Merge made by the 'ort' strategy.
fizzbuzz.py | 7 +++++++
1 file changed, 7 insertions(+)
create mode 100644 fizzbuzz.py
Deleted branch feature/fizzbuzz (was d945d40).
Summary of actions: 
# feature branch가 develop에 merge되고 local에서는 사라졌다는 뜻!
-The feature branch 'feature/fizzbuzz' was merged into 'develop'
-Feature branch 'feature/fizzbuzz' has been locally deleted
-You are now on branch 'develop'

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (develop)
$ git branch
* develop
main
# feature/fizzbuzz 브랜치가 사라진 걸 확인할 수 있음!
  1. 릴리즈(release) 시작하기 : $ git flow release start [버전이름]
82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (develop)
$ git flow release start v0.0.1
=> 그러면 develop에 기반한 release/[버전명] 브랜치가 생성되고 전환됨.
  • release branch에서 하는 일 : 사용자에게 배포할 준비, 큰 단위의 테스트 등 많은 테스트들이 일어난다!
  • [버전명] : 영향력에 따라!!
    • 보통 세 자리로 정함 (예시 : v0.0.1)
      : 중요한 큰 단위(ex. 캐릭터 추가,삭제) / 약간 큰 단위(ex. class단위 바뀌는 정도, 캐릭터 매커니즘) / 사소한 변화(ex. 버그 수정, 캐릭터 수치 변경)
    => 앞에 1이 붙기 전까지는 베타 버전이다가 1이 붙으면 정식 버전이 되는 것임!
  1. 릴리즈(release) 마치기 : $ git flow release finish [버전이름]
82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (release/v0.0.1)
$ git flow release finish v0.0.1 
# 작업 했다고 생각하고 닫음.
  • 이어서 3개의 vi창이 뜨게 된다.

    1) main에 들어갈 merge커밋 : release/[버전명] 브랜치를 main 브랜치에 병합 (그냥 저장 ok)
    2) 해당 커밋의 라벨링(=release note) : 해당 버전에서 어떤 일이 일어났는지 설명하는 것 (내용 추가해주기!!)
    3) 똑같은 버전을 develop에 재병합시키는 merge커밋 : (그냥 저장 ok)

  • 모두 commit 하고 나면 release 브랜치는 삭제된다.
  1. develop과 main 브랜치 둘다에 push 해주기

    BUT! develop은 로컬에서 처음 생긴 branch이기 때문에 github에 없다.
    따라서 첫 push라면 -u(upstream set)을 해줘야한다! (이것은 프로젝트 당 처음에 한번만 해주면 됨.)

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (develop)
$ git remote
origin

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (develop)
$ git push -u origin develop 
# develop에서 remote저장소(origin)로 첫 push해주기

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (develop)
$ git switch main 
# main으로 이동해서도 push해주기
Switched to branch 'main'
Your branch is ahead of 'origin/main' by 5 commits.
(use "git push" to publish your local commits)

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (main)
$ git push origin main
  1. $ git push --tags를 사용해 tag들도 push하는 것을 잊지말 것!!!
82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (main)
$ git tag
v0.0.1
# release마쳤을 때 main에 병합된 커밋에 대한 tag임.

82103@LAPTOP-NBT556I5 MINGW64 ~/Documents/dev/git-flow-practice (main)
$ git push --tags 
# tag는 특정한 commit에 종속되는 것임!

좋은 웹페이지 즐겨찾기