GitQuickStart
목차 |
서론
연구소에서 git를 이용한 소스 코드 관리를 추진하고자 한다. git는 기능도 막강하고 무엇보다 분산 Version Control이 가능하여 개인별로 자유로운 버전 관리와 offline 모드 지원이 막강하다.
git 설치 및 설정
Linux 환경
Linux 환경에서는 기본적으로 git 프로그램이 설치되어 있다. 만약 설치되어 있지 않다면 Ubuntu 의 경우 다음 패키지를 설치한다.
$ sudo apt-get install git
git을 이용한 commit시 사용되는 기본적인 설정 정보인 사용자 이름과 이메일, commit log 메시지를 작성하는 editor를 등록한다. 설정한 정보는 사용자 홈의 .gitconfig 파일에 기록된다.
$ git config --global user.name "KyungWoon Cho" $ git config --global user.email "cezanne@clunix.com" $ git config --global core.editor vi
git repository 접근 하기 위해서는, 자신의 ssh public key를 등록하여 repository에 대한 접근 권한을 획득해야 한다. ssh public key를 만드는 방법은 SSH 사용법 안내 페이지를 참고
SSH config 설정
보통 ssh client 설정에서 X11 forward는 하지 않도록 다음과 같이 설정한다.
Host git 192.168.12.11 ForwardX11 no
Windows 환경
- msysgit(Git for windows) 설치, http://code.google.com/p/msysgit/
- 설치시 행종결자 처리에 대한 옵션을 설정하는데, 3번째 옵션인 변환을 하지 않는 것이 바람직
- TortoiseGit 설치
- Putty용 private key 파일인 ppk 파일 생성. 생성 과정은 PPKGen을 참조
- Git clone시에 생성한 ppk 파일을 지정하여 git clone
git help
- git 명령 목록은 단순히 git을 입력 하면된다.
- git 명령 --help 를 하면 manual page 화면이 수행된다.
git clone
- git clone 명령은 svn checkout과 유사한 명령이다.
- 원격 git repository로 부터 로컬에 저장소를 만든다.
$ git clone git@git:testing testing
- git(192.168.12.11) 서버로 부터 testing repository를 로컬상의 testing 폴더를 작업 폴더로 만든다.
- git은 SVN과 달리 repository에 있는 전체 저장소를 가져온다.
- repository의 하위 폴더 일부를 가져오는 방법은 없다. 대신 submodule 기능을 통하여 하위 repository를 만들수 있다.
git add
- git은 repository에 commit을 하기전 저장공간인 staging area를 둔다.
- 신규 생성된 파일이나 기존에 존재하던 파일이라도 수정한 내용을 commit하기 위해서는 반드시 add 과정을 거쳐야 한다.
$ git add test.c
- 추가할 항목은 여러개나 glob 패턴도 가능하다.
$ git add test.c blah*.txt
- 이미 추가한 항목에 대해서는 별도로 오류를 발생하지 않고, 무시한다.
git status
- git status 는 현재 작업 폴더의 상태를 나타낸다.
- svn과 달리 상태 화면이 좀 복잡하다.
$ git status # On branch master nothing to commit (working directory clean)
위의 경우는 폴더에 어떠한 파일도 없거나 수정한 것이 없는 경우
$ git status # On branch master # Untracked files: # (use "git add <file>..." to include in what will be committed) # # mytest.c nothing added to commit but untracked files present (use "git add" to track)
mytest.c가 존재하지만, git으로 관리되지 않는 상태이다.
$ git add mytest.c $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # new file: mytest.c #
위의 mytest.c를 staging area에 add한 경우의 status 출력 결과이다.
기존 repository에 있는 파일을 수정한 경우라면 다음과 같은 출력 결과가 표시된다.
# On branch master # Changes not staged for commit: # (use "git add <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # modified: test.c # no changes added to commit (use "git add" and/or "git commit -a")
위의 경우는 기존에 존재하는 파일인 test.c를 수정한 경우의 status 출력 결과이다.
이 파일을 add하면 다음과 같은 출력결과가 표시된다.
# On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: test.c #
git diff
편집한 내용을 확인시에는 git diff를 사용한다.
$ git diff diff --git a/test.c b/test.c index 71ce22d..a32214c 100644 --- a/test.c +++ b/test.c @@ -1,3 +1,5 @@ +#include <stdio.h> + void main() {
git diff는 staging area에 포함되지 않은 내용에 대해서만 diff 를 수행한다. 만약 staging area에 있는 내용에 대해서 diff를 원한다면 다음과 같이 수행한다.
git diff --cached
특정 파일의 diff만을 보고자 한다면 해당 파일을 인자로 부여한다.
git commit
commit 과정
git commit은 staging area에 있는 변경 내용을 repository로 commit한다.
$ git commit [master 1bf0f40] test is just test 1 file changed, 2 insertions(+)
git commit을 수행하면 commit log를 입력하는 editor가 수행되고, editor를 저장후 종료하면 commit 과정이 완료된다. 아래는 commit 수행시 log 입력 화면예시이다.
this is test # Please enter the commit message for your changes. Lines starting # with '#' will be ignored, and an empty message aborts the commit. # On branch master # Your branch is ahead of 'origin/master' by 1 commit. # # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # modified: test.c #
'this is test'라는 로그메시지를 입력한 화면이며, 아래쪽 #이 표시된 영역은 단순 설명으로서 commit log에 반영되지 않는다.
- editor 편집을 취소하면 commit 과정은 자동 취소된다.
- staging area에 반영된 내용만 commit된다. staging area에 반영되지 않는 편집된 내용은 commit되지 않음을 유의해야 한다.
- commit도 일부 파일만 가능하며, 인자 없이 수행하면 staging area에 있는 전제 내용이 commit된다.
만약 staging area를 거치지 않고, 변경되거나 삭제된 파일을 일괄적으로 commit하고자 한다면 다음 명령을 수행한다.
$ git commit -a
- 이 명령은 새로 생성된 파일(untracked file)을 자동으로 commit하지는 않는다.
- staging area에 있는 변경파일도 동시에 commit된다.
- 일부 파일만 일괄적으로 적용할 수는 없으며, 전체 변경되거나 삭제된 파일을 대상으로 적용된다.
commit 전 확인 사항
협업시 공백라인이나 공백문자에 의해 변경되는 코드들은 매우 성가신 일이다. commit 전 이러한 부분이 없는지 반드시 아래 명령으로 확인을 하도록 한다.
$ git diff --check
변경사항들은 논리적인 단위로 구분해서 commit을 하도록 한다. 여러개의 이슈가 섞인 형태의 commit은 지양한다. git은 이를 위한 다양한 기능들을 제공한다.
commit 메시지는 해당 작업을 잘 표현할 수 있게끔 작성한다. 첫줄에 35글자 이하로 해당 작업 한줄로 요약한다. (영문의 경우라면 50이하) 좀 더 상세한 메시지는 한줄 공백 후 상세 내용을 작성한다.
좋은 commit 메시지의 예시
Short (50 chars or less) summary of changes More detailed explanatory text, if necessary. Wrap it to about 72 characters or so. In some contexts, the first line is treated as the subject of an email and the rest of the text as the body. The blank line separating the summary from the body is critical (unless you omit the body entirely); tools like rebase can get confused if you run the two together. Further paragraphs come after blank lines. - Bullet points are okay, too - Typically a hyphen or asterisk is used for the bullet, preceded by a single space, with blank lines in between, but conventions vary here
git log
commit log를 확인하는 방법은 git log 를 이용한다. git log는 터미널 화면에 맞는 만큼만 출력해서 보여준다.
$ git log
diff를 함께 보고자 하는 경우는 다음과 같이 수행한다. 양이 많은 경우 자동으로 paging 기능을 제공한다.
$ git log -p
최근 몇개만을 보고자 하는 경우는 다음과 같이 수행한다.
$ git log -2
git push
- git 분산 버전 관리도구이다. commit을 하더라도 원격지 repository에 반영되지 않고, 로컬 repository에 commit이 된 것이다.
- 로컬 repository에 반영된 commit 내용을 원격지 repository에 반영하기 위해서는 git push 명령을 수행한다.
$ git push Counting objects: 5, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 298 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To git@git:testing e0ab7f0..1bf0f40 master -> master
작업 내용 되돌리기
마지막 commit한 내용을 수정하고자 한다면 다음과 같이 수행한다.
$ git commit --amend
- 위 명령은 staging area에 있는 변경된 내용을 마지막 commit에 적용한다.
- 마지막 commit 내용중 변경되지 않는 부분은 영향을 받지 않는다.
- 만약 변경된 내용이 없다면 단순히 commit log만을 수정하는 것이다.
staging area에 있는 내용을 다시 되돌리는 경우에는 다음과 같이 명령을 수행한다.
$ git reset HEAD <file>...
수정된 내용을 되돌리는 방법(svn revert와 같은 효과)은 다음과 같다. (마이너스 2번)
$ git checkout -- <file>
파일 삭제 및 이동
파일을 repository상에서 삭제하고자 하는 경우 먼저 파일을 삭제한다.
$ rm test.c $ git status # On branch master # Changes not staged for commit: # (use "git add/rm <file>..." to update what will be committed) # (use "git checkout -- <file>..." to discard changes in working directory) # # deleted: test.c # no changes added to commit (use "git add" and/or "git commit -a")
파일 삭제 후 상태를 확인하면 deleted로 표시되며, 이를 staging area에 반영한다.
$ git rm test.c rm 'test.c' $ git status # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # deleted: test.c #
이후 commit을 하면 test.c 삭제가 repository에 반영된다.
만약 디스크상에서 파일을 삭제하지 않고, 단순히 repository에서 파일을 제거하고자 한다면 다음과 같이 수행한다.
$ git rm --cached test.c
파일 삭제 없이 test.c 파일이 삭제되었음을 staging area에 반영한다. 이후 commit시 repository에 반영된다.
이름을 변경하고자 하는 경우에는 다음과 같이 수행한다.
$ git mv test.c test1.c # On branch master # Changes to be committed: # (use "git reset HEAD <file>..." to unstage) # # renamed: test.c -> test1.c #
git remote
원격 저장소 정보를 열람하는 방법은 아래와 같다.
$ git remote origin
이것은 단순히 원격 저장소명만을 나열한다. 좀 더 자세한 정보를 보고자 한다면
$ git remote show origin
git pull
원격지의 repository에서 update하는 방법은 다음과 같다.(svn update와 같은 효과)
$ git pull
이 명령은 원격 저장소로 부터 변경된 내용을 로컬 저장소로 업데이트하며, 변경된 내용을 현재의 작업 폴더에 merge한다. 만약 conflict가 발생한다면 아래와 같은 오류 메시지가 나타나며, merge가 되지 않는다.
Updating 1bf0f40..80387cd error: Your local changes to the following files would be overwritten by merge: test.c Please, commit your changes or stash them before you can merge. Aborting
만약 merge하지 않고, 원격저장소로 부터 변경분만 로컬저장소에 저장한다면 다음과 같이 수행한다.
git fetch
tagging
git은 tagging 기능을 다양한 방식으로 제공한다.
- lightweight tag: 간편하게 tagging 하는 방식.
- annotated tag: tagging에 대한 부가설명을 추가할 수 있는 방식
$ git tag
위 명령은 tag 목록을 열람할 수 있다. 패턴으로 tag 목록을 열람할 수도 있다.
$ git tag -l 'v1.3*'
light-weight tag를 추가하는 방법은 다음과 같다.
$ git tag mytag
annotated tag를 추가하는 방법은 다음과 같다.
$ git tag -a mytag
이 경우는 tagging message를 입력하는 editor가 구동된다. annotated는 tagger와 날짜, log등이 기록된다.
tag 정보는 git push시 자동으로 전달되지 않으며, 다음과 같이 명시적으로 tag 정보를 원격 저장소에 전달하여야 한다.
$ git push origin mytag