한방 Git 정리
Git 을 사용하면 좋은 점?
Git 은 기존의 SVN 이나 CVS 와는 달리 분산환경을 고려한 버전관리 시스템이라는 것을 기억해야 합니다.
그래서, SVN 의 경우 저장소는 모두가 사용할 수 있는 공용 원격저장소 하나 밖에 없었지만, Git 은 로컬저장소를 추가하여 개발자가 로컬저장소에서 변경작업을 자유자재로 수행한 후 정리된 최종산물만 원격저장소에 저장할 수 있도록 하였습니다.
로컬저장소에서 혼자 지지고 볶고 할 수 있도록 하려니, 아무래도 아주 다양한 기능이 필요하게 됩니다.
(Git 이 SVN 보다 기능이 훨씬 많습니다.)
혼자 할 때는 실수도 하고, 했던 것을 되돌리기도 하고, 이것저것 합치기도 하고, branch 도 다양한 형태로 빼보기도 하고, 삭제도 하고... 등등 아주 많은 것들을 시도해볼 수 있을테니 말이죠.
그래서, 기본적으로 Git 은 Branch 생성 및 삭제가 쉽고, commit 된 내용도 되돌릴 수 있으며, Branch 간의 통합 및 분리도 아주아주 쉬운 형태로 만들어져 있습니다.
이는 Git 이 각 리비전마다 변경된 내용만 기억하는 형태로 아주 가볍게 만들어졌기 때문에 가능한 것입니다.
이러한 것들이 다른 사람에게는 전혀 영향을 주지 않고 자신만의 로컬저장소에서 수행할 수 있으니 아주 편리하겠죠.
반면에 SVN 의 경우는 이러한 모든 시도들을 원격저장소 하나만을 이용하여 수행해야 하므로, 아무래도 자율성과 독립성이 떨어지므로 분산 환경에서는 적합하지 않습니다.
기억하기 좋도록 git 의 개념 및 기능을 아래 그림들로 정리해보았습니다.
복잡해 보이지만, git 은 기본적으로 다음과 같은 순서로 사용하면 됩니다.
(원격저장소를 사용하지 않는 경우는 복제 대신 그냥 로컬저장소만 생성하면 됩니다.)
- 원격저장소 생성 (github.com 을 이용하거나 직접 만들거나)
- 원격저장소를 로컬저장소로 복제 (로컬저장소 자동 생성)
- 로컬저장소에서 변경작업
- 로컬저장소 반영준비(add) - Staging
- 로컬저장소 반영(commit)
- 원격저장소 동기화(pull) 및 반영(push)
원격저장소와 로컬저장소 관리
- 변경작업은 로컬에서 수행하므로 로컬저장소를 생성하는 것이 시작임.
- 로컬저장소를 생성하는 방법은 (1)git init으로 직접 생성, (2)git clone 으로 원격저장소 복제, (3)git clone 으로 로컬저장소 복제하는 3 가지 방법이 있음.
- git clone remote_url local_dir 을 통해 원격저장소를 복제할 로컬의 복제 디렉토리명을 임의로 줄 수 있음
- git remote add 를 통해 원격저장소 URL 을 자신만의 별칭으로 등록하여 사용할 수 있음
- 원격 branch 를 생성하고자 할 때는 먼저 로컬저장소에서 branch 생성 후 이를 push 하여 동기화함
변경적용 및 되돌리기
- 변경상태 : 사용자가 파일을 수정하거나 추가한 상태 (수정 내용 자동감지)
- Stage : 사용자가 git add 를 수행하여 commit 준비가 된 변경내용을 저장하는 곳. commit 하면 stage 상태인 것만 반영됨.
- 로컬저장소 (HEAD) : commit 을 수행하여 로컬저장소에 반영
- 각 단계마다 forward, backward 방향으로 진행하기 위한 명령어가 존재함 (git status 로 확인 가능)
- git push remote_repo branch 명령은 branch 의 변경사항을 remote_repo 원격저장소로 반영
- 이미 commit 한 것도 git revert 를 이용하여 되돌릴 수 있음
브랜치 생성 및 브랜치 간 이동
- branch 간의 이동, 즉 작업 branch 의 변경은 git checkout 명령을 이용함.
- 현재 branch 리스트는 git branch 명령으로 확인 (별표모양이 가리키는 branch 가 현재 선택된 작업 branch 임)
- 신규 branch 의 생성은 master branch 에서 뿐 아니라 어떤 branch 에서도 생성가능함.
- git branch br_1 master 명령은 master branch 로부터 br_1 이라는 branch 를 생성하라는 의미임
- git tag tag_1.0 br_1 명령은 br_1 branch 로부터 tag_1.0 을 생성하라는 의미임. (tag 는 branch 를 삭제해도 남아있게 됨)
브랜치 Merge
- merge 는 branch 의 변경내용을 통째로 merge 할 수도 있고, 특정 commit 만 선택(check-pick)하여 merge 할 수도 있음.
- 만약 br_1 branch 를 master branch 로 merge 하고자 할 때는, git checkout 을 통해 master branch 로 이동 후 merge 수행. vice versa.
Commit Log 및 Diff 확인
- git log -1 은 현재 branch 의 HEAD 의 한단계 전 commit 이후부터 마지막 commit(HEAD)까지의 log 를 보여달라는 의미임.
즉, 마지막 commit 의 log 만 보여주게 됨.- git log -1..HEAD 는 git log -1 과 같은 의미. 즉, 두번째 인자가 생략되면 그 두번째 인자는 HEAD 가 생략된 것.
- HEAD^ 는 -1 과 같고, HEAD^^ 는 -2 와 같음. 범위 지정할 때 많이 사용됨.
- git log 와 git diff 는 HEAD, HEAD^, HEAD^^,... 를 이용하여 범위 지정하는 방법이 같음. 다만, git log HEAD^ 하면 처음부터 HEAD^ 까지의 로그를 보여달라는 의미이고, git diff HEAD^ 하면 HEAD^ 이래로 변경된 내용을 보여달라는 의미임.
- 현재 branch 에서 마지막 commit 이후의 모든 변경사항을 보고 싶으면 git diff HEAD 를 사용해야 함. git diff 만 사용하면 staging 된 변경은 보여주지 않기 때문에, 만약 git add 이후에 변경이 없었다면 아무것도 보여주지 않음.
NOTE : 공통 사항
- HEAD 는 현재 작업중인 branch 에서 가장 최신의 commit 을 나타내는 키워드임. git checkout branch_name 을 수행하면 HEAD 는 해당 branch 의 최종 commit 을 가리킴.
- master 는 Default branch
- origin 은 Default 원격저장소
- HEAD^ 는 HEAD 의 부모, 즉 최종 commit 의 이전 commit
- HEAD^^ 는 HEAD 의 부모의 부모
- git config --global 명령으로 시스템에서 생성하는 모든 저장소에서 기본값으로 사용하기 위한 전역값들을 설정 가능
$> git config --global user.name "cloudrain21" # commit 하면 표시되는 이름
$> git config --global user.email "cloudrain21@gmail.com" # 다른 개발자가 변경사항에 대한 문의할 때 사용
$> git config --global --list
TIP
- 누구 책임인지 찾기
$> git blame file_name # file_name 파일의 모든 변경 이력(변경자, 변경시간, 변경내용)
$> git blame -L 10,+2 file_name # file_name 파일의 10,11 번째 줄의 변경이력- git rebase 를 이용하여 commit 순서 변경, 여러개의 commit 을 하나로 합치기, 하나의 commit 을 여러개로 나누기 등이 가능함.