Git
포스트
취소

Git

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

  • 파일 내용 작성

최초 다운로드하기

원격지에 연결해서 다운로드 받을 때 최초에 아무 브랜치도 없는 상황에서 다운로드 방법

  1. git clone 하면 default branch 를 다운로드
  2. 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 활용
  1. Remote Repository 생성 및 README.md 추가

  2. git clone

  3. git checkout -b dev

  4. 프로젝트 세팅

  5. git ignore 작성

  6. git push -all

  7. 브랜치 보호 : settings - branches - branch name pattern - require a pull reqeust merging

  8. 알림 설정 : notifications - address - email or Webhooks (실시간 알림)

  9. 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


반복

  1. github issue 작성
    • 자신이 구현할 기능을 작성하고 issue 번호를 feat 번호로 지정
    • 여기선 issue #3 으로 예시를 듦
  2. feat/3 branch 생성
    • git checkout -b feat/3
  3. 기능 구현

  4. git commit & git push origin feat/3
    • 자신의 local branch 이름과 동일한 원격지의 branch 이름에 push
  5. 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/>

소규모 협업 프로젝트 배포

  1. git checkout dev
  2. git pull origin dev
  3. git checkout main
  4. git merge –no–ff dev
  5. git tag {version}
  6. 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/>

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.