Git / Github 총 정리
Coding apple 의 Git / Github 영상을 시청 후 관련 자료들도 있고, 정리한 Posting
출처 : https://codingapple.com/course/git-and-github/
Git 을 사용하는 이유
작성한 Code 를 기록하기 위해 Git 을 사용한다.
내가 만든 작업 폴더에서 git 을 이용하고 싶으면 다음과 같은 코드를 Terminal 에 입력하고 시작한다.
git init
git add 파일명
git commit -m "원하는 메시지"
- git init 을 하면 git 이 파일 생성하는 것, 코드 생성하는 것을 추적하기 시작함.
- git init : Local Repository (로컬저장소) 를 생성하는 것인데, 후에 설명하기도 하고 전에 Posting 했으니 좀 보도록.
그렇다면 이 과정은 어떻게 이루어지는 것인가?
Staing Area
- commit 을 하기 전에 commit 할 파일들을 올려놓는 곳
- staging area 에 파일을 넣는 행위를 staging 이라고 함.
- git add 명령어를 통해 staging 가능
Repository
- commit 된 파일들의 version 을 모아놓는 곳
기타 명령어들
- git add 파일명1 파일명2 : 동시에 여러 파일 staging
- git add . : 작업 폴더 안에 있는 모든 파일들을 staging
- git status : 변경된 파일, staging 된 파일들을 알려줌 (지금 뭐 하는지 까먹었을 때 자주 입력)
- git restore : staging 된 파일들을 취소할 때 입력
- git log --all --oneline : commit 기록을 한 눈에 파악하고 싶을 때 git log 명령어 입력
- git log --all --oneline --graph : --graph option 을 넣으면 그래프로 그려줌
Commit 주기
- 간단한 기능을 하나 추가할 때마다 commit 함.
git diff
- commit 하기 전에 이전과 현재 코드의 차이점을 알 수 있는 명령어
- 잘 안쓴다. (git difftool 이라는 것도 있는데 잘 안씀 -> 더 편리한 게 있는데?)
- Editor 들을 많이 사용 (VSCode Editor 의 경우 Extensions 메뉴에서 Git 관련 부가기능을 설치)
Git graph
- VSCode Git 메뉴에서 Git Graph 버튼을 누르면 확인 가능
- commit 내역들을 한 눈에 확인할 수 있고 파일명을 우클릭하면 git diff 도 가능
Branch
- Project 복사본
- 안전하게 새로운 기능을 추가하고 싶을 때 사용
git branch 브랜치이름 // Project 사본 하나 생성
git switch 브랜치이름 // 원하는 branch로 이동하는 명령어 (예전에는 git checkout 사용했었음)
Merge
- branch 를 합치는 것
git switch main
git merge 브랜치이름 // 원하는 branch 이름을 넣으면 현재 있는 branch 에 합쳐짐. 그 후 git log 명령어를 통해 확인 가능
주의!
conflict 발생
예를 들어 master branch 와 coupon branch 에서 같은 파일, 같은 코드 줄을 수정했을 경우 merge conflict 발생.
VSCode Editor 의 경우는 Accept Incoming Change 등 버튼을 제공하여 활용하면 편리함.
아니면 둘 중 어떤 코드를 적용할지를 골라서 결정
git add 파일명 -> git commit -m "메시지" 이렇게 입력하면 새로운 commit 생성해주면서 merge conflict 해결해주고 branch 도 합쳐줌.
Branch 사용 이유
- 여러 개발자들과 협업할 때 편리함
그래서 기능을 하나 추가하고 싶은 경우 다음과 같이 개발하면 편리함.
- branch 로 프로젝트 사본을 하나 만들어서 거기서 개발
- test 해본 후 잘 되면 main branch 에 다시 합침.
Branch 합치는 방법
1️⃣ 3-way merge
- Merge 기본 동작 방식
2️⃣ fast-forward merge
- 새로운 branch 에는 신규 commit 이 있고, 기준이 되는 branch 에는 신규 commit 이 없는 경우
- 딱히 합칠 것이 없어서 신규 branch 에게 "너의 이름은 지금부터 main branch야" 라고 하는 것
- 싫으면 "git branch --no-ff branchName" 해서 강제로 3-way merge 가능
Branch delete
"git branch -d 브랜치이름" : 병합이 완료된 branch 삭제
"git branch -D 브랜치이름" : 병합하지 않은 branch 삭제
3️⃣ rebase and merge
- rebase : branch starting point 를 다른 commit 으로 옮겨주는 행위
- rebase 를 이용해서 신규 branch 의 시작점을 main branch 최근 commit 으로 옮겨준 다음 fast-forward merge 하는 것도 가능
이렇게 하는 이유?
- 3-way merge 말고 강제로 fast-forward 하고싶은 경우
- commit 내역을 한 줄로 계속 이어서 남기고 싶은 경우
실제로 이렇게 하려고 한다면 다음과 같이 진행하면 됨.
- 신규 branch 로 이동
- git rebase main
- git merge 브랜치이름
단점은 branch 끼리 차이가 너무 많이 나는 경우 rebase 를 하면 conflict 가 많이 발생할 수 있음.
4️⃣ squash and merge
- 모든 branch 를 3-way merge 하면 다음과 같은 참사가 발생할 수 있음.
사용 이유?
- 3-way merge 한 것들은 매우 복잡해보임.
- main branch git log 를 출력해보면 3-way merge 된 branch 들의 commit 내역도 다 같이 출력되어서 더러워보임.
- 이렇게 되면 main branch 의 git log 를 출력해볼 때 merge 완료된 branch 들의 commit 같은 것들은 출력되지 않음.
- 하는 방법은 --squash option 추가
- "git switch main" -> "git merge --squash 브랜치이름" -> "git commit -m "메시지" "
Repository 란?
- git 이 파일버전을 저장해두는 장소
- 실제로 개발할 때는 온라인 Repository 를 많이 사용
- github.com 은 원격 저장소를 제공해주는 곳인데, 설치 과정이나 이런 건 생략함. (전 포스팅에도 있음)
- 기본 브랜치 이름을 master 가 아닌 main 으로 사용하라고 강요함
git branch -M main // 기본 브랜치 이름 변경
github 에서 만든 원격 저장소에 올리기
git push -u 원격저장소주소 main (원하는 브랜치이름)
- -u option : 방금 입력한 주소를 기억하라는 의미로 다음부터는 주소를 길게 입력하지 않고 git push 만 입력해도 가능
- 원격저장소 주소를 길게 입력하는 것이 귀찮은 경우 다음과 같은 코드 실행
git remote add origin 원격저장소주소 // origin 이라는 변수명을 통해 주소를 대체할 수 있음 (변수와 동일)
git remote -v // 변수목록을 살펴볼 수 있음
- 원격저장소에 있는 걸 그대로 내려받고 싶으면 "git clone 원격저장소주소" 를 실행하면 됨.
저장소에 올리고 싶지 않은 파일이 존재하는 경우
- .gitignore 파일 생성 후 입력
- 원격저장소를 효율적으로 사용하고 싶으면 쓸데없는 파일은 commit 하지 않는 것이 좋음
- git add . 해도 staging 안됨
- 웹개발을 예시로 들면 node_modules, 개인 정보들이 들어있는 .env 파일은 올리면 안됨.
그렇다면 원격저장소는 왜 사용하는 걸까?
-> 다른 사람들과 협업하려고!
원격저장소와 로컬저장소에 있는 것이 같아야 git push 가 가능하다.
따라서 다른 사람과 협업하는 경우, git pull 을 통해 원격저장소에 있는 코드를 가지고 온 후 git push 를 하여야 한다.
git pull 원격저장소주소 브랜치이름
// 로컬이 원격저장소 내용을 반영한 최신상태가 되어 git push 가 가능해짐.
- git pull : git fetch + git merge
- fetch : 원격저장소에 있는 commit 중에 로컬에 없는 신규 commit 을 가져오라는 의미
- git pull 할 때 팀원 2명이서 같은 파일을 건드리고 있는 경우 merge conflict 발생할 수 있음.
- 로컬 뿐만 아니라 원격저장소에서도 branch 를 만들 수 있으니 어떤 곳에서 만들던 본인의 선택임.
- github 에서 만드는 건 생략함.
로컬저장소에서 branch 생성해서 git push 가능
- 다른 사람들과 협업하는 상황 속에서 branch 를 만들고 그 branch 를 push 함
- main branch 와 합쳐야 기능이 완성되는데 팀끼리 일하는 경우 merge 하기 전에 토론하거나 검토해야 하는 경우가 많음.
- github.com 은 Pull requests 라는 기능이 존재하는데, 쉬운 말로 merge request 라고 이해하면 됨.
- 이것은 내 branch 를 merge 해달라고 요청하거나 팀원끼리 merge 전에 코드 검토가 가능함.
- 위 사진처럼 Pull requests 메뉴에서 확인 가능하여 토론하거나 코드를 리뷰할 수 있음.
- 앞에서 언급한 것 처럼 merge option 존재
- Create a merge commit 은 3-way merge 이고 나머지는 동일함.
git branch 방법
필요한 이유?
- branch 관리가 쉬워짐
- 팀원이 아무리 많아도 개발 절차가 매끄러워짐.
① git flow
- 안정적인 운영이 필요한 경우 사용 (예를 들면 게임 개발)
크게 5개 branch 를 운영함
- main branch
- develop branch (개발용)
- feature branch (develop 에 기능추가용)
- hotfix branch (main branch 버그 해결용)
- release branch (develop branch 를 main branch 에 합치기 전 최종 테스트용)
예를 들어 게임 개발을 한다고 생각해보자.
1️⃣ 신기능 개발 후 develop branch 생성
- 실험용 프로젝트 사본을 만들고 개발
- 기존 main branch 에 있던 걸 복사 후 여기서 개발
2️⃣ 신기능 개발은 feature branch 에서 개발
- 길드 기능을 만들고 싶은 경우 feature / guild 와 같은 branch 를 만들어서 기능을 만든다.
- 보통 branch 를 작명할 때 여러 단어가 필요한 경우 대시나 / 기호를 사용한다.
- 완성되면 develop branch 에 merge 한다 (중요한 내용이 아닌 경우 squash and merge 사용 괜찮음)
3️⃣ 신버전 출시 준비는 release branch
- 기능들이 완성된 경우 테스트를 위해 release branch 에 복사한 다음 출시 준비
- 테스트나 QA 같은 것을 진행함
- 버그를 발견하면 알아서 임시 branch 를 만들어서 수정 (release / 1.0 이렇게 짓는 경우가 많음)
4️⃣ hotfix branch
- main branch 에서 버그가 발생한 경우 또는 급하게 업데이트를 해야 하는 경우 hotfix branch 를 만들어서 버그를 바로 수정
- 수정이 완료되면 main branch 에 직접 merge 함. (develop branch 에도 merge)
git flow 단점
- continuous delivery 같은 실시간으로 배포하는 것들을 할 때는 적합하지 않을 수 있음.
- 선택에 합당한 근거만 있다면 어떤 선택이든지 가능
② Trunk-based 방법
- 코드를 작성한 것을 바로 배포해도 상관 없는 Program 인 경우 또는 많은 업데이트를 하지 않는 Program 이면 많은 branch 를 만들 필요가 없기 때문에 main branch 와 feature branch 만 운영하는 방법
- github flow 도 이와 비슷한 방법임
장점
- Code 를 한 branch 에서만 관리하기 때문에 편리함
- 크게 개발해서 한 번에 merge 하는 것보다 작은 단위로 merge 하는 것이 더 안전함
단점
- main branch 에 있는 code 가 잘못되면 큰일나기 때문에 test 나 code review 를 자주 해야 함.
- test 를 자주하고 자동화해놓는 곳들이 제대로 사용가능함.
결론
어느 정도 개발이 진척되었거나 코딩을 엄청 잘한다 -> trunk-based 쓰는 것이 훨씬 편리
CI / CD 식으로 개발하는 곳들도 trunk-based 방법 적용
출시된 버전의 안정성이 중요한 프로그램들 or 뼈대가 확실하지 않아 연구식으로 개발하는 프로그램 -> git flow
중요한 것은 정해진 것은 없고 직접 해보고 판단하는 게 제일 중요함.