티스토리 뷰
Git 설치
- Git 설치 방법은 운영체제마다 다르다. 아래는 가장 널리 알려지고 권장되는 설치 예이다. (Windows에서 choco 패키지 관리자 설치 방법은 본 블로그의 이 글을 참고한다.)
# Windows에서 Git 설치, Git Bash도 함께 설치됨
$ choco install git -y
# macOS에서 Git 설치
$ brew install git -y
# Ubuntu에는 이미 설치되어 있음
Git 내 정보 설정하기
- Git을 설치하고 가장 먼저 필요한 작업은 내 정보를 설정하는 것이다. 아래와 같이 설정한다. [관련 링크]
# 한글 깨짐 현상 수정
$ set LC_ALL=ko_KR.UTF-8
# 현재 적용된 Git 환경 설정 출력
$ git config --list
user.name=foo
user.email=foo@bar.com
# 현재 작업 컴퓨터 전체에 적용될 내 계정 정보 설정
$ git config --global --replace-all user.name "foo"
$ git config --global --replace-all user.email "foo@bar.com"
$ git config --global credential.helper store
# 기본 pull 전략을 merge가 아닌 rebase로 설정
$ git config --global pull.rebase true
$ git config --global fetch.prune true
$ git config --global diff.colorMoved zebra
$ git config --global url."https://".insteadOf git://
# diff 명령을 GitHub 스타일로 표현해주는 git-split-diffs 설치
$ npm install -g git-split-diffs
$ git config --global core.pager "git-split-diffs --color | less -RFXe"
credential.helper store
옵션은 Git 원격 저장소의 인증 정보를 암호화하지 않고 저장하겠다는 것이다. Ubuntu on WSL 이용시 호환성이 좋아 추천한다. [관련 링크]git-split-diffs
은 diff 명령 실행 결과를 GitHub 스타일로 표현해주는 툴이다. [관련 링크]
Bash 쉘 프롬프트에 브랜치명 출력하기
- 아래는 Bash 쉘 프롬프트에 브랜치명을 출력하는 방법이다. [관련 링크]
$ nano ~/.bashrc
# git branch info if present
parse_git_branch() {
git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
}
export PS1="\[\033[36m\]\u@\h\[\033[00m\] \[\033[32m\]\w\[\033[33m\]\$(parse_git_branch)\[\033[00m\] \n\[\033[1;31m\]>>\[\033[00m\] "
SCM Breeze 설치
SCM Breeze
는 Bash에 여러 유용한 축약어와 단축키를 제공하는 환경 설정을 제공한다. [관련 링크] Git Bash 실행 상태에서 아래와 같이 설치한다.
# Ubuntu 사용시 Ruby 사전 설치
$ sudo apt-get install ruby -y
$ cd ~
$ git clone git://github.com/scmbreeze/scm_breeze.git ~/.scm_breeze
$ ~/.scm_breeze/install.sh
$ source ~/.bashrc
- 설치 후에는 아래와 같이 축약어를 사용할 수 있다.
# 사용 가능한 모든 축약어 목록 출력
$ list_aliases
# git status 축약어
$ gs
# git log 축약어
$ gl
# git commit 축약어
$ gc -m "Something added."
# git branch 축약어
$ gb
# git checkout 축약어, gb 결과 목록의 1번째 브랜치로 이동
$ gco 1
로컬에서 Git 원격 저장소 클로닝하기
- GitHub으로 생성한, 또는 이미 존재하는 저장소를 클로닝하는 것이 대개 Git과의 첫 만남이라고 할 수 있다. 굳이 내가 작성하지 않은 소스 코드라도, 특히 유명한 오픈 소스 공개 저장소를 클로닝하여 IDE로 분석해보면 자신의 실력을 일취월장할 수 있다.
# GitHub 원격 저장소 클로닝
$ git clone https://github.com/some-projects/some-project.git
# 클로닝한 프로젝트 디렉토리로 이동
$ cd some-project
Git 작업내역 반영하기
- Git 생태계에서 특정 작업의 시작은 최신 상태의 trunk 브랜치에서 내가 작업할 새로운 브랜치를 생성하는 것에서 시작한다. 커밋은 로컬 브랜치에 반영되며, 내가 작업한 내역이 컴퓨터의 고장 등으로 유실되지 않으려면, 최종적으로 원격 저장소에 푸시가 되어야 한다.
- 최종 작업분까지 푸시가 완료되면 Pull Request(PR)을 통해 팀원들의 리뷰를 거쳐 최종적으로 trunk 브랜치에 머지되어 배포 가능한 상태로 전환된다.
# 작업 전 trunk 브랜치 전환 후 최신 상태로 갱신
$ git checkout {trunk}
$ git pull
# 로컬에 기능을 작업할 새 작업 브랜치 생성
$ git checkout -b feature/foo
# 작업 후 로컬에 반영
$ git add .
# 로컬에 작업 내용 커밋
$ git commit -m "Added foo feature"
# 원격 저장소에 작업 내용 푸시
$ git push --set-upstream origin feature/foo
작업 중인 내 브랜치에 trunk 브랜치의 작업내역 받아오기
- 특정 브랜치에서의 작업이 길어지면 다른 팀원에 의해 계속 업데이트되는 trunk 브랜치와 차이가 발생하기 시작한다. 수시로 trunk 브랜치를 현재 작업 브랜치에 머지하여 소스 코드가 충돌하는 부분을 수정해주는 습관을 들이는 것이 좋다.
# 내 작업 브랜치로 이동
$ git checkout feature/foo
# trunk 브랜치 최신 내용 내 려받기
$ git checkout {trunk}
$ git pull
# 내 작업 브랜치로 이동
$ git checkout feature/foo
# trunk 브랜치의 최신 내용을 내 브랜치에 rebase
$ git rebase {trunk}
# 충돌 발생한 파일 수정 후 rebase 종료
$ git add {filename}
$ git rebase --continue
# 원격 저장소에 수정 내용 푸시
$ git push --force
Git 파일 내용 비교하기
git diff
명령을 이용하면 소스 코드 레벨에서 파일 내용을 비교할 수 있다. (앞서 소개한 git-split-diffs 환경 셋업을 추천한다.)
# 마지막 커밋과 unstaged 상태를 비교
$ git diff
# 마지막 커밋과 staged 상태를 비교
$ git diff --cached
# 특정 브랜치를 비교
$ git diff sourc
e-branch target-branch
현재 로컬 작업내역 취소하기
git reset --hard
명령을 사용하면 현재 작업 내역을 모두 취소하고 원하는 브랜치로 전환할 수 있다.
# 특정 브랜치 또는 커밋 해시로 강제 전환
$ git reset --hard {branch|tag|commit-hash}
원격지에 푸시한 작업내역 취소하기
- 가끔씩, 실수로 원격지에 푸시한 작업내역을 취소하고 싶은 경우가 있다.
git revert
명령어로 작업내역을 취소할 수 있다. 이 경우 취소한 작업내역 또한 커밋 이력에 남는다. (반대로git reset
명령어를 사용하면 취소한 작업내역은 완전히 제거되고, 취소에 대한 커밋 이력 또한 남지 않는다.)
# 작업내역을 취소, 파라메터에는 취소할 커밋 해시를 입력
$ git revert d8e1dd65ea448a0c0e06cbca27a0c5a9419d09e5
$ git push
원격지에 푸시한 연속된 여러 개의 커밋 합치기
- 자신의 작업 브랜치에서 작업하다 보면 PR에 앞서 불필요하게 여러 개의 커밋이 생겨, 하나로 정리하고 싶을 때가 있다. 이 경우에는
git rebase
명령을 사용하면 된다. (반드시의 본인의 작업 브랜치에만 해야 한다.) [관련 링크 1]
# 최근 커밋 목록 확인
$ git log
# 최근 3개의 커밋에 대해 합치기 요청
$ git rebase -i HEAD~3
# 모든 커밋에 대해 합치기 요청
$ git rebase -i --root
# 편집기로 화면 전환
# 커밋이 합쳐질 목적지가 되는 커밋에만 라인 접두어에 pick을 입력
# 합쳐져야될 커밋들은 라인 접두어에 s를 입력
pick 3f94c280 Do something
s e1418737 do dirty things 2
s 34e346e7 do dirty things
# 원격지에 합쳐진 커밋 결과를 반영
$ git push --force
Git Submodules 제어하기
- Git에서의
Submodules
는 리파지터리 속의 리파지터리라고 말할 수 있다. 만약 특정 리파지터리 속의 특정 경로의 소스 코드가 다른 리파지터리에서도 중복으로 사용할 수 있다고 가정해보자. 해당 소스 코드가 갱신되면 다른 리파지터리는 매번 소스 코드를 복사해야 한다. 이러한 중복 문제를 효율적으로 해결하고 관리하기 위해 Submodules 개념이 등장했다. 대표적인 사용 방법은 아래와 같다.
# 현재 저장소에 특정 서브모듈을 추가
$ git submodule add https://github.com/some-projects/some-project.git
# 서브모듈을 모두 포함하여 원격 저장소를 로컬로 복제
$ git clone --recurse-submodules -j8 https://github.com/some-projects/some-project.git
# 서브모듈을 모두 포함하여 원격 저장소로부터 최신 파일을 갱신
$ git pull --recurse-submodules
- 특정 원격 저장소를 로컬로 복제하면 서브모듈에 해당하는 디렉토리는 텅 빈채 복제가 된다.
--recurse-submodules
옵션(v2.13부터 가능) 주면 해당 저장소에 포함된 모든 서브모듈을 자동으로 복제할 수 있다. 추가적으로-j8
(v2.8부터 가능) 옵션을 주면 서브모듈을 동시에 8개까지 병렬로 동시에 복제할 수 있어 시간을 단축할 수 있다. - 서브모듈을 포함한 특정 저장소에 대한 변경 작업을 로컬에서 수행한 후 커밋과 푸시는 어떻게 해야 할까? 서브모듈과 상위 저장소에 대한 커밋/푸시를 각각 별도로 진행해야 한다. 사용 예는 아래와 같다.
# 먼저 서브모듈이 포함된 경로로 이동하여 커밋/푸시를 수행
$ cd some-submodule
$ git add .
$ git commit -m "some-comment"
$ git push
# 마지막으로 본 저장소로 이동하여 커밋/푸시를 수행
$ cd ..
$ git add .
$ git commit -m "some-comment"
$ git push
Pull Request하기
Pull Request(PR)
란 Git에는 없고GitHub
에 존재하는 개념으로 개발자가 작업한 브랜치를 최종적으로 언제든지 배포 가능한 프로덕션 레벨의main
브랜치에 머지를 요청하는 절차를 의미한다. PR을 요청하면 팀원 간의 활발한 코드 리뷰와 토론을 통해 최종적으로 머지를 결정하게 된다.TBD(Trunk-based Development)
와 같은 중요 방법론의 근간이 된다고 말할 수 있다.- 일반저으로
base
브랜치는 main 브랜치가 되며compare
브랜치는 작업자의 브랜치가 된다.
TBD 방식으로 배포하기
- TBD 방법론은 PR의 대상 브랜치를 main으로 한정하여 관리 대상을 단일 브랜치로 관리함으로서 브랜치의 파편화를 방지하여 개발 복잡도를 줄이는 기법이다. 작업자는 철저하게 최대 하루에서 이틀 분량의 작업 분량을 꾸준히 PR하는
Short-lived Branch
전략으로 개발하여 main으로부터 격리되는 현상을 방지할 수 있다. - TBD에서는 24시간 언제든지 배포가 준비된 trunk 브랜치를 유지한다. 개발자는 작업의 전체 크기를 하루 단위로 잘게 쪼개어 하루 안에 커밋 가능한 Short-lived Branch에서 작업 후 trunk 브랜치에 PR 요청한다.
- 각 작업은 trunk 브랜치에 머지되기 전에 엄격한 유닛 테스트를 통과해야만 하므로 trunk 브랜치는 24시간 작동 상태를 보장 받는다.
- 작은 크기의 작업 브랜치의 장점은 작업 크기가 작기 때문에 동료들이 부담 없이 높은 집중력으로 빠르게 코드 리뷰가 가능하다. 또한, 기능의 빠른 반영이 지속되어 충돌 부담도 줄어든다.
- 내 경우, 현재 프로젝트에서 릴리즈 엔지니어 역할을 수행하면서 매일 정해진 시간마다 main 브랜치를 STAGING 서버에 배포하여 현업 부서가 24시간의 테스트를 진행할 수 있게 하고, 동시에 24시간의 테스트가 완료된 STAGING 태그를 최종적으로 PROD에 배포하는 절차를 확립했다.
# 현재 main 브랜치의 내용을 STAGING 브랜치에 배포
git fetch --tags origin
git checkout STAGING
git reset --hard main
git push --force
git tag STAGING_RELEASE_06022022_1
git push --tags
# 24시간 전에 배포된 STAGING 태그를 PROD 브랜치에 배포
git fetch --tags origin
git checkout PROD
git reset --hard STAGING_RELEASE_06012022_1
git push --force
git tag PROD_RELEASE_06022022_1
git push --tags
# Hotfix가 발생하면 해당 작업분만 체리픽으로 PROD 브랜치에 배포
git fetch --tags origin
git checkout PROD
git cherry-pick {commit-id}
git push --force
git tag PROD_RELEASE_06022022_2
git push --tags
참고 글
댓글
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- DynamoDB
- Docker
- 평속
- node.js
- 로드 바이크
- spring
- Kendo UI
- JavaScript
- java
- Spring Boot
- jsp
- 자전거
- 알뜰폰
- jpa
- Tomcat
- kotlin
- chrome
- Eclipse
- 구동계
- bootstrap
- Spring MVC 3
- jstl
- JHipster
- MySQL
- Kendo UI Web Grid
- 로드바이크
- maven
- graylog
- CentOS
- 태그를 입력해 주세요.
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
글 보관함