Git
git의 필요성
- 동시에 같은 파일을 여러 사람이 변경할 때, 어떤 파일이 최신 버전인지, 어떤 부분이 변경되었는지를 쉽게 확인할 수 있도록 도와주는 버전 관리 시스템
- git을 사용해 소스 코드가 변경된 이력을 확인하고, 특정 시점에 저장된 버전과 비교하거나, 해당 시점으로 돌아갈 수 있음
기본 명령어
git clone
- 원격 저장소에 있는 내용을 로컬에 저장
- git clone <원격 저장소 주소> 형태로 사용
branch
- git branch : 모든 branch와 현재 branch가 무엇인지 알 수 있음
- git branch -r : 원격 저장소의 branch 목록을 알 수 있음
- git branch <이름> : 이름을 가진 새로운 branch 생성
- git checkout <이름> : checkout 뒤의 이름을 가진 branch로 이동
- git checkout -b <이름> : b 옵션을 통해 branch를 생성함과 동시에 현재 branch 변경
- git checkout <file 이름> : 로컬 file의 변경을 되돌림
- git merge <이름> : 현재 branch에 이름에 해당하는 branch를 병합
- git branch -d <이름> : 이름에 해당하는 branch를 삭제
- git push <branch 이름> : 원격 저장소에 로컬의 branch를 등록
- git push <저장소 이름> --delete <branch 이름> : 원격 저장소에 있는 branch 삭제
git status
- 작업 디렉토리(working directory)와 스테이징 영역(staging area)를 확인하기 위해 사용
- 3가지 영역으로 구분
- Changes to be commited : 스테이징 영역에 넘어가 있는 변경 내용
- Changes not staged for commit : working directory에 있는 변경 내용
- Untracked files : working directory에 있는 git이 관리한 적이 없는 파일
- staging area
- commit 하기 전 대기 상태
- git add 명령어를 통해 working directory에 있는 내용을 staging area로 이동시킬 수 있음
- git commit 명령을 할 경우 staging area에 있는 내용만 기록
git add
- git add는 다음 commit을 기록할 때까지 변경한 부분을 모아놓기 위해 사용
- git add <이름> : working directory 중 이름에 해당하는 변경 부분을 staging area로 이동시킴
- git add . : 현재 디렉토리의 보든 변경 내용을 staging area로 이동시킴
- git add -A : 모든 변경 내용을 staging area로 이동시킴
- git add -p : 모든 변경 내용을 하나씩 확인하여 staging area로 이동시킬 것인지 결정할 수 있음
git commit
- staging area에 있는 변경 내용을 기록함
- git commit -m <메시지> : 변경 내용을 -m 옵션을 통해 메시지로 적을 수 있고, -m을 사용하지 않을 경우 새 페이지로 이동해 기록할 수 있음
- git commit -S
- commit 내용을 RSA 키를 사용해 인증할 수 있음
- 사전에 키 등록 과정을 마쳐야 사용할 수 있고 gitconf를 수정해야 함
- 개인적으로 키의 비밀번호를 입력하는 과정을 거쳐야 해서 commit 전 gpg --clearsign 를 사용해 비밀번호를 입력한 후 commit을 해야 함 - 이는 사용하는 사람마다 다를 수 있음
- commit의 경우 로컬 저장소에 변경 이력을 남기기 위해 사용
git push
- 로컬 저장소의 변경 부분을 원격 저장소에 업로드
- push를 실행하면 로컬 저장소와 원격 저장소가 동일한 상태가 됨
- git push <저장소 이름> <branch 이름> : 저장소 이름은 보통 origin을 사용하고, 저장소와 branch 모두 원격 저장소와 branch를 뜻함
- git remote를 통해 정확한 저장소 이름을 알아낼 수 있음
- push의 경우 원격 저장소에 변경 이력을 남기기 위해 사용
git pull
- 원격 저장소의 내용을 로컬 저장소로 가져와 자동으로 병합 작업 실행
- fetch + merge 작업
git fetch
- 원격 저장소의 내용을 병합은 하지 않고 가져옴
- 원격 저장소의 변경 내용을 확인하고 로컬 데이터와 병합은 하고 싶지 않을 경우 사용
- FETCH_HEAD branch에 변경 내용을 가져옴
- 현재 branch에서 FETCH_HEAD를 병합할 경우 pull과 같은 작업
git reset
- commit을 취소하고 이전으로 돌아가고 싶을 때 사용
- soft vs hard
- git reset --soft : 현재 코드를 살리고 이전 commit으로 되돌아감
- git reset --hard : 아예 이전의 상태 및 코드로 돌아감
- git reset HEAD^ : 바로 이전 커밋으로 돌아감
- git log를 통해 돌아가고 싶은 commit을 찾은 후 git reset <commit 번호>를 입력해 원하는 commit으로 버전을 되돌릴 수 있음
git stash
- 현재 상태를 스택에 저장하고, 다른 작업이 끝나면 pop해 불러올 수 있음
- A branch에서 작업을 하던 중 commit 하기 전 B branch에서 작업을 처리해야 할 경우 git stash를 사용해 A branch의 변경 내역을 기록하고, B branch로 checkout 해 작업을 이어나갈 수 있음
- git stash : stash 영역에 변경 내역을 기록
- git stash pop : 마지막에 저장한 코드를 불러옴
- git stash list : stash의 내역을 보여줌
git rebase
Git에서 branch를 병합하는 방법은 merge와 rebase가 있는데 merge의 경우 안전하고, 쉽다. 그냥 git merge hotfix
처럼 입력하면 충돌이 생기면 충돌이 생겼다고 알려주고, 충돌이 없을 경우 완전히 merge 된다. 하지만 한 branch에서 여러 개의 커밋을 한 개로 묶고 싶을 경우 merge로는 이를 할 수 없다(내가 알기로는).
여기서 도움이 되는 것이 git rebase
다. rebase를 하면 합치고 싶은만큼 커밋을 합쳐서 하나로 만들고, 이를 병합하려는 branch의 head에 가져다 놓을 수 있다.
$ git checkout hotfix
$ git rebase -i @~5 // 최근 5개의 커밋을 합침
위를 실행하면 아래와 같은 창을 볼 수 있을 것이다.
pick a03c578 initial commit
pick d587ff3 헤더 수정
pick f3f5f1f hotfix 수정
pick c30397a 테스트
pick e795cd1 완료
# Rebase a03c578..e795cd1 onto a03c578
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out
위는 vi로 열리는데 가장 위의 initial commit의 pick은 고정이고, 아래부터 pick을 하단의 커맨드 중 원하는 것으로 바꿔주면 되는데, 커밋을 하나로 합치고 싶은 경우라면 s로 바꿔주면 된다.
이후 :wq
로 나가면 또 한번 vi가 열린다.
# This is a combination of 5 commits.
# The first commit's message is:
initial commit
# This is the 2nd commit message:
헤더 수정
# This is the 3rd commit message:
hotfix 수정
# This is the 4th commit message:
테스트
# this is the 5th commit message:
완료
여기서는 이제 자기가 원하는 커밋 메시지를 작성하면 되는데 dd
명령을 사용하면 한 줄을 삭제할 수 있다.
이제 이후 master branch로 checkout 한 다음, merge를 진행하면 5개의 커밋 메시지가 삽입되는 대신, 한 개의 커밋 메시지가 삽입된다.
추가 팁
ID, PW 입력하지 않고 push
$ git config --global credential.helper 'cache --timeout=864000'
- timeout에 설정한 시간만큼 push 할 때 비밀번호를 묻지 않음
- timeout 될 때마다 입력해주어야 함
원격 저장소의 branch 가져오기
$ git checkout --track <원격저장소branch이름>
이렇게 입력하면 원격 저장소의 branch를 가져오고 자동 checkout함
원격 저장소 commit 되돌리기
$ git reset --hard <commit ID>
$ git push -f origin <branch name>
commit ID의 상태로 원격 저장소의 commit 상태를 되돌릴 수 있음