[교육] Git & GitHub 중급
규칙
Look
슬라이드 내용에 집중합니다.
D.I.Y
직접 실습합니다.
Git Rebase
Merge [Look]
- experiment를 master로 merge
- C3, C4를 조상으로 하는 새로운 Merge 커밋 C5 생성
Rebase [Look]
- feature를 master에 rebase한다란
- feature의 master에 대한 base(feature와 master의 공통 조상)를 master로 변경(rebase)
Rebase 과정 [Look]
- base에서 현재 브랜치까지의 변경 사항을 구한다.
- head를 master로 변경
- 변경사항 1을 적용하여 새로운 커밋 C4'를 생성
- 변경사항 2를 적용하여 새로운 커밋 C5'를 생성
- feature가 C5'를 가리키도록 함
- C4와 C5는 git 저장소 내에는 존재하나 찾아 갈 수 있는 포인터가 없는 상태(dangling)
- 여기까지가 rebase
- rebase된 feature를 master로 fast-foward하지 않고 merge
- rebase를 이용한 브랜치 합치기 완료
SourceTree를 이용한 rebase [Look]
- 연습을 위한 로컬 저장소 생성
- 적당한 위치에 생성
- master와 feature 브랜치가 갈라지도록 커밋을 생성
- master에서 최초 커밋을 생성
- feature 브랜치 생성
- feature에서 커밋을 두개 생성
- master에서 커밋을 하나 생성
- feature로 체크아웃
- feature를 master에 rebase
- feature에 체크아웃된 상태에서 master의 컨텍스트 메뉴에서 master로 현재 바뀐 내용 재배치(현재 변경사항을 master에 재배치) 선택
- 484f73a가 base 였던 0e28385, 7b3d74d 커밋이 master 브랜치가 가리키는 b739862 커밋 이후로 새로운 커밋 7e9463, b12731a를 생성하며 rebase
- master로 체크아웃한 후 feature를 merge
- rebase를 통행 feature를 master에 반영하며 커밋 그래프가 일렬이 된 모습
SourceTree를 이용한 rebase [DIY]
- 로컬 저장소를 생성하세요
- master와 feature 브랜치가 갈라지도록 커밋을 생성하세요
- feature를 master에 rebase하세요
- master에 feature를 merge하세요
대화형 rebase [Look]
- 커밋을 합치고, 없애고, 순서를 바꿀 수 있다!
- 커밋 메시지를 바꾸고 중간 커밋의 내용을 바꿀 수 있다!
커밋 합치기 [Look]
- 변경사항 1과 변경사항 2를 동시에 적용하여 C2/3를 생성
- C2와 C3을 하나로 합치는 효과
SourceTree를 이용한 커밋 합치기 [Look]
- 연습을 위해 master에 커밋을 적당히 생성
- feature 브랜치를 삭제
- 7ec9463, b12731a를 하나로 합치기
- base로 사용할 b739862의 컨텍스트 메뉴에서 'b739862' 하위 요소 대화식 재배치...(자식 커밋을 쌍방향 재배치...) 선택
- 합치려는 커밋 중 제일 마지막 커밋을 선택하고 이전 것과 합치기(이전 커밋과 합치기)를 클릭
- 커밋 두개가 하나로 합쳐지는 것 확인
- 더블클릭하여 커밋 메시지를 다시 작성 가능
- 변경사항을 확인하고 확인 클릭
- 7ec9463, b12731a가 하나로 합쳐져 d3da71e가 되었고 이후 커밋은 부모가 달라졌기 때문에 새로운 해시로 생성
- 예제는 두개의 커밋을 합쳤지만 세개 이상도 합칠 수 있습니다
- 그래프가 한줄로 안 보이는 경우는 feature 브랜치를 삭제하지 않아서 이전 커밋에 도달할 수 있기 때문
- 어쨌든 master만 봤을 경우 두개의 커밋이 하나로 합쳐진 결과는 다름이 없습니다
SourceTree를 이용한 커밋 합치기 [DIY]
- 대화형 rebase 기능을 이용하여 두개의 커밋을 하나로 합쳐보세요
커밋 없애기 [Look]
- base인 C1을 head가 가리키고 변경사항 1을 적용
- 적용 결과가 이전과 다르지 않기 때문에 git에서는 새로운 C2' 커밋을 생성하지 않고 C2를 그대로 사용
- 변경사항 2를 생략하고 적용
- C3을 없애는 효과
SourceTree를 이용한 커밋 없애기 [Look]
- d3da71e를 없애기 위해 b739862에서 대화형 rebase 진입
- 커밋을 선택하고 삭제 클릭
- 삭제되는 것을 확인하고 확인 클릭
- d3da71e가 삭제되고 이후 커밋들은 새로운 해시로 생성
SourceTree를 이용한 커밋 없애기 [DIY]
- SourceTree를 이용하여 이전 커밋 중 하나를 없애보세요
커밋 순서 바꾸기 [Look]
- 변경사항을 2, 1, 3 순서로 적용
- C2, C3의 순서를 바꾼 효과
SourceTree를 이용한 커밋 순서 바꾸기 [Look]
- 22efded와 7dbcc81의 순서를 바꾸기 위해 b739862에서 대화형 rebase 진입
- 커밋을 선택한 후 방향 버튼 클릭
- 순서가 변경된 것 확인한 후 확인 클릭
- 커밋의 순서가 변경되고 새로운 해시로 생성된 것 확인
SourceTree를 이용한 커밋 순서 바꾸기 [DIY]
- SourceTree를 이용하여 커밋의 순서를 바꿔보세요
커밋 메시지 바꾸기 [Look]
- 변경사항 2를 적용하며 커밋메시지를 변경
SourceTree를 이용한 커밋 메시지 바꾸기 [Look]
- 대화형 rebase 진입
- 변경하고자하는 커밋에서 더블클릭한 후 메시지 편집
- 커밋 메시지가 변경된 것 확인
- 그리고 당연히 커밋도 새로운 해시 값으로 생성 됨
- 아쉽게도 Windows 버전은 rebase에서 커밋 메시지를 변경하면 한글이 ?로 나오는 버그가 존재...
- 만약 마지막 커밋만 다시 고치고 싶다면 SourceTree의 커밋 창에서 커밋 옵션의 마지막 커밋 수정을 선택하면 됩니다.
- 커밋 메시지를 고치면 당연히 새로운 해시 값의 커밋이 생성됩니다
SourceTree를 이용한 커밋 메시지 바꾸기 [Look]
- SourceTree를 이용하여 커밋 메시지를 변경해 보세요.
중간 커밋의 내용 바꾸기 [Look]
- C3을 amend 하겠다고 표시후 rebase 시작
- 변경사항 1을 적용한 후 rebase를 잠시 멈춤
- 사용자가 추가로 수정한 후 커밋
- git rebase --continue 명령을 통해 rebase를 계속 진행하여 마무리
- 예제는 이전 커밋의 내용을 기반으로 변경하는 예이지만 커밋을 두번 한다든지 rebase가 멈춘 후 다시 진행하기 전까지 자유롭게 변경하면 됩니다
SourceTree를 이용한 중간 커밋의 내용 바꾸기 [Look]
- 빈 f 파일만 추가된 4783491 커밋의 내용을 바꿔 봅니다
- b739862에서 대화형 rebase에 진입
- 내용을 바꾸고자 하는 커밋에 체크한후 확인 클릭
- rebase가 변경하고자하는 커밋에서 일시정지된 것 확인
- 빈 파일 f에 내용을 추가하고
- 새로운 파일을 하나 추가
- stage에 올리고
- 커밋 창에서 마지막 커밋 수정
- 커밋
- 4783491을 amend한 새로운 커밋 9762ff1이 생성 됨
- rebase를 계속하면 9762ff1에 4783491에서 022b601 사이의 변경사항을 적용하여 새로운 커밋이 생성 됨
- 재배치 계속을 선택
- 여섯번째 커밋의 내용을 변경하여 새롭게 히스토리가 구성된 모습
SourceTree를 이용한 중간 커밋의 내용 바꾸기 [DIY]
- 커밋 히스토리 중간의 커밋의 내용을 바꿔보세요
rebase 중 충돌해결 [Look]
- 빈 conflict 파일을 추가하고 conflict 브랜치를 만듦
- master에서 파일 내용을 작성
- conflict에서 파일 내용을 작성
- 이제 conflict를 master에 rebase
- 충돌이 발생
- rebase 중 충돌 발생 시 HEAD는 내 코드가 아닌 상대방 코드, 아래 쪽이 내 코드가 됨
- conflict에 master를 merge할 때의 충돌과는 정반대
- base에서 현재 브랜치까지의 변경 사항을 구한다.
- head를 master로 변경
- rebase 과정 중 rebase 하려는 기준이 되는 브랜치로 head가 이동하기 때문
- 충돌을 해결한 후 stage로 올림
- rebase를 계속 진행
- rebase 완료
rebase 중 충돌해결 [DIY]
- master에서 빈 파일 conflict를 만드세요
- master에서 파일 내용을 추가하세요
- conflict에서 파일 내용을 추가하세요
- conflict를 master에 rebase하세요
- 충돌을 해결한 후 rebase를 완료하세요
rebase 중 충돌은 계속... 계속..?! [Look]
- master에 conflict를 merge
- master에서 두번째 줄 추가
- conflict에서 두번째 줄 추가
- conflict에서 한번 더 수정
- conflict를 master에 rebase
- 첫번째 변경사항을 적용하며 충돌이 발생
- 충돌을 해결하고 rebase 계속 진행
- 두번째 변경사항을 적용하며 또 충돌이 발생
- Tip: 미리 C4, C5를 하나로 합친 후에 rebase 한다면 충돌 해결은 한번만 하면 되겠죠
rebase를 사용하는 이유 [Look]
- 동시에 여러 feature가 진행되고 merge될 경우
- 여러 갈래의 merge들로 인해 히스토리 파악이 어려움
- rebase로 feature들을 차례대로 merge(no-ff)한 것과 같이 하거나 (특정 feature의 범위를 한 눈에 파악 용이)
- master를 일렬로 유지
- 히스토리 파악 쉬움
GitHub-flow에 rebase를 접목 [Look]
- GitHub에 저장소를 하나 생성
- 이때, README 초기화는 사용하지 않습니다.
- 저장소 주소를 복사
- 저장소 설정으로 진입
- 원격 탭의 추가 클릭
- 원격 이름은 origin, 저장소 주소를 붙여넣기
- origin에 master를 push
- feature1, feature2 브랜치를 만들어서 각각 커밋을 생성 후 push
- feature1, feature2를 master에 merge하는 PR를 각각 생성
- feature1을 master에 merge
- SourceTree에서 master를 pull 받아 최신 상태를 적용
- feature2를 master에 rebase
- origin/feature2는 여전히 이전 커밋을 가리키는 것을 확인
- origin/feature2의 입장에서 가지고 있지 않은 커밋 a2d2d8f, 1d903a9, b6c057d 때문에 3개 앞서 있다고 표시
- feature2 입장에서 가지고 있지 않은 커밋 57c85ed 때문에 1개 뒤처져 있다고 표시
- 여기서 다시 pull을 받고 push를 하면 rebase 의미가 없습니다
- rebase한 feature2를 다시 push해야 합니다
- push를 하려고 하면 오류가 발생하며 실패
- push가 reject 되었습니다
- 왜냐하면 우리가 push하려는 feature2의 어떤 조상도 origin/feaure2가 아니기 때문입니다
- 쉽게 말해서 feature2의 줄기가 origin/feature2로 부터 나오지 않았기 때문입니다
- force push 기능을 이용하여 강제로 push하여야 합니다
- 설정으로 진입
- 강제 푸시를 허용 체크
- 강제 푸시 옵션을 체크한 후 다시 push
- 경고 확인
- force push 후 merge
- feature 들이 차례대로 merge 된 모습
- PR을 생성 후 코드 리뷰를 진행할 동안 다른 feature 들이 먼저 merge 될 수 있습니다
- feature의 merge가 결정되면 먼저 rebase가 필요한지 확인한 후에 필요하다면 rebase 먼저 한 후에 merge를 합니다
GitHub-flow에 rebase를 접목 [DIY]
- 실습하던 로컬 저장소를 GitHub 저장소로 push하세요
- master에서 feature1, feature2 브랜치를 생성해 각각 커밋을 생성하세요
- feature1, feature2를 push하여 각각 PR을 생성하세요
- feature1을 먼저 merge하세요
- feature2는 rebase를 한 후 force push한 후 merge하세요
모두가 함께 사용하는 브랜치를 rebase하면? [Look]
- 팀원1과 팀원2가 feature 브랜치에서 함께 작업하고 있다면
- 팀원1은 feature를 master에 rebase 했고
- 팀원2는 feature에 새로운 커밋을 생성
- 팀원1이 feature는 force push 하면
- 팀원2가 fetch를 받았을 때 feature에 받을 것 3개 올릴 것 3개로 표시
- 팀원2가 feature를 pull을 받으면
- feature의 히스토리에 C2', C3'의 본래 커밋인 C2, C3까지 포함이 됨
- 결과적으로 동일한 변경 내용을 갖는 커밋이 중복으로 히스토리에 존재하게 됨
- 이 경우 혼란을 야기
- 팀원2가 push를 하면 팀원2뿐 아니라 다른 사람들까지 혼란에 빠지게 됨
- 만약 모두가 함께 사용하는 브랜치를 rebase 했다면 다른 사람들은 pull 대신 rebase 사용하기(git pull --rebase)를 통해 pull을 받으면 됨
- pull 대신 rebase 적용 시 C3' 뒤에 다시 C2, C3가 생기지 않음
- 변경사항 을 적용할 때 해당 변경사항이 이미 반영되어 있는지 확인 후 반영되어 있다면 제외
- push를 하기 전 rebase는 다른 사람에게 영향을 주지 않습니다
- push를 했더라도 해당 브랜치가 나 혼자 사용하는 브랜치라면 주의를 하면 됩니다
- 여러 명이 함께 사용하는 브랜치를 rebase 한다면 많은 혼란을 가져올 수 있습니다
- 하지만 히스토리를 다시 쓴다는 특성과 force push를 사용하는 특성 상 히스토리를 읽어 버릴 수 있는 가능성이 있으므로 항상 주의하여 사용하여야 합니다
GitHub/Jenkins 연동을 통한 pre merge test
GitHub Pull Request Builder 플러그인 설치 [Look]
- Jenkins 관리
- 플러그인 관리
- 설치 가능 탭에서 github pull로 필터링 후 GitHub Pull Request Builder를 체크
- 지금 다운로드하고 재시작 후 설치하기
- GitHub Pull Request Builder 를 설치
GitHub 접근용 비밀번호 생성 [Look]
- Jenkins에서 GitHub 저장소로 접근할 수 있도록 일회용 비밀번호를 생성해야 합니다.
- GitHub에서 오른쪽 상단 Settings 클릭
- 왼쪽 하단 Personal access tokens 클릭
- 오른쪽 상단 Generate new token 클릭
- Token description에 나중에 참고할 수 있는 설명을 적음
- 권한은 repo에 체크 후 create token 클릭
- 생성된 비밀번호는 지금 한번만 볼 수 있기 때문에 복사한 후 다른 곳에 잘 보관
- Jenkins 관리 - 시스템 설정의 GitHub Pull Request Builder에서
- Credentails의 Add 클릭
- 사내 GitHub를 사용하고 있을 경우 API URL에 https://github.nhnent.com/api/v3를 입력
- Username은 git, 비밀번호는 아까 복사한 값을 붙여넣고 Add 클릭
- Description에 나중에 알아 볼 수 있도록 설명을 적고 저장
- github.com과 사내 GitHub를 동시에 사용하고 있을 경우 추가 버튼을 눌러고 각각의 접근 정보를 추가하면 됩니다
Jenkins Job 생성 [Look]
- 새로운 Job을 하나 생성하고 구성을 시작
- General의 GitHub project에 GitHub 저장소 페이지 주소
- 소스 코드 관리의 Git에 체크
- Repository URL은 저장소의 git 주소
- Credentials에 아까 생성한 권한으로 선택
- 고급을 누른 후 Refspec에 +refs/pull/*:refs/remotes/origin/pr/* 입력
- Branch Specifier에 ${sha1} 입력
- 빌드 유발의 GitHub Pull Request Builder 체크
- GitHub API credentials에 아까 생성한 credentails 선택
- Admin list에 저장소 멤버 중 관리자로 지정할 아이디를 한줄 씩 작성
- 여기 작성한 아이디가 테스트 결과, 댓글 등을 입력한 것과 같이 동작
- Use github hooks for build triggering에 체크
- GitHub 쪽 변경사항을 polling 뿐 아니라 hook을 통해서 받을 수 있도록 하는 설정이며 좀더 빠르게 반응하도록 합니다
- github.com <-> 사내 jenkins 조합의 경우 github.com에서 내부 jenkins에 hook을 발송할 수 없기 때문에 polling으로만 구성해야 합니다
- Crontab line을 변경하여 polling 스케쥴 설정 가능합니다
- Build에 test를 위한 빌드 세팅을 하고 구성 저장
- jenkins에서 구성을 저장하면 GitHub 저장소의 Settings - Webhooks에 자동으로 훅 설정이 됨
- GHPRB 플러그인의 hook 주소는 http://젠킨스 주소/ghprbhook/
PR 생성 [Look]
- 전달 받은 int 두개를 더하는 메소드를 일부러 고장내는 PR를 생성
- PR 생성 후 얼마 지나지 않아 check가 있다고 표시 됨
- 일부러 테스트를 통과할 수 없게 만들었기 때문에 check가 실패
GHPRB 자세한 설정 [Look]
- GitHub Pull Request Builder는 기본적으로
- 저장소 관리자가 PR를 생성한 경우: 자동으로 빌드
- 그외 사용자가 PR을 생성한 경우: 관리자의 승인이 있으면 빌드
- 관리자가 아닌 사용자가 PR를 생성했을 때 GHPRB 플러그인은 관리자의 승인을 묻는 댓글을 생성
- 관리자 중 한명이 ok to test라고 댓글을 남기면 빌드
- 모든 PR을 자동으로 빌드하려면
- Build every pull request automatically without asking (Dangerous!).에 체크
- PR에 새로운 커밋이 올라오면 무조건 자동으로 빌드
- Build every pull request automatically without asking (Dangerous!).에 체크
- 모든 PR을 자동으로 빌드하지 않으려면
- Only use trigger phrase for build triggering에 체크
- Trigger phrase에 빌드 유발 텍스트 설정
GitHub Protected branches [Look]
- 특정 브랜치에 강제 push/삭제 차단, 머지 전 check 통과 등을 강제할 수 있는 기능
- GitHub 저장소 페이지 - Settings - Branches
- Protected branches에서 보호할 브랜치 선택
- Protect this branch
- 보호 기능을 활성화
- Require pull request reviews before merging
- 머지 전 PR에 대한 승인이 필요
- Dismiss stale pull request approvals when new commits are pushed
- 승인 후 새로운 커밋이 추가되었을 경우 이전 승인을 무시
- Require review from Code Owners
- 지정된 코드 오너의 승인이 필요
- Require status checks to pass before merging
- 머지 전 체크 통과가 필요
- require branches to be up to date before merging
- PR 테스트가 반드시 보호된 브랜치의 최신 상태를 포함하고 있어야 함
- Status checks found in the last week for this repository
- 지난 일주일간 이 저장소의 check를 찾아 표시
- 체크하면 반드시 해당 check를 통과해야 함
- Include administrators
- 저장소 관리자까지 포함
- CODEOWNERS 파일
- gitignore의 패턴 규칙과 동일
- 개인은 물론 팀도 지정 가능
# 이것은 주석입니다. # 각 줄에 파일 패턴과 오너를 하나 이상 적습니다. # 이 오너들은 저장소의 모든 파일에 대한 기본 오너입니다. # 나중에 적힌 것들이 매칭되지 않는 한 @global-owner1과 @global-owner2는 # 누군가 PR을 열었을 때 리뷰 요청을 받게 됩니다. * @global-owner1 @global-owner2 # 순서가 중요합니다. 나중에 매칭된 것이 가장 우선순위가 높습니다. # 누군가 JS 파일만 변경한 PR을 오픈할 경우 글로벌 오너가 아닌 @js-owner만 리뷰를 요청 받게 됩니다. *.js @js-owner # 만약 원한다면 이메일 주소를 사용할 수도 있습니다. github 사용자 계정에 등록된 이메일이어야 합니다. docs/* docs@example.com
- Review required
- 이 PR이 승인 되지 않았아 머지가 불가능
- All checks have failed
- 이 PR의 테스트가 실패하여 머지가 불가능
- This branch is out-of-date with the base branch
- base 브랜치의 최신 내용이 반영되어 있지 않기 때문에 머지가 불가능
- Comment
- 승인은 하지 않고 의견을 남김
- Approve
- 승인을 하며 의견을 남김
- Request changes
- 반드시 의견에 대하여 변경을 해야 함
여러가지 Git workflow 들
Gitflow [Look]
메인 브랜치
- 항상 존재하는 브랜치
master
- 배포된 소스가 있는 브랜치
develop
- 다음 배포를 위한 소스가 있는 브랜치
- 개발이 완료되면 일련의 과정을 통해 master로 merge
서포팅 브랜치
- master와 develop 외에 팀 멤버들이 병렬로 일할 수 있도록 도와주는 브랜치
- 메인 브랜치와는 다르게 필요할 때마다 생성하였다가 삭제
feature 브랜치
- 브랜치 생성: develop으로 부터
- merge: develop으로
- prefix: feature/
- feature 브랜치는 특정 기능 하나에 대하여 develop으로부터 생성하여 개발하며 개발이 완료되면 다시 develop 브랜치로 merge
release 브랜치
- 브랜치 생성: develop으로 부터
- merge: master와 develop으로
- prefix: release/
- release 브랜치는 배포를 위한 준비를 할 수 있는 브랜치
- 각종 메타 데이터(버전 명 등)를 변경하거나 작은 버그를 수정
- 배포 준비가 되면 master와 develop에 각각 merge
- merge된 master를 배포
- release 브랜치를 따로 가져가기 때문에 develop 브랜치에서는 바로 다음 배포를 위한 기능을 시작할 수 있습니다
hotfix 브랜치
- 브랜치 생성: master로 부터
- merge: master와 develop으로
- prefix: hotfix/
- hotfix 브랜치는 배포된 버전에 긴급한 변경 사항이 있을 때 활용
- 핫픽스가 완료되면 master와 develop에 각각 merge
- merge된 master를 배포
GitHub Flow [Look]
- Gitflow는 너무 복잡
- 대부분의 케이스에서 Gitflow 처럼 복잡한 workflow가 불필요
- master 브랜치는 항상 배포 가능한 상태여야 한다
- 새로운 기능 개발은 명확한 브랜치 이름으로 master에서 생성한다
- 토픽 브랜치의 커밋은 비번하게 push 한다
- 피드백, 도움이 필요하거나 merge할 준비가 되었다면 PR을 생성한다
- 누군가 리뷰를 하고 승인을 했다면 master에 merge한다
- master에 merge한 커밋은 즉시 배포한다
master 브랜치는 항상 배포 가능한 상태여야 한다
- GitHub Flow의 유일한 강제 사항
- master의 최신 커밋은 최대한 빠르게 배포
- 배포한 커밋에 문제가 있어 이전 커밋을 되돌려야 하는 케이스는 매우 드물다
- 문제가 있을 경우 revert 커밋을 하든지 문제를 해결한 후 merge
- master 브랜치는 배포하거나 브랜치를 만들기 위해 항상 stable해야 한다
- 모든 브랜치에 push된 내용은 자동으로 테스트 수행하며 결과를 채팅창으로 받음
명확한 브랜치 이름으로 master에서 생성한다
-
master에서 명확한 이름으로 브랜치를 만들어 작업을 시작한다
- fetch를 통해 나뿐 아니라 다른 사람들의 현재 작업 현황을 파악할 수 있다
- 당분간 현재 브랜치 작업을 중단하였을 때 다시 돌아왔을 때 이름만 보고 어떤 브랜치였는지 기억해내기 쉽다
-
GitHub의 브랜치 페이지를 통해 최근 작업 중인 브랜치와 작업 상태를 러프하게 알 수 있다
- 마치 신규 기능 목록
토픽 브랜치를 지속적으로 push
- 서버에 꾸준히 push함으로 개인 컴퓨터 문제로 인한 loss 걱정이 없다
- fetch / GitHub 브랜치 페이지를 통해 우리의 TODO들을 파악할 수 있다
언제나 PR을 생성
- 라인 단위로 코멘트 가능
- PR 자체에도 코멘트 가능
- 새로운 커밋을 push하면 반영 됨
- 이 모든 것이 타임라인으로 표시 됨
- PR이 너무 오래 열려 있어 master와 멀어졌다면 master를 merge
리뷰가 완료된 것만 merge
- master에 바로 작업하지 않고 토픽 브랜치에서만 작업하며 완료되었다고 생각했을 때 merge
- 다른 사람에게 승인을 받음. ,
- 이후에 CI를 통과한 브랜치만 merge
리뷰 후 즉시 배포
- master에 merge가 되면 내가 당장 배포하지 않더라도 몇 시간 내에 다른 사람이 merge한 커밋을 기반으로 새로운 작업을 시작하고 배포할 수 있다
- 다른 사람이 내가 잘못 개발한 내용을 배포하는 것을 원하지 않기 때문에 사람들은 토픽 브랜치가 merge 되었을 때 정말 stable한지 확인하려는 경향이 있다
- 채팅창을 통해 회사 내 누구나 배포가 가능
- hubot depoy github to production
- 6명의 다른 사람들(디자이너와 서포팅 스텝 포함)이 하루 사이에 24번 배포한 기록
GitLab Flow [Look]
- GitHub Flow는 심플하지만 배포, 환경, 릴리즈 등을 해결해주지 못 함
Production branch
- GitHub Flow는 master 브랜치의 지속적인 배포를 가정하지만 적합하지 않은 케이스도 존재
- 예> iOS 앱은 배포 시 심사 과정이 필요, 배포 시간이 제한적일 때(운영 팀이 10am ~ 4pm까지 일할 때)
- 배포가 필요할 때 master에서 production으로 merge를 하여 배포
- production에 hotfix가 필요할 경우 production에서 패치하는 것이 아니라 master에서 패치 후 master 검증 후 production에 cherrypick
- production에서만 패치 후 패치 결과가 master에는 잊어버리고 반영되지 않는 문제를 해결하기 위해
Environment branches
- production 단계 전 pre-production 환경이 존재한다면 pre-production 배포를 위해 master에서 pre-production으로 merge
- 리얼 배포를 위해서는 pre-production에서 production으로 merge
Release branches
- 마이너 버전 릴리즈 브랜치가 존재
- 릴리즈 브랜치는 stable한 master에서 시작
- 릴리즈 브랜치를 생성하는 때는 최대한 늦게 가져가 각각의 브랜치에 버그를 픽스 해야 하는 상황을 최소화
- 릴리즈가 공개된 후에는 치명적인 버그만 픽스
- 가능하다면 버그 픽스는 master에서 진행 후 각 브랜치로 cherry-pick
- master에 반영하는 것을 잊어 이후 릴리즈에서 버그가 다시 나타나는 것을 방지
- 패치 버전은 새 태그를 사용하여 표시
NHN Edu 서버개발팀은? [Look]
- 단기간의 배포 일정
- 6/28, 7/18, 7/26
- 장기간의 배포 일정
- 코드 네임을 부여
- strewberry, tomato
- 같은 시간에 여러 배포 일정의 작업이 필요
- Gitflow 기반으로 develop 역할의 브랜치를 여러개 사용
- rebase 적극 활용
- 모든 배포 일정 브랜치는 develop에서 시작
- 각 브랜치 내에서 feature 브랜치 생성, merge
- PR를 통해 자동 테스트
- merge 전 rebase를 이용
- 다가오는 배포 일정의 개발이 완료되면 해당 브랜치를 이용하여 QA 진행
- QA 완료 후 master와 develop에 merge
- 남은 배포 일정 브랜치들을 develop에 rebase (이때 -p 옵션을 이용하여 머지 커밋을 유지)
- 각자의 feature 브랜치를 각 배포 일정 브랜치에 rebase
- 이 때 rebase 중 충돌이 많이 발생하면 cherry-pick
- hotfix가 필요할 경우 hotfix 브랜치 생성 후 master와 develop에 merge
- 다시 각 배포 일정 브랜치와 각자의 feature 브랜치를 rebase
우리 팀에 적합한 Git workflow는? [Look]
- Gitflow
- 체계적으로 관리 가능
- 복잡한 절차
- GitHub Flow
- 간단한 절차
- 너무 간단한...
- GitLab Flow
- 절충안
- 웹보다 동시에 여러 릴리즈 버전들이 현실 세계에 존재할 때 적합
- rebase를 적용
- 히스토리 보기 편함
- 절차가 복잡, 커밋을 잃을 수도 있는 리스크
Git/GitHub 토론
- Git/GitHub 관련 자유롭게 토론해보아요.