git
git 기본
리눅스 코발트가 만듬
- CVCS 는 remote 에만 히스토리가 저장됨
- DVCS(git) 은 Local 에도 히스토리가 저장됨
최근 Master - Slave 구조를 없애는 운동의 일환으로 default branch 가 main 으로 변경됨
- git 은 commit 이전에 staging area 또는 index 라 불리는 상태를 가진다
repository
1
2
3
4
5
6
7
8
9
10
11
12
13
Local
Working directory
로컬 작업 디레토리, git add 수행 시 Staging Area(index)에 저장
Staging Area(index)
커밋 시 반영되는 파일 보관, 로컬 저장소에 저장
Local Repository
원격 저장소와 교류하는 영역, fetch 했을 때 저장되는 영역, Origin Respository 로 push
Remote
Upstream Repository
개발자들이 공유하는 저장소, 깃헙 같은 곳
Origin Respository
fork 했을 때 생기는 저장소, Upstream 으로 Pull Request
branch
- 개별 독립 작업 영역
- 분리된 작업 영역에서 자유롭게 소스 코드 변경, 개별 작업
Git Flow 브랜칭 기법
- 프로젝트 상황에 맞게 커스텀해서 사용하면 됨
- feature branch를 이용하기 때문에 기능 개발과 책임 소재를 명확히 할 수 있음
- 개발 버전과 제품 버전을 개별 관리할 수 있음
- Pull Request를 이용하기 때문에 코드 리뷰가 간편함
- feature branch와 hotfix branch의 commit message를 취합하게 되면 이전 버전과의 변경점 쉽게 파악 가능하다
git flow 의 5가지 브랜치
1
2
3
4
5
master : 제품으로 출시될 수 있는 브랜치
develop : 다음 출시 버전을 개발하는 브랜치
feature : 기능을 개발하는 브랜치
release : 이번 출시 버전을 준비하는 브랜치
hotfix : 출시 버전에서 발생한 버그를 수정하는 브랜치
- develop과 master는 중심이 되는 브랜치이다
- 따라서, git flow에서 두 브랜치는 반드시 존재해야 한다
(develop 브랜치는 master에서부터 시작된 브랜치)
1
2
3
4
5
6
7
master는 실제 배포되는 영역
release는 master되기 직전 최종 검증영역
hotfix는 master의 버그를 수정하므로 사실 포트폴리오에서
출시라고 하면 핵심 컨텐츠를 분기로 나눌 수 있는데
브랜치가 너무 많아지면 그것도 힘들 것 같다
단독으로 버그를 수정,,흠
feature에서 말하는 기능의 규모는 흠..
Git Ignore 제외 후보
1
2
3
자동으로 생성되는 로그 파일
프로젝트 설정 파일
중요 정보가 담긴 파일
https vs ssh
1
2
3
원격 저장소의 주소를 설정할 때,
https 와 ssh 를 선택할 수 있다.
https 는 id/pw 방식, ssh 는 private/personal key 방식
git 명령어 필수
git config
- git config –global user.name “<github name>”
- git config –global user.email “<github email>”
- git은 커밋할 때마다 이 정보를 사용한다.
- 하나의 커밋에서 계정 정보를 변경할 수 없다
- 현재 계정 정보 확인 : 제어판 > 사용자 계정 > 자격 증명 관리자
git init
- local git repository 를 설정한다
- workspace(작업 영역) 로 지정하는 명령어
- git 은 작업 영역에서의 변경을 감지한다
git add
- 감지된 변경 사항은 클라이언트가 인덱스 영역에 보관할 지 결정할 수 있다
- 인덱스 영역은 tree 와 BLOB 로 구성됨
- 인덱스 영역 내부는 참조 개념이 적용됨
git commit
- 인덱스에 추가된 변경 사항을 이력에 추가한다(상태를 저장)
- 인덱스 영역의 내용은 헤더 영역에 영구히 저장시킬 수 있다
- 헤더 영역은 트리의 참조를 저장한다
- 트리를 날려도 어딘가에 복제되고 있다
- git commit –amend -m “<message>” : 최종 로그 메시지 변경
git remote
- add origin <remote> : 원격지와 로컬 연결
- git ls-remote, git remote -v : 연결된 원격지 검색
git push
- 원격지에 없는 branch 명으로 push 했을 때 원격지에 해당 branch 생성
- 현재 원격 저장소 생성 과정에서 README 추가 설정하면 main branch 가 default
- git push –tags origin <branch> : 태그와 함께 push, 개발 단계를 알 수 있음
- git push –all : 팀장은 최초에 환경 설정 하고 브랜치 상관없이 다 push 할 수 있다
- git push - f origin <branch> : 강제로 push 하면 현재 log 남음
git clone
- 생성 directory 의 이름도 지정할 수 있다
- git init, git remote add, git pull 이 동시에 수행됨
- remote branch엔 모든 브랜치가 저장된다 « remote branch 가 뭘까
- 사실상 fetch 까지 진행
git pull
- 원격지와 로컬의 차이가 커지면 충돌이 많이 발생하기 때문에 자주 수행하기
- git pull origin master : origin 원격지의 master branch 의 버전을 가져옴
- download 와 merger 가 동시에 수행됨
git 명령어 나머지
git checkout
- branch 변경시 local 형상에 따라 작업 영역도 변경됨
- HEAD 포인터가 달라지니깐 참조 tree 가 변경되는 거
- git checkout -b <branch> origin/<branch> : branch 생성과 동시에 변경 및 merge
git fetch
- git fetch origin : 원격지의 모든 branch 의 모든 이력을 가져옴
git merge
1
2
3
4
fast-forward
형상이 같을 때 브랜치 포인터만 이동함
3 way merge
형상이 다를 때, merge 충돌이 생기는 상황, 동일 파일을 수정
- git 은 동일한 파일을 수정하지 않으면 자동으로 merge
- 같은 파일을 수정했더라도 서로 다른 행을 수정하면 자동으로 merge
- 충돌이 발생하면 양쪽 브랜치에서 동시에 변경된 사항을 표시해주며
이중 개발자가 스스로 판단하고 결정해야함 - git merge origin/<branch> : 해당 branch 의 이력을 현재 branch 에 merge
- git merge –squash : 커밋 안 된 상태로 가져옴. 이력 정리하기 좋음
git rebase
- 이력을 합치고 싶을 때, 커밋 이력을 정리할 떄
- git rebase -i HEAD~3 : 이력 순서가 v1 v2 v3 v4 일때 v2 까지의 커밋 이력을 합침
- vi editor 가 실행됨
- squash(찌그러트림, 압축, 로그 통합)는 과거로 찌그러트려짐
- 과거 이력으로 코드가 모아짐 « rebase 도 그럼 충돌 위험이 있지 않은가
코드가 모아지는 게 아니라 이력만 모아지는 거 아닌가
git reflog
- reset 으로 커밋 이력을 제거 했을 때
- 한번이라도 커밋 했던 이력을 다 확인할 수 있다
- 참고하여 git reset –hard <version> 하면 된다
- 헤더 영역이 참조 형태로 기록되기 때문에 이러한 버전 관리가 가능하다
git reset « reset 강의 다시 듣기
- git reset –soft <version>
- 이전 상태로 (이력 제거)
1 2 3 4 5 6 7 8 9 10
hard v2 를 reset 대상으로 지정하면 v2 로 복구시킨다 -> 이후 이력이 삭제됨 삭제된 이력은 reflog 를 이용하면 다시 돌아갈 수 있다 mixed v2 를 대상으로 시행하면 v2 commit 이력과 index 영역을 지우고 작업물은 그대로 놔둔다 즉 변경 감지 상태로 돌아간다 차라리 새로운 버전을 만드는 게 나을 수도 있다 soft v2 를 대상으로 시행하면 커밋 이력만 지우고 인덱스 영역은 유지
git revert
- 이전 상태로 (이력 유지)
- 일반적으로 특정 버전을 배포했는데 문제가 생기면 문제가 생긴 commit 을 revert 한다
- v3를 revert 대상으로 하면 v2로 되돌려짐
git status
- 현재 작업 중인 파일의 상태를 확인
git switch
- git switch -c feature/5 : bracnh 생성과 전환을 한번에 수행
- 새 브랜치 생성시, 현재 브랜치의 상태를 기준으로 만드니까 현재 브랜치에 대해 알아야함
- 여기서 말하는 상태는 인덱스 영역인지 커밋에대한 건지 이해 필요
git tag
- git tag <message>
- git tag -n : 어느 시점에 tag 를 남겼는지 검색
- push 했을 때 원격지에서 태그를 확인할 수 있다
terminal 명령어
touch
- 빈 파일 생성
echo
- 파일 내용 작성
최초 다운로드하기
원격지에 연결해서 다운로드 받을 때 최초에 아무 브랜치도 없는 상황에서 다운로드 방법
- git clone 하면 default branch 를 다운로드
- git checkout -b <branch> origin/<branch> : 원격지가 등록 됐으니 다른 브랜치 다운로드
혼자서 개발하기
setting_feature 브랜치에서 환경설정 작업
1
2
3
1. 필요한 라이브러리 다운
2. 패키지 구조 설계
3. 인터페이스 구조 설계
dev 로 돌아가서 merge 또는 pull
1
2
1. git checkout -b dev origin/main
2. git merge --no-ff setting_feature : merge option(log) 남기며 merge
- feature 에선 커밋을 막 해도 된다
- 이때 rebase 를 쓴다
- git rebase -i HEAD~<number> - ‘i’ - ‘pick’ - ‘s’ - ‘esc’ - ‘:wq’
- This is the 1st comiit message << commit message 삭제
- 의미 없는 커밋 이력은 지워라
- 이제 main으로 dev를 merge 할 때 이력이 넘쳐난다
- main 을 push 하기 전에 tag 를 남기자
- git tag blog1.0.0
소규모 협업하기(팀장)
- 단기 소규모 프로젝트니깐 main - dev - feat 활용
Remote Repository 생성 및 README.md 추가
git clone
git checkout -b dev
프로젝트 세팅
git ignore 작성
git push -all
브랜치 보호 : settings - branches - branch name pattern - require a pull reqeust merging
알림 설정 : notifications - address - email or Webhooks (실시간 알림)
Collaborators - Manage access - Add people
Pull Request 대응
- commits - review changes
1 2 3
1. comment : 초안에 대한 답변 2. approve : 승인 -> 팀원도 merge 할 수 있게 되지만 소규모에선 팀장이 하기 3. request changes : 거절
merge 방식
1
2
3
1. create a merge commit : 그냥 이거하자
2. squash and merge : 애초에 squash 교육하고 지시
3. rebase and merge : 애초에 rebase 교육하고 지시
실수했다고 뭐라하지 말고 실수하지 않는 환경을 구성하기
주의
- main, dev branch 보호하고 팀원들은 이 브랜치들에서 rebase 하지마라고 지시
- 실수로 dev 에서 작업한 팀원이 있다면 feat 으로 넘기고 rebase 해서 push 하도록 교육
소규모 협업하기(팀원)
최초
1
2
3
1. git clone
2. git checkout -b dev origin/dev
반복
- github issue 작성
- 자신이 구현할 기능을 작성하고 issue 번호를 feat 번호로 지정
- 여기선 issue #3 으로 예시를 듦
- feat/3 branch 생성
- git checkout -b feat/3
기능 구현
- git commit & git push origin feat/3
- 자신의 local branch 이름과 동일한 원격지의 branch 이름에 push
- pull request
- base branch 를 dev branch 로 변경하고 우측엔 feat/3 branch 지정
- 이때 draft pull request 는 단순히 코드 리뷰를 요청
5-1 요청 승인시
1
2
3
4
5
6
7
8
9
1. git push --delete origin feat/3
- 원격지의 feat/3 branch 를 삭제
2. git checkout dev
- merge 된 dev branch 를 local 에 동기화 해야함
- local branch 를 dev 로 변경
3. git pull origin dev
- 원격지 dev branch 의 형상을 현재 branch 로 가져옴
5-2 요청 거절시
1
2
3
4
5
6
- request rebase, code error, merge conflict 등
- 상의 후 결정
- 거절 후 rebase 하고 다시 올리면 error 가 발생할 텐데
- git push -f origin feat/3 실행하면 강제로 local 형상을 원격지에 적용함
- 이전의 pull request 의 형상이 자동으로 바뀌므로
수정 완료 comment 를 작성하면 팀장에게 알림이 가서 인지할 수 있다
<hr/>
소규모 협업 프로젝트 배포
- git checkout dev
- git pull origin dev
- git checkout main
- git merge –no–ff dev
- git tag {version}
- git push –tags origin main
github actions
1
2
3
CI 도구 대신 github actions
Docker를 활용하여 AWS 엘라스틱 빈스톡 사용
하지만 바로 이런식으로 넘어가면 기반이 없다
배포 자동화 도구(CI Tool)
1
2
3
4
5
6
7
github 에서 push 하거나 github 으로 request 하거나해서
github origin/main 의 코드를 넘겨주고
배포 스크립트 작성 후 AWS, Azure 같은 클라우드 저장소로 넘긴 뒤에 jar(또는 war) 실행
jenkins, travis 같은 CI 도구에서 배포 스크립트를 작성할 수 있다
1. jar 파일을 webapp 폴더로 이동
2. java -jar <jar-file>
하지만 바로 이런식으로 넘어가면 기반이 없다
그럼 어떻게
- 클라우드 저장소를 직접 공부하고 CI 없이 해보며 기초부터 접근해야함
- 최신 기술 탐내면서 바로 배포 자동화 같은 걸 공부하지 말자
<hr/>