Git 간단하게 살펴보기
해당 포스트는 Inflearn '초급 개발자의 성장을 위한 핵심 개발 클래스 강의자료' 강의에서 다루는 강의 내용을 정리한 것이다.
Git의 4가지 작업 공간
S#01. Workspace
일반적으로 우리가 작업하는 공간을 말하며, git을 쓰기 이전 처음 상태에 해당한다.
S#02. Index (Staging Area)
변경되는 모든 파일 및 폴더들을 추적하는 공간으로, git add 명령어를 통해 workspace에 있는 작업물을 해당 공간으로 보낼 수 있다. 최종적으로 커밋하고자 하는 작업물들을 해당 공간에 두면 되며, 한 번 index에 올라갔던 파일들은 git에서 계속 추적한다.
S#03. Local Repository
최종적으로 커밋된 작업물드이 놓이게 되는 공간으로, git commit 명령어를 통해 index에 있는 파일들을 해당 공간으로 보낼 수 있다.
S#04. Remote Repository
Git 호스팅 공간으로, 인터넷으로 연결된 별도의 공간이다. 최종 작업물들을 여기에 저장하고 다른 사람들과 공유하며, 여러 사람이 협업할 때 해당 공간을 사용한다. git push 명령어로 local repository에 있는 작업물을 해당 공간으로 보낼 수 있으며, git fetch나 git pull 명령어로 해당 공간의 작업물들을 local repository로 가져올 수 있다 (GitHub, BitBucket 등)
* git clone vs fetch vs pull
git clone: Remote Repo를 Local Repo + Workspace로 복사
git fetch: Remote Repo의 변경 사항을 Local Repo로 가져옴 (Workspace에 반영 x)
git pull: Remote Repo의 변경 사항을 Local Repo와 Workspace에 반영
Git branch 사용법
Branch란 ?
사용자가 독립적으로 작업을 진행할 수 있도록 돕는 작업 흐름으로, 하나의 브랜치는 독립된 workspace, index, local repo, remote repo 공간을 가진다. 사용자는 브랜치 (기본: main)위에 새로운 브랜치를 생성해 독립된 작업 공간을 만들 수 있다.
1. 각 개발자는 메인 브랜치에서 각자 자신이 작업할 새로운 브랜치를 만들며, 이 공간에서 작업한다.
2. 코드 리뷰(Pull request)를 받지 않는 경우, 작업 완료 후 작업한 브랜치를 메인 브랜치에 머지한다. Local repo의 메인 브랜치가 업데이트 되었으므로, remote repo에도 푸시하여 최신 내역을 공유한다.
2.1 코드 리뷰를 받는 경우, 작업 완료 후 remote repo에 자신이 작업한 브랜치를 푸시한다. 이후, remote repo에서 메인 브랜치로 pull request를 한다. 협업하는 다른 개발자에게 리뷰를 받고, 리뷰 및 합의가 된 후에는 메인 브랜치에 머지한다.
Branch 실습
브랜치를 새로 만드는 명령어는 다음과 같다. 보통 switch 명령어는 branch 간의 이동을 할 때 사용하지만, -c 옵션을 통해 브랜치를 새로 생성하는 것도 가능하다.
git swith -c [branch 이름]
git branch # 브랜치 조회
생성한 브랜치에서 add, commit등을 수행하고, 작업 내용을 메인 브랜치에 합쳐보자.
git switch main
git merge [branch 이름] # fast forward 방식
git push
해당 방식은 코드 리뷰를 받지 않은 병합 방식으로, 일반적인 회사에서 사용하기에는 리스크가 있다. 머지 이전으로 내역을 돌리고, 코드 리뷰를 받기 위한 방식으로 코드를 병합해보자.
git reset --hard HEAD^
git switch [branch 이름] # git switch - 사용시 이전 브랜치로 돌아감
git push origin [branch 이름]
이렇게 수행하면 GitHub 웹 페이지에서, Pull requests를 생성할 수 있다. 리뷰어들이 코드를 보고 메인 브랜치와 머지를 했다면, 로컬 레포에서 변동 내역을 동기화시켜주어야 한다.
git pull origin main
Log 확인하기
HEAD는 가장 현재 커밋을 가리키는 심볼릭 링크(포인터)로, 보통 커밋 ID 대신 HEAD 포인터를 많이 활용한다.
HEAD의 이전 커밋들을 확인하고 싶을 땐 HEAD ^ 혹은 HEAD ~ 으로 포인팅이 가능하다.
e.g) HEAD로부터 3개 전의 Commit 접근: HEAD^^^, HEAD~3
커밋들에 대한 확인은 log 명령어를 통해 볼 수 있다.
git log
git log --oneline # 한줄로 간단하게 보여줌
git log -n n # 최근 커밋 n개만 보여줌
git log --oneline --decorate --graph # 그래프 형태로 보여줌 (시각적)
show 명령어를 통해서 커밋의 변경 사항들을 확인할 수 있는데, show 명령어 같은 경우 뒤에 태그를 붙여야 한다.
git show
git show HEAD^
git show HEAD~1
git reflog를 통해 git reset, git rebase 명령어로 삭제된 커밋을 포함한 모든 커밋 히스토리를 볼 수 있다(git log에서는 확인 불가). 해당 명령어는 커밋 해시 값도 반환하기 때문에 reset을 통해 이전 커밋으로 되돌아가는 것도 가능하다.
git reflog
git reset --hard [hash id] # git reset --hard 278c94b
Git에서 reflog는 HEAD가 변경될 때 마다 그 이력을 저장하는데, 가장 최근 변경이 "HEAD@{0}"이고, 그 이전은 HEAD@{1}, HEAD@{2}와 같은 식으로 숫자가 증가한다.
작업 내역 되돌리기
M#01 git reset --hard {커밋 ID}
특정 커밋 시점으로 돌아갈 때, 해당 커밋 이후 만들어진 모든 작업물을 삭제한다. 현재 작업한 파일들을 모두 날리고 이전 커밋 상태로 완전히 돌아가고 싶을 때 사용하며, 기존에 작성하던 변경사항들도 전부 날아가기 때문에 주의가 필요하다.
M#02 git reset --mixed {커밋 ID}
특정 커밋 시점으로 돌아갈 때, 해당 커밋 이후 모든 작업물은 workspace 공간에 unstaged 상태로 남게되며, git reset 명령어의 기본 옵션이다.
M#03 git reset --soft {커밋 ID}
특정 커밋 시점으로 돌아갈 때, 해당 커밋 이후 모든 작업물은 Index 공간에 staged 상태로 남게된다.
M#04 git restore {파일 경로}
특정 파일의 변경사항을 제거하고 HEAD 기준으로 되돌리고 싶을 때 사용한다. git reset --hard와 비슷한 효과를 보이지만 git restore는 새 파일의 변경사항을 되돌리지 않는 반면, reset은 새 파일의 변경사항도 되돌린다.
M#05 git revert {커밋 ID}
이는 이전 커밋의 변경사항을 되돌리고자 할 때 사용하는 명령어로, 10개의 커밋 중 3번째 커밋(a file 수정)이 오류를 발생시키고 있다고 가정해보자. 이를 hotfix 상황이라 부르며, 해당 커밋의 변경사항을 이전으로 되돌리면 된다. 해당 명령어를 사용하면 기존 커밋들을 지우지 않고, 현재 commti 위로 이전 commit 내용을 다시 되돌리는 commit을 생성한다.
변경 사항 임시저장하기
git stash는 수정 내용을 임시 저장하는 명령어로, 브랜치 간 전환을 할 때 가장 많이 사용한다. main 브랜치로부터 my-branch를 만들어 이 브랜치로 전환해서 작업하고 있었다고 했을 때, 작업 도중 요구사항으로 인해 main 브랜치로 전환해야 할 일이 생겼다고 해보자. 이때 변경사항을 커밋으로 남기기에는 아직 애매한 상황이라면, stash 명령어를 활용해 임시저장하면 된다.
git stash # git stash -m "message"
git stash list
git switch main
main 브랜치에서 해야 할 일을 다 마치고, 이제 다시 my-branch로 돌아가 작업을 진행한다고 해보자. 이때는 브랜치 이동 후 git stash pop 명령어를 통해 아까 스택에 넣어뒀던 작업내역을 다시 불러오면 된다.
git switch my-branch
git stash pop # git stash pop {id}
git stash apply 또한 pop 명령어처럼 작업내역을 불러오는데, pop 명령어의 경우 스택에서 작업 내역을 제거하는 반면 git stash apply 명령어의 경우 스택에서 작업 내역을 유지한채 불러오게 된다. 여전히 스택에 남아있기 때문에, 다른 곳에서 넣어둔 작업내역을 다시 사용할 수 있다.
git switch -
git stash apply
이외에도 해당 강의에서는 이전에 쌓인 커밋들을 변경하는 방법(ammend), 브랜치를 머지할 때 머지 커밋을 남기지 않는 방법(squash merge, rebase merge), 다른 브랜치에 있는 커밋을 내 브랜치로 가져오는 방법을 다루고 있으니 관심있는 사람들을 수강해보는 것을 추천한다.