Git
1. Git 이란
- 버전 관리 도구
- 리눅스 창시자인 Linus Torvalds가 2005년 리눅스 커널 소스코드를 관리하던 BitKeeper가 상용으로 전환되어 버전 관리시스템을 직접 개발하였다.
- 특징 및 장점
- 빠른속도
- 분산형 저장소 지원 (여러 명이 동시에 수정하는 환경에 적합)
- 비선형적인 개발 (branch)
- 완벽한 분산
- 리눅스 커널 같은 대형 프로젝트에도 유용하다 (속도와 데이터 크기 면에서)
2. Git 설정과 명령어
- install and user configuration
Window 기준 git-scm.com에서 다운로드 후, git bash를 이용하여 user.name, user.email 설정
$ git config --global user.name "YOUR NAME"
$ git config --global user.email "YOUR EMAIL"
// 확인
$ git config user.name
YOUR NAME
$ git config user.email
YOUR EMAIL
- git init
- Git 프로젝트를 생성한다
- .git이 생성된다 (프로젝트와 버전 관리에 대한 정보가 담겨있다)
- git status
- 파일 상태를 확인한다
- Area
1) Git Directory
- 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳 (.git)
2) Working Directory
- 프로젝트의 특정 버전을 Checkout 한 영역 (현재 작업공간)
3) Staging Area(index)
- 저장할 파일들에 대한 정보를 담고 있는 파일 (.git/index)
- LifeCycle & 파일 관리 단계
1) Working Directory에서 작업하여 new file 혹은 changed file이 발생
2) commit 할 파일들을 Staging Area에 add 하여 스냅숏을 만든다 (git add).
3) Staging Area에 있는 파일들을 commit 하여 Git directory에 영구적인 스냅샷으로 저장한다 (git commit).
- 파일의 4가지 상태
1. Untracked
- Git의 관리대상에 포함되지 않는 상태
- git add를 통해 stage로 올리게 되면 git이 파일의 상태를 추적한다
2. Staged
- 로컬 데이터베이스에 저장하기 위해 등록해 놓은 상태
3. Committed
- 데이터가 로컬 데이터베이스에 안전하게 저장된 상태
4. Modified
- 수정한 파일을 아직 로컬 데이터베이스에 저장하지 않은 상태
- git add
- staging area에 추가할 파일을 지정
git add (file path)...
- 수정된 모든 파일을 추가 할 경우
git add .
git add -A
- git commit
- commit - 현재까지의 작업을 git db(.git 파일)에 기록, 저장
- 간단한 메시지를 남기며 커밋
git commit -m "add README.md file"
commit이 완료되었음을 확인 On branch master nothing to commit, working tree clean
- 자세한 메시지를 남기며 커밋(multi line)
git commit
(message 입력 후 esc -> :wq -> enter) - commit 이후
git status
로 파일 상태 확인
- git diff
- working directory와 index를 비교한다
git diff
- 커밋 간 차이점을 비교
git diff (commitA)..(commitB)
- index와 HEAD를 비교
git diff --staged
- git log
- git commit history를 조회한다
- 저장소의 시간순 커밋 히스토리
git log
- diff를 함께 보기
git log -p
- 히스토리 개수 지정
git log -Number
- 커밋 메시지 조화
git log --grep keyword
- 메시지 한 줄로 표시
git log --oneline
- 그래프 표현
git log --graph
- 그래프 + 한줄로 표현
git log --oneline --graph
- git branch
-
현 프로젝트를 건드리지 않고 새로운 기능을 추가, 실험, 버그 픽스를 하고 싶을 때 사용
-
프로젝트에 대해 새로운 형상을 만드는 행동
-
index와 working directory의 파일들이 변경된 branch를 기준으로 switching 되며 HEAD가 가리키는 branch가 변경된다
-
branch 목록 확인
git branch
-
branch 만들기
git branch (branch_name)
-
branch 삭제하기
git branch -d (branch_name) # merge 된 branch만 삭제
git branch -D (branch_name) # branch 삭제
- git checkout
- 지정한 브랜치로 변경
git checkout (branch_name)
- 새로운 브랜치를 만들고 그 브랜치로 변경
git checkout -b (branch_name)
- git merge
- branch를 합칠 때 사용
- merge 하기
git merge (target_branch_name)
- 코드가 반영될 branch에서 merge를 수행해야 한다
- Fast-forward merge
-
현재 브랜치의 커밋이 변경이 일어난 브랜치의 base commit과 동일한 경우
-
현재 브랜치의 HEAD를 target-branch의 HEAD로 이동시켜주는 것
-
fast-forward merge가 안 되는 경우 (base commit이 다른 경우) 3-way merge 사용
- 3-way merge
- 두 브랜치 간 공통의 parent commit을 이용하여 변경된 순으로 merge 수행
- merge의 결과를 별도의 commit object로 저장
- 코드가 반영된 branch가 바라보는 commit을 새로 만들어진 commit으로 변경한다
- 이때 만들어진 commit을 merge commit이라 명명한다
- git rebase
- 지정한 target branch의 base commit을 기준으로 현재 branch의 base commit을 변경
- 내부적으로는 base commit을 기준으로 현재 branch에서 추가된 변경을 하나씩 적용
- merge와 log history 자체가 변경되기 때문에 항상 좋다고 판단할 수 없다
- base commit 을 기준으로 커밋을 새롭게 만들기 때문에 상당한 conflict 상황이 발생 가능
- 작업 history가 유지되지 않게 되므로 작업 이력이 중요한 경우에는 적절하지 않음
- 개념을 잘 이해하지 못하고 사용하게 되면 작업 순서가 꼬여서 더 힘들 수 있다
3. GitHub
- git 원격 저장소를 호스팅 해주는 서비스
- 차별화된 이유로는 저장소 fork기능이 있다 (사실 가장 많이 사용하기 때문에 더 쓴다)
- git remote
- 원격 저장소 추가
git remote add (remote alias) (remote url)
- 원격 저장소 상세정보 확인
git remote show (remote alias)
- 원격 저장소 alias 변경
git remote rename (old_name) (new_name)
- 원격 저장소 url 변경
git remote set-url (remote alias) (new remote url)
- 원격 저장소 목록 확인
git remote -v
- git push
- 원격 저장소에 branch의 내용을 업로드(push)한다
git push (remote) (remote branch_name)
- git clone
- 이미 존재하는 저장소를 받아온다
- 사용 예시
- 이미 프로젝트가 진행되고 있어 remote repository가 존재하는 경우
- 새로운 개발장비에 개발 환경을 세팅해야 하는 경우
- 현재 작업 중인 directory 외에 프로젝트를 복사하고 싶은 경우
- remote 저장소를 local에 clone 하기
git clone (remote_url) [directory name] -b [branch name]
directory_name 생략 시 remote repository 명으로 생성
branch_name 생략 시 default branch로 받아옴
- git fetch
- remote 저장소에 추가된 object 들을 받아와서 local에 저장한다
git fetch (remote) (remote branch)
git fetch origin master
- git pull
- remote 저장소에 추가된 object 들을 local로 받아오면서 merge까지 수행한다 (fetch + merge)
git pull (remote) (remote branch):(local branch)
git pull origin master:master
git pull origin master
- pull request
- 프로젝트 혹은 fork 한 프로젝트에서 branch를 생성하여 개발한 기능을 origin 저장소에 merge 시켜달라고 요청하는 것
- origin 저장소 관리자가 요청자의 commit에 대한 comment를 통해 review 하거나 reject 할 수 있다
4. Tips
- .gitignore
- 필요한 소스와 설정만 관리하고 싶을 때 local환경을 위한 설정 파일들은 제외시킬 수 있다.
- https://www.gitignore.io/ - OS, IDE, 프로그래밍 언어에 대한 .gitignore 생성 가능
- .gitingore 를 설정하지 않고 이미 관리할 필요 없는 파일을 원격 저장소에 올린 경우
-
git에서 관리하지 않아도 되는 파일을 이미 올린 경우
git rm --cached
git rm -r --cached some-directory
git commit -m 'Remove ignored directory'
git push origin master -
cached를 붙이면 local에 있는 파일과 폴더들은 그대로 놔두고 원격 저장소에 있는 것들만 지우게 된다.
- non-fast-forward push 거부 해결하기
- remote branch에 새로운 커밋이 추가된 경우
git push -f
옵션으로 강제로 remote branch가 변경된 경우
1) git pull origin master를 통해 local에 다른 사람의 작업을 merge 시킨 후 push
2) fetch를 통해 데이터를 들고 온 후 rebase 시킨 후 push
- github 커밋 되돌리기
-
커밋 메시지 변경
git commit --amend
-
Working tree를 유지하며 되돌리기 (--mixed)
git reset <commit>
-
Working tree, index(staging area)를 유지하며 되돌리기
git reset --soft <commit>
-
Working tree, index 모두 되돌리기
git reset --hard <commit>