버전 관리 시스템(Version Control System)의 한 종류로 스냅샷 기반의 데이터 저장을 통해 성능에 중점을 둔 분산 버전 관리 시스템
git add [파일명]
를 통해 Staging Area
라는 논리적 영역에 스테이징 상태로 변경git commit -m ""
을 통해 스테이징 상태의 파일의 스냅샷을 저장하고, 해시값 부여git push
를 통해 커밋된 변경 사항을 원격 저장소로 전송Git의 객체 모델
Git은 내부적으로 4가지 주요 객체를 사용하여 데이터를 관리
1. 블롭(blob) : 파일의 내용 자체를 저장
2. 트리(tree) : 디렉토리와 그 안의 포함된 파일 및 하위 디렉토리를 표현
3. 커밋(commit) : 프로젝트의 특정 시점(스냅샷)을 가리키며, 트리 객체를 참조
4. 태그(tag) : 특정 커밋이나 객체에 별칭을 부여트리 객체의 역할
- 디렉토리 표현 : 디렉토리 하나를 표현
- 연결 구조 : 해당 디렉토리 안의 파일과 하위 디렉토리에 대한 정보를 보유하여 이를 통해 전체 프로젝트의 디렉토리 구조를 나타냄
트리 객체의 구성
- 모드(mode), 해시(hash), 타입(type), 파일 또는 디렉토리 이름으로 구성되는 여러 개의 엔트리(entry)를 포함
- 엔트리는 블롭, 다른 트리로 두 가지 타입을 가질 수 있음
트리 객체의 연결 구조 상세
- 위 프로젝트 구조는 다음과 같다.
- 블롭 : 각 파일에 대한 객체
- README.md
- src/main.py
- src/utils.py
- docs/manual.md- 트리 : 디렉토리 객체
- src/
- docs/
- root/- 커밋 : 루트 트리 객체를 가리키며, 커밋 메세지와 메타데이터를 포함
위 내용을 토대로 시각화하면 다음과 같다.
이렇게 연결하는 이유?
- 효율적인 데이터 관리
- 동일한 파일 또는 디렉토리가 변경되지 않으면 이전에 생성된 객체를 재사용
- 저장 공간 절약이 가능하고, 데이터의 중복을 방지- 빠른 변경 추적
- 해시는 내용 기반으로 생성되어 내용이 변경되면 해시가 달라져 빠른 추적 가능
- SHA-1 해시로 식별되므로 데이터의 무결성을 보장
위와 같은 이유들로 인해 다수의 개발자가 작업하는 환경에서는 Git의 사용법을 숙지하여 코드 관리 및 리뷰에 대한 안정성 및 연속성을 제공하여 생산성을 향상시키는 것이 중요하다.
각 개발자의 격리된 작업 환경을 제공하기 때문에 다수의 팀 구성원이 메인 코드베이스를 중심으로 안전하게 새로운 기능을 개발 할 수 있는 전략으로 메인 코드베이스(master)는 항상 버그 프리 상태로 유지할 수 있어 안정적인 상태가 되며, CI를 적용하기도 수월하다.
로컬 저장소와 원격 저장소 연결
기존에 생성된 로컬 저장소에 새로운 원격 저장소를 연결하고, 로컬 저장소의 데이터를 푸시하는 방식을 의미
git init
git add .
git commit -m "initial commit."
git remote add origin [repository URL]
git push origin master
원격 저장소 코드 내려받기
원격 저장소의 코드를 새로운 로컬 저장소를 생성하여 원격 저장소의 모든 데이터를 내려받는 것을 의미
git clone [repository URL]
메인 베이스코드(master)에 직접 작업하는 것이 아닌 새로운 기능 개발을 위한 분리된 작업 브랜치 생성
# 존재하는 브랜치 확인
git branch -r
# 체크아웃
git checkout -b issue-[#이슈번호]
# 없으면 master 기준 생성 후 체크아웃
git checkout -b issue-[#이슈번호] master
새로 생성한 브랜치에서 작업을 완료하고, 반영
git status # git
git add . or [some-file]
git commit -m "커밋 메세지 작성"
git push origin issue-[#이슈번호]
커밋 메세지
커밋 메세지는 각자 작업한 변경사항에 대한 내용을 다른 개발자들과 공유한다는 생각을 가지고 작성해야한다. 따라서 다음과 같은 사항에 중점을 두고 작성해야한다.
다음 예시처럼 작성하는 버릇이 필요하다.
# 구조
헤더 : type(커밋의 성격)
[Black Line]
본문
[Black Line]
바닥글 : 이슈 번호 및 기타 참고 사항
# 일반
git commit -m "
feat: Logging Intercepter 기능 구현
- 서비스 계층 메서드 실행 시 파라미터, 요청자에 대한 자동 logging 구현
- interceptor 구현을 통한 유지보수성 확보
- ...생략
"
git push origin [브랜치명]
# 이슈 해결
git commit -m "
fix : Logging Interceptor 미작동에 대한 이슈 해결
- 서비스 계층에서 메서드 호출 시 interceptor가 관여하지 않던 문제 해결
- DTO 매핑 간 상속의 문제로 인한 정상적인 로직 실행이 불가능
- early return 패턴의 조건 재설정
- ...생략
close : #42
"
git push origin issue-42
헤더에 해당 하는 타입 종류는 다음과 같다.
Merge Request
는 GitHub
에서의 Pull Request
와 동일한 기능을 하는 기능으로 GitLab
에서 사용되는 용어이다.
개발자가 자신의 브랜치에서 작업한 변경 사항을 메인 브랜치나 특정 브랜치에 병합을 요청할 때 사용한다.
Merge Request 절차
1. 프로젝트 선택 > sidebar의 Merge Request 클릭
2. 새로운 MR 생성
3. source -> target 브랜치 선택
4. 요청 정보 입력
- 요청 제목
- 요청에 대한 간략한 설명
- 예시
```
Title : 로그인 기능에 OAuth 2.0 인증 방식 추가
Description
- Google과 Kakao 계정을 이용한 소셜 로그인 기능 구현
- 기존의 자체 로그인 방식과 병행 가능
- ...생략
```
- Assignee : 해당 요청을 Assign할 대상 선택
- Reviewer : 코드를 검토하고 리뷰를 요청할 사람 선택
- Create merge request 버튼 클릭
해당 MR의 변경사항에 대한 코드 확인을 통해 코드에 발생 가능한 버그가 있는지 없는지 여부를 확인
Approve
버튼을 클릭하여 MR 승인Merge
권한자가 모든 Assignee
에게 Approve
가 완료됨을 확인하면 Merge
버튼 클릭Comment
가 필요한 경우 하단에 작성 후 Comment
버튼 클릭Close merge request
클릭GitLab 리포지토리 - Plan - Issues - 우측 상단의 New Issue 클릭
이슈 작업에 대한 전용 브랜치를 생성한다. 이때 이슈 번호를 포함시켜 생성하면 어떤 이슈에 대한 브랜치인지 인식이 용이하고, 커밋 시 키워드 인식을 통한 처리가 간편해진다.
git checkout -b issue-#이슈번호
#!ex) git checkout -b issue-42
git add .
git commit -m "fixes 42 : 변경 내용 설명
- ...생략
"
git push origin issue-42
정상적으로 push가 완료되면 기존과 동일하게 머지 리퀘스트를 작성하여 이슈를 처리한다.
Git에서 커밋 메시지를 통해 이슈를 자동으로 닫거나 참조할 수 있는 키워드
fixes #이슈번호
fix #이슈번호
fixed #이슈번호
closes #이슈번호
close #이슈번호
closed #이슈번호
resolves #이슈번호
resolve #이슈번호
resolved #이슈번호
see #이슈번호
refs #이슈번호
ref #이슈번호
references #이슈번호
related to #이슈번호
part of #이슈번호
#! 병합 시 이슈 자동 닫기
git commit -m "Close #42 : 이슈 해결
- ...생략
"
#! 이슈 참조
git commit -m "Ref #42: 일부 코드 변경
- ...생략
"
두 브랜치에서 동일한 파일의 같은 부분을 수정한 후 병합하려고 할 때 발생하는 문제
오류 메세지
Auto-merging [파일명]
CONFLICT (content): Merge conflict in [파일명]
Automatic merge failed; fix conflicts and then commit the result.
해결 방법
충돌 파일 확인
git status
충돌된 파일 열기
<<<<<<< HEAD
// 현재 브랜치의 변경 내용
=======
// 병합 대상 브랜치의 변경 내용
>>>>>>> branch-name
충돌된 부분을 수동으로 수정 후 아래와 같이 확인
git status
On branch inung
nothing to commit, working tree clean
수정된 내용 스테이징(add)
git add [파일명]
커밋
git commit
필요 시 메세지까지 작성
로컬 브랜치가 원격 브랜치보다 뒤처져 있는 경우에 git push
시도 시 발생
오류 메세지
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to 'origin'
hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart.
해결 방법
원격 변경 사항 병합
git pull origin master
충돌 발생 시 Merge Conflicts
오류와 동일하게 해결
푸시
git push origin master
리베이스
를 시도하는 도중에 충돌이 발생하여 진행이 중단되는 경우
[!info]Rebase란?
Git에서 브랜치의 기반을 다른 커밋으로 변경하여 이력을 재구성하는 작업을 의미하며, 브랜치를 병합하는 또 다른 방법으로, 이력 그래프를 보다 깔끔하고 직선적으로 만들어줌Rebase의 장점
- 병합 커밋 없이 직선적인 이력을 유지 가능
- 커밋의 순서를 변경하거나 수정할 수 있음
- 코드 리뷰나 디버깅 시 이력 파악 용이
주의사항
- 공유된 브랜치에 대한 Rebase를 할 경우 이력 불일치 문제가 발생
- Rebase 후에는 기존 이력이 변경되기 때문에 원격 저장소에 강제로 푸시해야하는 위험성 존재
오류 메세지
error: could not apply commit_hash... commit message
해결 방법
충돌된 파일 확인 및 수정
git status
이후는 Merge Conflicts와 동일하게 해결
충돌 부분 수정 및 스테이징
git add [파일명]
리베이스 재개
git rebase --continue
리베이스 중단(필요 시)
git rebase --abort
로컬에서 수정한 파일이 있을 때 다른 브랜치로 체크아웃을 시도하면 발생
오류 메세지
error: Your local changes to the following files would be overwritten by checkout:
[파일명]
Please commit your changes or stash them before you switch branches.
해결방법
변경 사항 커밋
git add [파일명]
git commit -m "커밋 메세지"
브랜치 전환
git checkout branch-name
원격 브랜치에 로컬에 없는 커밋이 있을 경우 푸시를 시도하면 발생
오류 메시지
error: failed to push some refs to 'origin'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally.
해결 방법
원격 브랜치와 병합
git push origin [브랜치명]
충돌 발생 시 해결 : Merge Conflicts
와 동일하게 해결
푸시
git push origin [브랜치명]
이미 존재하는 원격 저장소를 다시 추가하려고 하는 경우 발생
오류 메세지
fatal: remote origin already exists.
해결 방법
원격 저장소 URL 변경
git remote set-url origin [변경할 URL]
원격 저장소 삭제 후 재추가
git remote remove origin
git remote add origin [추가할 URL]
운영체제 간 줄바꿈 문자 인식 차이로 인해 발생하는 경고
오류 메세지
warning: LF will be replaced by CRLF in filename.ext.
해결 방법
git config --global core.autocrlf false
작업을 커밋, 푸시하기 전 항상 원격 브랜치의 최신 변경 사항을 가져오는 습관을 가지는 것이 좋다.
git fetch origin
git rebase origin/master