Git 특강
📚 목차
Git의 개념
‘소스 코드 나 파일’의 ‘변경 이력’을 기록하고 수정할 수 있는
‘버전 관리 시스템’의 일종
왜 필요한가?
-
파일의 버전을 이전 버전으로 되돌려
이상한 수정 등을 막을 수 있음 -
새로운 기능을 시험하고 싶지만
기존 버전을 수정하긴 좀 꺼려질 때
별도의 버전을 만들어 테스트 가능 -
여러 인원들이 작업한 다양한 버전을
하나의 버전으로 합쳐 협업 효율 Up
Git 과 GitHub?
- Git은 버전 관리 도구(프로그램)
- GitHub는 Git 저장소를 온라인에서 호스팅하고 협업 도구를 제공하는 서비스
(GitLab, BitBucket 등과 비슷)
Git의 구성요소
구성요소 | 설명 |
---|---|
Repository (저장소) | 프로젝트의 모든 버전 이력과 메타데이터를 저장하는 공간 |
Branch (브랜치) | 특정 개발 라인의 포인터, 독립적인 작업 공간 |
Commit (커밋) | 변경 이력을 기록하는 스냅샷 |
Tag (태그) | 특정 커밋에 라벨 붙이기 (주로 버전 표시) |
Remote (원격 저장소) | 네트워크로 연결된 다른 Git 저장소 |
Git은 ‘저장소’라는 큰 개념을 바탕으로
다양한 버전의 ‘브랜치’와
실제 각각의 변경 이력인 ‘커밋’과
커밋의 분류 역을 하는 ‘태그’를 통해 구성된다
이후 완성된 ‘프로젝트’를 네트워크를 통해
‘원격 저장소’로 옮겨 다양한 환경에서
프로젝트를 공유할 수 있다
Git의 내부 동작 방식
[Working Directory] ←→ [Staging Area] ←→ [Local Repository] ←→ [Remote Repository]
| | |
실제 파일 임시 저장 이력 DB
-
- Working Directory
- 실제 파일이 있는 폴더이며
git status 명령어를 통해 변경된 사안 확인 가능
- Working Directory
-
- Staging Area
- 다음 커밋에 포함할 내용을 확인한 후
git add 를 통해 파일을 등록한다
이후 git commit으로 로컬 저장소에 임시 저장
- Staging Area
-
- Local Repository
- 로컬 저장소에서 커밋들을 저장
git push 명령으로 원격 저장소로 저장소 상황을 공유 가능
- Local Repository
-
- Remote Repository
- 원격 저장소에서 다른 사람 등이
github,gitlab 등의 서비스를 이용하여 접근가능하며
다른 사람이 git pull 등을 통해 이용 가능
- Remote Repository
자주 쓰이는 명령어
명령어 | 용도 | 설명 | 사용 예시 |
---|---|---|---|
git init |
로컬 저장소 생성 | 현재 디렉터리를 새로운 Git 저장소로 초기화 (.git 폴더 생성) |
git init |
git add |
스테이징 | 변경된 파일을 Staging Area에 등록 | git add file.txt / git add . |
git commit |
커밋 생성 | 스테이징된 변경을 Local Repository에 저장 | git commit -m "메시지" |
git push |
원격 업로드 | 로컬 커밋을 Remote Repository로 전송 | git push origin main |
git clone |
원격 복제 | 원격 저장소를 로컬에 복제 | git clone https://github.com/user/repo.git |
git pull |
원격 가져오기 + 병합 | 원격 저장소의 변경 사항을 가져와 로컬에 병합 (fetch + merge ) |
git pull origin main |
git fetch |
원격 가져오기(병합 X) | 원격 저장소의 변경 사항을 가져오되, 로컬 브랜치에는 적용하지 않음 | git fetch origin |
git status |
상태 확인 | 현재 작업 디렉터리의 변경 상태와 스테이징 상태 확인 | git status |
git branch |
브랜치 관리 | 브랜치 목록 보기, 생성, 삭제 | git branch / git branch feature |
git checkout |
브랜치/커밋 이동 | 다른 브랜치로 전환 또는 특정 커밋으로 이동 | git checkout feature |
git merge |
브랜치 병합 | 현재 브랜치에 다른 브랜치 내용을 합침 | git merge feature |
- branch와 checkout - b 모두 브랜치를 생성 가능
다만 checkout은 매우 다양한 기능을 내포하고 있기에
branch가 더 안정적인 수행이 가능
(branch는 브랜치 포인터만 추가하므로, 작업 디렉터리나 스테이징 상태를 건드리지 않음)
(현재 브랜치에서 작업 중인데 바로 checkout -b 하면, 그 변경 내용이 새 브랜치로 같이 따라감)
Rebase?
특정한 브랜치의 기반(Base)를 다른 브랜치의 위에 올린다는 작업 방식
커밋 히스토리를 다시 쓰기에 merge보다 기록이 조금 더 깔끔해짐
(git rebase<브랜치>)
브랜치>
구분 | Merge | Rebase |
---|---|---|
히스토리 | 분기와 병합이 모두 기록됨 | 직선(Linear) 히스토리 |
방식 | 두 브랜치의 공통 조상부터 병합 | 내 브랜치의 커밋을 재적용 |
장점 | 히스토리 보존, 안전 | 히스토리 깔끔, 읽기 쉬움 |
단점 | 커밋 그래프 복잡해질 수 있음 | 커밋 해시 변경(공유 브랜치에 주의) |
-
- Rebase는 위험하다?
- 커밋 히스토리를 ‘재작성’하기에
‘이미 공유된’(원격에 push된) 브랜치를 Rebase하게 되면
다른 사람의 Local과 히스토리가 달라져서 충돌이 발생한다!
- Rebase는 위험하다?
-
- Rebase를 안전하게 사용하는 법
- 이미 공유된 브랜치에는 rebase를 사용하지 말 것!
(보통 release, main, dev 등은 많은 이들이 자주 사용함)
(이 때는 merge하는 것이 보통)
- Rebase를 안전하게 사용하는 법
너무 두려워하진 말자
개인 작업용 브랜치에 rebase를 통해 작업하면
깔끔하게 작업 가능
Pull Request
- GitHub 등에서 제공하는 협업 기능
- 내 브랜치의 변경 사항을 다른 브랜치 (보통 Main 등)에 병합해 달라는 요청
- git pull과는 달리 ‘코드 리뷰 + 브랜치 병합’의 역할을 겸한다
(보통 팀장 등이 진행)
방식 | 특징 |
---|---|
Merge Commit | 기본 방식, 병합 커밋이 추가됨 |
Squash and Merge | 여러 커밋을 1개로 합쳐서 병합 |
Rebase and Merge | 히스토리를 재작성해 직선화 후 병합 |
- Github UI나 웹 등에서 Pull Request를 요청해야 생성된다
- 기본적으로 브랜치 병합 이후에도 브랜치가 유지되나
설정에 따라서 삭제되는 경우도 있으니 주의
Git 충돌
Git Conflict 라 하며
협업을 한다던가 했을 때
merge 등을 한다던가 하면서 ‘흔히’ 발생하는 현상
-
- 정의
- 두 개 이상의 변경 사항이 같은 파일의 같은 위치를 수정했을 때,
Git이 자동으로 병합을 못 하고 중단하는 상황
(Git은 파일 단위가 아니라 라인 단위로 병합을 시도하기 때문에,
같은 라인을 서로 다르게 수정하면 충돌 발생)
- 정의
충돌이 나는 상황들
상황 | 예시 |
---|---|
Merge 중 | feature 브랜치와 main 브랜치에서 동일 파일의 같은 줄을 다르게 수정 |
Pull 중 | 원격에서 변경된 코드와 내 로컬 변경이 같은 위치에서 충돌 |
Rebase 중 | 내 커밋을 새 기반에 재적용하는 과정에서 같은 위치가 변경됨 |
Cherry-pick 중 | 특정 커밋을 다른 브랜치에 적용하려는데 같은 부분이 이미 수정됨 |
해결 방식들
-
자신 의 작업 부분과 수정된 파일을
비교하여 자신 or 수정된 파일을 다시 수정하고
재 커밋한 후 push하기 -
병합 취소 or rebase 취소 한 후
충돌 부분을 stash해놓고 재수정하기
Git 유용한 세부기능
Stash
작업한 내용을 임시 저장
일반적으로 branch 전환 혹은 pull 등을 받기 전에
수정 사항을 별도로 보관하여
충돌 등의 상황을 방지
- 로컬에만 저장되기에 정말 필요한 기능은 커밋을 하자
CLI 사용법
git stash # 변경 사항 임시 저장
git stash save "메모" # 설명 추가
git stash list # 저장된 stash 목록
git stash apply stash@{0} # 특정 stash 적용 (목록 유지)
git stash pop # 적용 + 목록에서 제거
git stash drop stash@{0} # 특정 stash 삭제
git stash clear # 모든 stash 삭제
github desktop에는 찾아보기 힘들지만
Git kraken, Git Fork 등에선 지원하여 편하게 사용가능
Cherry Pick
다른 브랜치에서 특정한 Commit 만
현재 브랜치로 가져오는 기능
전체적인 병합 없이 일부 변경 사항을 빠르게 적용할 때 사용
- 새로운 커밋으로 처리되기에
차후 branch끼리 병합될때, 중복 반영될 수 있음
CLI 사용법
git checkout main
git cherry-pick <커밋해시> # 단일 커밋
git cherry-pick <해시1> <해시2> # 여러 커밋
git cherry-pick A..B # A 다음부터 B까지(범위)
공통적인 문제를 빠르게 해결할 때 종종 사용하는 기능
Revert
지정한 커밋을 되돌리는 새로운 커밋을 생성
이력은 그대로 유지하면서 해당 변경만 취소
협업 환경에서 이미 원격에 반영된 변경을 취소할 때 안전
git revert <커밋해시> # 단일 커밋 되돌리기
git revert <해시1>..<해시2> # 범위 되돌리기
git revert -n <해시1> <해시2> # 여러 개를 한 번에 revert(커밋은 따로)
로컬이라면 기록을 깔끔히 남기기 위해 Reset 등을 고려할 수 있으나
이미 Push하였다면 Revert가 안전한 선택
- revert를 revert 하려는 등의 시도는 하지 말자
롤백을 하려면 새로이 커밋을 파는것이 더 직관적
Reset
브랜치의 HEAD 포인터를 다른 커밋으로 이동시키는 명령
동시에 Staging Area(Index)와 Working Directory의 상태를 어떻게 할지도 선택할 수 있음
주로 커밋 취소, 스테이징 해제, 브랜치 되돌리기 등에 사용
- Reset의 모드들
모드 | HEAD 이동 | Staging Area(Index) | Working Directory | 설명 |
---|---|---|---|---|
--soft |
✅ 이동 | ❌ 유지 | ❌ 유지 | 커밋만 취소, 변경은 그대로 스테이징 상태 유지 |
--mixed (기본) |
✅ 이동 | ✅ 초기화 | ❌ 유지 | 커밋 취소 + 스테이징 해제, 파일 수정 내용은 남김 |
--hard |
✅ 이동 | ✅ 초기화 | ✅ 초기화 | 커밋/스테이징/작업 내용 모두 해당 커밋 상태로 복원(변경사항 전부 삭제) |
Revert vs Rebase vs Reset
| 기능 | 목적 | 히스토리 재작성 | 원격 푸시 방식 | 원격 안전도 | 전형적 사용 사례 | 주요 주의사항 |
| ——– | ————————— | —————– | ———————————– | ————- | —————————- | ——————————————— |
| revert
| 특정 커밋을 취소(반대 변경을 새 커밋으로 추가) | ❌ 아니오 | 일반 git push
| ⭐⭐⭐⭐⭐ (매우 안전) | 이미 배포된 버그 커밋 되돌리기, 협업 브랜치 롤백 | merge 커밋은 -m
부모 지정 필요, 다수 커밋 revert 시 충돌 가능 |
| rebase
| 기반을 최신으로 옮겨 히스토리 정리/직선화 | ✅ 예 | 보통 git push --force-with-lease
필요 | ⭐⭐ (주의) | 개인 작업 브랜치 정리, PR 올리기 전 정돈 | 공유/원격 브랜치에 금지(합의 없는 재작성은 사고 유발) |
| reset
| 브랜치 포인터를 과거/다른 커밋으로 이동 | ✅ 예 (특히 --hard
) | 보통 git push --force-with-lease
필요 | ⭐ (위험) | 로컬에서 실수 정리, 임시 커밋 되돌리기 | 원격/공유 브랜치에 거의 금지. 이력 삭제로 동기화 붕괴 |
Git LFS
Git이 기본적으로 처리하기 어려운 대용량 파일(예: .uasset, .umap)들을
외부 저장소에 따로 관리하고, Git에는 해당 파일의 경로 정보만 저장하는 방식
(Large File Storage)
(저장소 용량 증가, 속도 저하, 충돌 위험 등을 어느 정도 완화)
Unreal과 같은 환경에선 Git LFS가 중요하다
.uasset
,.umap
등 대용량 파일은 변경사항을
비교(diff)하거나 병합(merge)할 수 없기 때문에 충돌 방지가 중요- Git LFS는 이러한 파일을 효과적으로 추적하고 관리해줍니다.
다만 용량 관리에 주의할 것
GitHub 무료 계정은 LFS 저장소와
트래픽 제한(기본 1GB 스토리지, 월 1GB 전송) 있음
→ 초과 시 유료 플랜 필요
설정 방법
- 설치
sudo apt install git-lfs (Git bash)
- 파일 추적
git lfs track "*.png" git lfs track "*.mp4"
이렇게 해놓고 git Desktop이나 kraken 등에서 push해도 좋다
댓글남기기