branch
는 분기
라는 뜻을 가지고 있는데, 말그대로 git 에서 버전 관리의 분기점을 만드는 기능이다.
git branch (새 브랜치명)
: 새 브랜치 생성
git checkout -b (새 브랜치명)
: 새 브랜치 생성 후 이동
git checkout (이동하고 싶은 브랜치명)
: 브랜치 이동
git branch —list
: 브랜치 리스트 확인
git branch -D (브랜치명)
: 브랜치 삭제 (해당 브랜치 밖에 있어야.)
git merge
는 서로 다른 branch 의 작업 내용을 하나의 branch 로 통합하기 위한 명령어입니다. main 브랜치에서 develop 브랜치를 merge 하려면?git merge develop
merge가 되면 이제 아래 명령어를 입력해서, 커밋 기록이 어떤식으로 이루어져있는지를 확인할 수 있다.git log --graph --decorate --oneline
만약 줄기가 나눠진 형태로 커밋 기록을 남기고 싶다면?
```markdown
git merge develop --no-ff
```
위와 같이 `--no-ff` 를 붙여서 merge 명령어를 입력하면 됨. (non fast forward 의 약자)
<aside>
💡 Fast-forward 개념이 중요한 이유는, 커밋 기록 (히스토리) 을 어떻게 관리할지 정할 때 사용되기 때문. 만약 하나의 줄기로 관리를 하고자 한다면 아래에서 배울 rebase 와 함께 fast-forward 형태로 병합을 진행시키면 되고, 브랜치의 줄기를 남기고자 한다면 non fast-forward 형태로 병합을 진행시키면 되는 것. 어떻게 관리할지는 팀에서 정하기 나름이지만 **보통은 non fast-forward 형태로 병합을 진행해서 브랜치 작업을 확인할 수 있도록 기록을 남기는 경우가 많다.**
</aside>
rebase
는 특정 브랜치를 base(기준)으로 놓고 커밋 이력을 정렬하겠다는 명령어. 만약 브랜치가 나뉘어져있다면, main 에서 rebase develop 을 실행할 경우 아래처럼 develop 의 커밋 이력을 base 로 해서, 거기에 이어서 main 의 커밋 이력이 정렬되게 된다. 이어지는 main 의 커밋 이력은 이전과 동일해보이지만, 정확히는 이전과 다른 커밋 이력. 즉, merge (non fast-forward) 와 같이 줄기가 나뉘지 않고, 하나의 줄기로 커밋 이력이 정렬되게 되는 것. 예) develop 의 커밋 이력에 main 의 이력이 이어지도록 rebase 를 해주려면?git rebase develop
💡 rebase 는 정확히 말하면 병합을 위한 것이 아니라, **커밋 히스토리를 정렬하기 위한**. 이미 병합이 된 브랜치가 있더라도 거기서 rebase 를 하면 커밋 히스토리를 다시 정렬할 수 있다.
💡 rebase 는 커밋 이력을 단순히 관리하고 싶을 때 사용하는 명령어이고, merge 는 변경 이력을 모두 남기고 싶을 때 사용하는 명령어. 실제로는 커밋 이력을 남기는 것이 굉장히 중요하기 때문에 rebase 는 fork 시에 원본 프로젝트에 맞게 (동기화해서) 변경 이력을 관리하고자 하는 특수한 상황에서만 사용하고 보통은 merge 만을 사용한다.
- rebase 시의 merge conflict 해결하기
그냥 merge 를 할 때는 파일을 수정해준 후에 바로 add → commit 을 진행하면 해결되는거였지만, rebase 는 조금 다르다.
우선 파일을 수정하고 add 를 진행한 후에, commit 대신에 `git rebase --continue` 를 진행하면 된다.
```markdown
git add .
git rebase --continue
```
만약 merge conflict 가 발생한 상황에서 rebase 를 취소하고 싶다면 `git rebase --abort` 를 입력.
Pull Request
란 ‘내 담당 브랜치에서 작업이 완료되었으니, 이 브랜치의 코드를 가져가서 병합해주세요’ 라는 요청을 보내는 것. main 브랜치
는 사용자가 이용할 서비스의 코드가 담기는 브랜치. 즉, 해당 브랜치에 있는 코드가 사용자에게 배포된다. develop 브랜치
는 사용자에게 서비스를 배포하기 이전에 모든 기능들이 통합되어서 테스트를 진행하는 브랜치. 테스트가 완료되면 main 브랜치에 코드를 통합해서, 실제로 사용자가 이용하는 서비스에 코드가 반영. (보통은 테스트용 브랜치가 따로 존재.) feature ~ 브랜치
는 서비스의 기능을 분할해서 기능 하나를 구현하는 브랜치. 여기서 하나의 기능 구현이 완료되면 develop 브랜치로 내 코드를 통합해달라고 요청. → pull request → 이때, 주니어 개발자가 그냥 마구잡이로 develop 브랜치에 코드를 merge 해버리면 어떻게 될까요? 코드가 비효율적으로 작성되었는데도, 오류가 발생하는 코드인데도, 이 코드를 서비스에 반영해버리게 되면 큰 문제가 발생할 겁니다! → 그래서 개발자가 작성한 코드를 merge 하기 이전에 ‘병합해주세요’ 라는 요청을 보내고, 시니어 개발자 혹은 동료들이 그 코드를 보고 ‘코드 리뷰’ 를 진행하면서 더 효율적으로 작성할 수 없는지, 오류가 발생하는 코드는 아닌지를 검사하는 것입니다. → 검사가 완료되면, 그제서야 관리자가 병합 요청을 승인하고, 해당 기능이 develop 브랜치에 반영되는 것입니다.git remote add origin (github repo 주소)
이제 우리가 로컬(우리 컴퓨터)에서 작업한 내용을 github 로 푸쉬.git push --all
이전까지 진행했던 브랜치 생성 작업, 브랜치 생성 후 commit 내역 등이 모두 github 로 올라간다. 뒤에 --all
을 붙이지 않으면, 하나의 브랜치만 올라간다!
💡 실제로 git push —all 을 쓰는 경우는 거의 없고, 보통은 작업할 때 하나의 브랜치에 집중해서 작업하고, 작업이 완료되면 해당 브랜치만 push 하는 방식으로 진행.
이제 github repo 로 가보니?
![Screen Shot 2022-10-16 at 7.03.37 PM.png](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/1087fee1-9bf6-4b9b-b6f8-10af92f6a0c7/Screen_Shot_2022-10-16_at_7.03.37_PM.png)
버튼이 이렇게 표시되고 있다. 이제 Pull Request 를 할 준비가 완료된 것!
이렇게 버튼이 표시되는 이유는, **main 브랜치보다 더 이후의 commit 이력을 가지고 있는 브랜치가 존재할 경우 자동으로 github 가 pull request 를 하라고 표시해주기 때문.**
Github에서 Pull Request 하기.
보통은 pull request 를 작성할 때는, 왜 해당 부분을 작성했고, 이전에 비해서 어떤 것이 바뀌었는지, 그리고 코드 리뷰와 관련해서 요청사항은 어떤 것이 있는지 (ex. 특히 이 파일에서 if 문을 봐달라) 를 내용으로 작성.
pull request 가 성공적으로 merge 되면, feature/name 브랜치를 삭제할 수 있다고 표시된다. delete branch 버튼을 눌러서 삭제. (필요하다면 추후에 다시 살릴 수도 있다.)
→ 삭제해주는 이유는 이미 해당 브랜치에서 할 작업은 끝났기 때문에, 삭제해서 정확히 우리가 작업을 진행 중인 브랜치만 남겨서 확인하기 위함.
git pull origin main
→ 이제 로컬 (우리 컴퓨터의) main 브랜치의 intro.txt 가 github 와 동일해졌다. 그런데, 우리 컴퓨터는 아직도 github 쪽에 feature/desc 등의 브랜치가 존재하는 줄 착각하고 있다. pull request 이후에 분명 삭제되었는데도, 우리 컴퓨터는 아직 모르고 있다.git fetch --prune
위 명령어를 입력하면, 우리 컴퓨터가 github 상에서 해당 브랜치들이 삭제되었음을 인식. → 이렇게 해주는 이유는 혹시나 git pull 하는 과정에서 발생할 수 있는 오류를 방지하기 위함이다. 그리고 아래 명령어를 이용해서 로컬 브랜치들을 삭제. (로컬 브랜치를 어떻게 할지는 선택이지만, 보통은 ‘pull request 가 merge 된 이후에는’ 지우면서 진행.)git branch -D feature/desc feature/email feature/name
→ merge 가 되기도 전에 지우지 않게 조심!git switch/checkout (base 브랜치)
git pull origin (base 브랜치)
git switch/checkout (head 브랜치)
git merge (base 브랜치)
위 명령어를 순서대로 vscode 터미널에 입력하면, 이제 vscode 상에서 conflict 를 해결할 수 있다.해결 후에,git add .
git commit -m"Etc: Merge main to hotfix/name2 for resolving conflict"
git push origin (head 브랜치)
를 입력하시면, 이제 커밋 이력이 충돌나지 않게 정리된 상태로 github 에 올라가게 된다. 다시 github 에서 pull request 부분을 보면? → 새롭게 pull request 를 생성하지 않아도, push 한 내용이 반영되면서, merge 할 수 있다고 표시되는 것을 알 수 있다!
💡 이미 pull request 를 생성한 상황에서 해당 브랜치 내부 파일을 수정한 후에 push 를 하면, 새롭게 pull request 를 만들지 않아도 자동으로 해당 pull request 에 수정사항이 반영!