Git 핵심 개념과 명령어 정리
2024년 09월 02일Git의 기본 개념, 자주 사용하는 명령어를 정리했습니다.
1 Git 기본 개념
저장소 구조
- 로컬 저장소 : 개발자의 컴퓨터에 있는 저장소
- 독립적인 작업 가능
- 오프라인 상태에서도 버전 관리 가능
- 원격 저장소 : 서버에 위치한 저장소
- (ex: Github, Gitlab, Bitbucket)
- 팀 협업을 위한 중앙 저장소
- 코드 백업 및 공유
- 코드 리뷰, 이슈 트래킹 등 추가 기능
Git 설정
# 시스템 전체 설정
git config --system user.name "username"
# 현재 사용자 전역 설정
git config --global user.name "username"
# 현재 저장소만 설정
git config user.name "username"
# 설정 확인
git config --get user.name
git config --list
Git 저장소 시작
git init [directoy]
- directory가 없으면 현재 디렉토리에서 init
- 깃 저장소 디렉터리에 서브 디렉터리
.git
이 생성됨.- → 여기서 버전 관련 내용이 깃 프로그램에 의해 알아서 기록됨.
저장소 공간
- Working Directory(작업 디렉토리)
- 실제 작업하는 파일들이 있는 디렉토리
- Staging Area(스테이징 영역 / index)
- 개별 파일의 변경 내용을 기록하는 임시 공간
- 커밋 수행전에 스테이지 영역에 기록해야함.
- Local Repository(깃 저장소)
- .git 폴더에 저장되는 커밋된 파일들의 저장소
- 버전이 만들어지고 관리되는 공간으로 커밋을 수행하여 특정 시점에서 스테이지의 스냅숏을 저장함.
- 시간 흐름에 따라 커밋이 쌓이면서 커밋 이력이 관리됨.
깃 파일의 상태 변화
- 처음 파일을 생성하면
untracked(추적되지 않음)
상태 git add
명령을 사용하여 스테이지에 올려야함staged(스테이지에 올라옴)
상태 파일은 git commit 명령으로 . 깃저장소에 스냅샷이 기록됨.- 커밋 수행 직후 파일은
unmodified(수정 전)
상태가 됨 - 이 팡리을 수정하면
modified(수정함)
상태가 됨. - 수정된 파일의 변경 내용을 기록하려면 스테이지에 올린 후 커밋할 수 있음.
git add
: 스테이지에 파일을 추가하는 명령
git add files
: 해당 파일들git add .
: 현재 + 하위 디렉터리 모두git add (--a | A)
: 현재 디렉터리 모두
git commit
: 깃 저장소에 커밋 이력을 남기는 명령
git commit -m "message"
git commit -a -m "message"
: 스테이지에 올리면서 커밋을 함께 실행- *신규 생성한 파일은 이렇게 불가. 일단 스테이지에 먼저 따로 올려야함.
git log
: 커밋 이력을 확인하는 명령
git log
: 현재 브랜치의 커밋정보git log --oneline
: 커밋 정보를 1개당 한줄로 표시git log (--patch | -p)
: 커밋 정보의 파일의 변경 내용 표시git log --graph
: 여러 브랜치를 그래프로 이력 표시git log --reverse
: 오래된 커밋부터 표시git log --all
: 모든 브랜치의 커밋 이력 표시git log --n
: 최근 n개 이력만git show HEAD
git show
commitID
:HEAD
/commitID
이 가리키는 커밋의 기본정보를 표시하고 이전 커밋과의 차이 표시
HEAD
: 현재 작업중인 브랜치를 가리킴
checkout : 버전 여행
-
HEAD를
- 1)현재 브랜치의 과거 커밋
- 2)다른 브랜치의 최신 커밋으로 이동할 수 있음
-
git status
명령 결과에서 작업 폴더가 깨끗(clean)해야 checkout 가능- clean? = 디렉토리-스테이지-저장소 3개 저장공간 내용이 동일한 상태 = 커밋 직후
- checkout 으로 과거 커밋으로 이동하면
분리된(detached) HEAD
상태가 됨.
-
HEAD가 이동하면 상응하는 커밋 내용으로 작업 영역, 인덱스가 업데이트 됨.
-
HEAD는 시간 이동을 위한 수단으로 활용가능
HEAD~
HEAD^
: 직전 커밋HEAD~~
HEAD~2
HEAD^^
: 전전 커밋- 예시
git checkout HEAD~ //직전 커밋으로 이동 git checkout - //직전 브랜치(이전 HEAD)위치로 이동 git checkout _branch_ //다른 브랜치로
버전 / 커밋간 파일 비교
-
git diff
commit1 commit2
_:_commit1을 기준으로 commit2가 어떻게 변경되었는지 표시git diff HEAD~ HEAD //직전을 기준으로 현재가 어떻게 변경되었는지 표시
2 브랜치
브랜치 : 특정 목록을 가진 독립적 개발 흐름.
-
기본 브랜치 (master 혹은 main)이 주어짐
-
기능 추가, 개선, 버그 수정을 위해 각각 별도 브랜치를 만들어서 작업함.
-
브랜치는 커밋 이력을 가지며, 브랜치 이름은 커밋이력에서 최신 커밋을 가리킴.
-
예시
git init myProject git branch -m master //현재 브랜치 이름을 master로 수정 git commit -m A git branch -m main //이름을 다시 main으로 수정 git log
Branch 확인과 생성
git branch / git branch —list
: 브랜치 이름 나열git branch -v
: 브랜치 마다 상세한 정보도 나열git branch newBranchName
: 새로운 브랜치 생성 (HEAD는 이동하지 않음)git switch newBranchName
: 새로운 브랜치 생성 + HEAD 이동git checkout -b newBranchName
: 새로운 브랜치 생성 + HEAD 이동
작업브랜치 이동
- git switch branchName / git checkout branchName : 브랜치 이동
- git switch : 직전 브랜치로 HEAD 이동
예시
git branch develop //브랜치 생성
git branch
git switch develop
이전 커밋으로의 이동
git checkout [-d] HEAD~
: HEAD가 분리되어 HEAD~(이전)로 이동git switch -d HEAD~
: HEAD가 분리되어 HEAD~로 이동git switch -d [commit]
: HEAD가 분리되어 commit으로 이동
병합 여부 확인
git branch -—merged
현재 작업 브랜치 기준으로 병합된(도달 가능한) 브랜치 표시
git branch -—no-merged
현재 작업 브랜치 기준으로 병합되지 않은(도달 불가) 브랜치 표시
git branch -—merged branchName
주어진 브랜치 기준으로 병합된(도달 가능한) 브랜치 표시
git branch -—no-merged branchName
주어진 브랜치 기준으로 병합되지 않은(도달 불가) 브랜치 표시
브랜치 삭제
git branch -d branchName
이미 명합된 브랜치 삭제
git branch -D branchName
이미 병합되지 않았더라도 브랜치를 삭제 (*위험)
브랜치 병합
fast-forward 병합
- 자손 브랜치(최신)의 커밋 이력이 조상 브랜치(원래의 브랜치)의 커밋 이력을 모두 포함한 경우에 가능
- 즉, 조상 브랜치를 자손. ㅡ랜치 위치로 이동하는 것
- 순서
- 먼저 조상브랜치로 HEAD 이동하고
git merge childBranch
- 예시
- main이 커밋 1-2-3 을 갖고있고
- dev가 여기서 따온 후에 1-2-3-4-5 로 4-5를 추가했다면
- dev(자손이) 조상(main)을 이력을 다 포함하고 있기 때문에 fast-forward가능.
- 결과로는 실제로 합친다기보다 1-2-3-4-5 커밋이력에 main이 3 / dev가 5에 위치하고 있었던 것에서 → main을 5로 이동시키는 것.
3-way 병합
한 커밋에서 갈라져 나온 두 브랜치를 병합함
- 어느 시점 이후 대상 커밋의 변경을 현재 브랜치에 병합
- 병합을 의미하는 새로운 커밋이 생김(커밋 메세지 입력)
- (HEAD→현재브랜치)가 새로운 커밋으로 이동됨
git merge -m “message” branch
강제 3-way 병합
- fast-forward 병합이 가능하나 3-way 병합을 수행.
- 3-way가 되니 추가 커밋이 생김
git merge --no-ff branchName -m "message"
Squash 병합
3way 병합이지만, 병합만 진행하고 커밋 직전까지만 수행함. 추후에 커밋 해야함
브랜치 병합 충돌 / 해결
- 충돌
- 두 브랜치에서 같은 파일-같은 위치를 동시에 수정한 경우
- 자동 3way 병합을 할 수 없어서 충돌이 발생함
- 해결
- vi / IDE에서 개발자가 해결해야함
3 Stash
stash
마지막 커밋 이후 → 변경된 작업 영역, 스테이지 영역을 임시 저장
- 작업중에 급하게 작업 브랜치를 바꿔야할 때 사용
git checkout
/git switch
명령은 작업 폴더가 깨끗한 상태에서 가능하기에
→ git stash
로 스택 구조의 임시 저장소(stash)에 저장함
→ 작업 영역 / 스테이지 영역은 마지막 커밋과 동일한 깨끗한 상태가 됨.
주의!!
-
추적되지 않은 파일(add 안한) 도 저장하려면!
→
—-include-untracked
/-u
사용하기 -
마지막 커밋 이후 변경이 없으면 stash 할게 없으니 안됨.
-
git stash [-m message]
: 스태시 저장 -
git stash push [-m message]
: 위와 동일 -
git stash save [message]
: 위와 동일 -
git stash -u
: 작업영역의 추적되지 않는 파일(=아직 스테이지 안올라온 파일도) 저장 -
git stash list
: 저장된 목록 확인 -
git stash show [stash@{n}]
최종 커밋 - 스태시 저장된 내용 비교해서 보여줌. 명시한 스태시가 없으면 최신 저장항목과 비교git stash show stash@0
: 최신 stash랑 비교git stash show stash@1
: 2번째 stash와 비교
stash 적용 (복원)
git stash apply [stash@{n}]
- 기본적으로 작업 영역으로 복원된다. 원래 스테이지에 있었다고 하더라도.
- 복원할 때 스테이지 영역까지 올라가도록 복원시키려면
--index
옵션 사용 (스테이지=인덱스)
stash 삭제
-
git stash drop [stash@{n}]
: 특정 스태시 삭제 -
git stash claer
모두 삭제 -
git stash pop [stash@{n}]
: 적용하면서 삭제
Stash 활용
git stash branch branchName : 새로운 브랜치 만들고, 기존 브랜치의 최신 스태시를 적용(apply함)
기타
git clean
: 추적되지 않는 파일 삭제
n
: 실제로 제거하지는 않고 어떤 파일이 제거되는지 확인f
: 강제 삭제 실행d
: 디렉토리도 포함하여 삭제
Reset
- HEAD위치를 이전 특정 커밋으로 되돌리는 기능. 버전을 과거로 완.전.히. 되돌리는 것
- 해당 커밋 이후의 커밋 이력은 삭제됨.
- 새로운 커밋은 생성되지 않음
3가지 모드
git reset --hard
commit
- 작업 디렉토리 / 스테이징 영역 / Git 저장소 모두를 지정한 커밋 상태로 되돌림.
git reset [--mixed]
commit
- Git 저장소 / 스테이징 영역만 되돌림.
- 작업 디렉토리는 현재 상태 그대로 유지
git reset
의 디폴트 옵션
git reset --soft
commit
- Git 저장소만 되돌림.
- 스테이지 영역, 작업 디렉토리는 현재 상태 유지.
git reset --hard HEAD~
//이전 커밋으로 돌아감
git reset --hard ORIG_HEAD
//돌아왔던 가장 최신 커밋으로 돌아감.
Revert
- 최근 커밋부터 차례로 이전 커밋을 취소할 때 사용.
- 리셋(--hard 옵션)과 유사하나 기존 커밋을 삭제하지 않고, 커밋 이력을 남겨둔 채 ‘커밋 취소’를 의미하는 새로운 커밋 생성.
- → 협업시 권장되는 방식
git revert
commit
git revert
commit
--no-edit
: 커밋 메세지를 “Revert - 주어진 커밋 메세지”로 기록됨
주의
- 작업 폴더가 깨끗한 상태야 revert 수행 가능. (reset은 그냥 가능했는데)
- 한번에 한 커밋만 취소하므로 → 충돌이 발생하지 않으려면 최신 커밋부터 순차적으로 여러 번 취소
- 충돌이 발생한다면
- 충돌된 파일을 찾아 수정
- 수정한 파일을 인덱스(스테이지)에 등록
- git revert --continue로 명령을 계속 진행
git reset --hard HEAD : HEAD니까. 뒤로 돌리는 건 아니고 작업 영역 stage에 있는 것들 날리는 것.
리버트의 연속 적용
순서대로 리버트 수행하여 과거의 커밋으로 이동
git revert HEAD HEAD~ HEAD~2
- 취소(revert) 커밋이 3개가 추가됨.
범위로도 가능, 위와 동일한 다른 표현
git revert HEAD~3…
(*HEAD3의 다음부터~ )
git revert HEAD~3…HEAD
고급 활용
- 여러 커밋 취소를 하나의 커밋으로 만들기
git revert --no-commit HEAD~3..HEAD
- 변경사항 확인 및 필요시 수정
git commit -m "여러 커밋 취소"
- 여러 개의 커밋을 취소해서 스테이지에 쌓아놓고, 커밋 한개만 생성할수 있음
- revert는 한개 커밋마다 한개 revert 커밋이 생겨서 별로인데, 이렇게 하면 좋음.
권장 사항
- 개인 브랜치에서는 reset 사용해도 됨.
- 공유 브랜치에서는 revert 사용 권장
- 작업 전 항상 현재 상태 확인
git status
TAGS
GIT