GIT 튜토리얼 맨페이지
gittutorial(7) Manual Page
이름
개요
설명
무엇보다도 먼저 다른 프로젝트를 가져와서 git 로 사용하는 것, 예를 들어 최신 버전을 테스트 하기 위해서, 에 관심이 있다면 git 사용자 설명서 의 처음 두 장을 시작하는 것이 좋을 것이다.
먼저, git log --graph 같은 명령에 대한 문서를 다음과 같이 얻을 수 있다는 것을 알고 있어라.
$ man git-log
시작하기 전에 먼저 사용자 이름과 이메일을 git에게 알려주는 것이 좋다. 그렇게 하는 가장 쉬운 방법은 아래와 같다.
$ git config --global user.name "Your Name Comes Here"
$ git config --global user.email you@yourdomain.example.com
새 프로젝트 끌어오기
$ tar xzf project.tar.gz
$ cd project
$ git init
git 이 다음과 같이 출력할 것이다.
.git/ 에 텅빈 git 저장소가 초기화 되었다.
$ git add .
$ git commit
이 명령은 커밋 메세지를 남기도록 프롬프트를 표시할 것이다. 이제 당신은 당신의 프로젝트의 첫 번째 버전을 git에 저장했다.
변경을 생성하기
몇몇 파일을 변경하고 변경사항을 인덱스로 추가해라.
$ git add file1 file2 file3
이제 커밋할 준비가 되었다. git-diff 에 --cached 옵션을 줘서 뭐가 커밋되었는지 볼 수 있다.
$ git diff --cached
(--cached 옵션을 빼면, git-diff 는 인덱스로 추가되지 않은 모든 변경사항을 보여줄 것이다.) 또한 git-status 로 상태에 대한 간단한 요약을 볼 수도 있다.
$ git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# modified: file1
# modified: file2
# modified: file3
#
더 수정할 것이 있으면 더 수정하고 새롭게 수정된 내용을 인덱스에 추가하라. 마지막으로 변경사항들을 커밋하라.
$ git commit
이 명령은 변경에 대한 설명을 입력하도록 하는 프롬프트를 다시 표시할 것이며, 프로젝트의 새버전에 대한 기록을 할 것이다.
한편으로, git-add 를 실행하는 대신에 먼저 다음과 같이 사용할 수 있다.
$ git commit -a
그것은 한방에 자동으로 변경된 파일들(새 파일이 아닌)을 알아채고 인덱스에 추가한 다음 커밋한다.
커밋 메세지 기록: 비록 필수는 아니더라도, 짧은 한줄(50 글자 미만)의 변경에 대한 요약으로 커밋 메세지로 시작하고 이어 빈줄을 넣고 그 뒤에 보다 자세한 설명을 넣는 것은 좋은 생각이다. 프로그램도구들은 커밋사항을 메일로 보내준다. 예를 들어 첫 줄을 제목으로 사용하고 나머지 커밋사항을 메일 내용에 채워서 보내주는 것이다.
Git 은 파일이 아닌 내용을 추적한다
많은 이력관리 시스템들은 add 명령어를 새 파일의 변경을 추적하는 것을 시작하는 명령으로 사용한다. git는 add 명령을 좀 더 단순하고 강력한 어떤 것으로 사용한다. git-add 는 새 파일이나 새로 변경된 파일들 모두에 사용된다. 그리고 두 경우에서 주어진 파일들과 변경된 내용들의 다음 커밋에 포함될 스냅샷을 인덱스에 만든다.
프로젝트 이력내역 살펴보기
아래 명령을 사용하여 변경사항에 대한 기록을 언제라도 볼 수 있다.
$ git log
만약 각 단계에서 완전한 차이점들을 보고 싶다면, 아래 명령을 사용해라.
$ git log -p
종종 변경에 대한 개요를 보는 것은 각 단계에 대한 변경을 한눈에 파악하기 좋다.
$ git log --stat --summary
분기 관리하기
하나의 git 저장소는 여러 개발 분기(branches)들을 유지 할 수 있다. "experimental" 이라는 새 분기를 만들기 위해서는 아래 명령을 수행해라.
$ git branch experimental
이제 아래와 같이 실행하면
$ git branch
모든 분기들의 목록을 얻을 수 있을 것이다.
experimental
* master
"experimental" 분기는 방금 만든것이고, "master" 분기는 자동으로 생성된 기본 분기이다. 별표(asterisk)는 현재 작업하고 있는 분기를 나타낸다. experimental 분기로 바꾸기 위해서 아래를 입력하라.
$ git checkout experimental
(파일 수정)
$ git commit -a
$ git checkout master
experimental 분기에서 만든 변경이 더이상 보이지 않음을 확인해라. master 분기로 되돌아 왔다.
master 분기에서 다른 변경을 가할 수 있다.
(파일 수정)
$ git commit -a
이 시점에서 두 분기들은 서로 다른 변경이 각각 행해져서 서로 갈라졌다. experimental 에서 만든 변경사항을 master 로 병합(merge) 하기 위해서는 아래를 실행해라.
$ git merge experimental
만약 변경들이 충돌나지 않는다면 된것이다. 만약 충돌이 있다면, 충돌을 일으키는 문제되는 파일들에 표시가 나타날 것이다.
$ git diff
위 명령은 충돌표시를 보여줄 것이다. 충돌을 해결하기 위해 파일을 수정했다면,
$ git commit -a
위 명령으로 병합결과를 커밋한다. 마지막으로...
$ gitk
이 명령은 결과 기록에 대한 훌륭한 그래픽적인 표시를 보여줄 것이다.
이 시점에서 experimental 분기를 아래와 같이 지울 수 있을것이다.
$ git branch -d experimental
이 명령은 experimental 분기의 변경사항들이 현재 분기에 이미 있다는 것을 확실히 한다.
crazy-idea 분기에서 개발하고 있는데 그것을 후회 한다면, 아래 명령으로 항상 지울 수 있다.
$ git branch -D crazy-idea
분기는 가볍고 쉽다. 따라서 어떤 것을 시도 해보는데 좋은 방법이다.
git 으로 협업하기
앨리스(Alice)가 /home/alice/project 에 있는 git 저장소로 새 프로젝트를 시작했다고 가정하고 봅(Bob)은 같은 서버장비에 홈디렉토리를 가지고 있으면서 공헌하기를 원한다고 가정하자.
봅은 아래 명령으로 시작한다.
bob$ git clone /home/alice/project myrepo
이 작업은 앨리스의 저장소와 동일한 복사본을 "myrepo" 라는 새 디렉토리에 만든다. 이 복사본은 원본 프로젝트와 동일하게 진행하는 원본 프로젝트의 기록을 그대로 복사해서 가지고 있는 것과 동일하다.
봅 어떤 변경을 하고 그것을 커밋한다.
(파일 수정)
bob$ git commit -a
(필요한 만큼 반복)
봅이 준비되면, 그는 앨리스한테 /home/bob/myrepo 에 있는 저장소로 부터 변경사항들을 끌어가라고 알려주고, 그녀는 그렇게 한다.
alice$ cd /home/alice/project
alice$ git pull /home/bob/myrepo master
"pull" 명령은 이와 같이 두 작업을 수행한다. 원격 분기로 부터 변경들을 가져오고, 현재 분기에 그것을 병합한다.
일 반적으로 앨리스는 이 "pull" 명령을 수행하기 전에 자신의 변경사항을 커밋했을 것임에 주의하라. 만약 그들이 작업을 나눠서 하는 동안에 봅의 작업이 앨리스가 한 것과 충돌이 생긴다면, 앨리스는 그녀의 작업중인 트리와 충돌을 해결할 인덱스를 그대로 사용할 것이고, 지역적(local) 변경은 충돌 해결 과정을 방해할 것이다.(git 은 여전히 가져오기를 수행하지만, 병합하기는 거절 할 것이다. --- 이런 일이 생길 경우, 앨리스는 자신의 지역적 변경을 어떠한 방법으로 없애야 하고 다시 끌어오기(pull) 을 수행해야 할 것이다.)
앨리스는 "fetch" 명령을 사용해서 병합없이 먼저 봅이 한 것을 들여다 볼 수 있다. 이것은 앨리스가 봅이 한 것을 "FETCH_HEAD" 라는 특별한 표시(symbol) 를 사용해서 봅이 한작업이 끌어올만한 것인지 결정할 수 있도록 추출한다.
alice$ git fetch /home/bob/myrepo master
alice$ git log -p HEAD..FETCH_HEAD
이 작업은 앨리스가 지역적 변경들을 커밋하지 않았어도 충분히 안전하다. HEAD..FETCH_HEAD 라는 범위 표기는 HEAD 는 제외하고 FETCH_HEAD 에 다다르는 모든 것을 보이게 하라는 의미이다. 앨리스는 이미 자신의 현재 상태(HEAD)로 온 것에 대해서 잘 알 고 있고 봅이 이 명령으로 그녀가 보지 못한 어떠한 상태(FETCH_HEAD)로 있는지에 대한 검토를 알 수 있다.
$ gitk HEAD..FETCH_HEAD
이것은 이전에 git log 에서 봤던 같은 점두개 범위 표기를 사용한다.
앨리스는 그들이 따로 작업한 이후로 둘이 동시에 뭘 했는지 보기를 원할 것이다. 그녀는 점두개의 형태 대신에 점세개의 형태를 사용할 수 있다.
$ gitk HEAD...FETCH_HEAD
This means "show everything that is reachable from either one, but exclude anything that is reachable from both of them".
이것은 "어느 한쪽으로 부터 닿을 수 있는 모든 것 하지만 각 양쪽 끝은 제외한 것을 보여준다."
이 범위 표기는 gitk 와 "git log" 모두에 사용될 수 있다는 것을 알아둬라.
봅이 한 것을 추출한 후에 급하지 않다면 앨리스는 봅으로 부터 끌어오기를 하지 않은 채 계속 작업려고 할 것이다. 봅의 내력에 앨리스가 즉시 필요한 뭔가가 있다면 앨리스는 먼저 그녀의 작업중인 일을 따로 두고 "pull" 을 하고 나서 최종적으로 그녀의 작업중인 일을 다시 결과 이력의 최상위로 올릴 것이다.
당신이 작고 친밀하게 짜여진 그룹에서 일하고 있을 때, 같은 저장소를 사용하여 되풀이하여 서로 작업하는 것은 드문일이 아니다. 간단히 원격 저장소 빨리 쓰기(remote repository shorthand)를 정의함으로써 그것을 보다 쉽게 할 수 있다.
alice$ git remote add bob /home/bob/myrepo
With this, Alice can perform the first part of the "pull" operation alone using the git-fetch command without merging them with her own branch, using:
이것으로 앨리스는 "pull" 의 첫부분만 그녀 자신의 분기와 병합하지 않고 git-fetch 명령으로 수행할 수 있다. 아래와 같이 사용하는 것은:
alice$ git fetch bob
보통으로 쓰는(longhand) 형태와 달리, 앨리스가 git-remote 로 원격 저장소 빨리 쓰기를 사용하여 봅으로부터 가져올때, 가져온 것은 원격 추적 분기에 저장된다. 이 경우에는 bob/master 가 된다. 따라서 이렇게 한 후 아래를 실행하면,
alice$ git log -p master..bob/master
봅이 앨리스의 마스터 분기로부터 가지쳐서 나온 후에 만든 모든 변경의 목록을 보여준다.
그런 변경사항들을 검증한 후에, 앨리스는 그 변경사항들을 그녀의 마스터 분기에 병합할 수 있을 것이다.
alice$ git merge bob/master
이 병합은 그녀 자신의 원격 추적 분기로부터 끌어오는것으로 동일하게 완료 될 수 있다.
alice$ git pull . remotes/bob/master
git pull은 명령줄에 어떤 인수를 주었던 간에 현재 분기로 항상 병합하는 것에 주의하라.
이후에, 봅은 앨리스의 최신 변경사항들을 아래 명령을 사용하여 그의 저장소를 최신화 할 수있다.
bob$ git pull
그가 앨리스의 저장소 경로를 줄 필요가 없다는 것에 주의해라, 봅이 앨리스의 저장소를 복제했을때, git 은 그녀의 저장소의 위치를 저장소 설정에 저장했고, 그 위치가 끌어오기에 대해 사용된다.
bob$ git config --get remote.origin.url
/home/alice/project
(git-clone 가 생성한 전체 설정은 git config -l 을 사용해서 볼 수 있고, git-config(1) 맨 페이지(man page)는 각 옵션에 대한 의미를 설명한다.)
git 은 또한 앨리스의 마스터 분기를 "origin/master" 라는 이름의 초기의 복사본으로 유지한다.
bob$ git branch -r
origin/master
봅이 나중에 다른 호스트서버로부터 작업하기로 한다면, 그는 ssh 프로토콜을 통하여 여전히 복제하기와 끌어오기를 수행할 수 있다.
bob$ git clone alice.org:/home/alice/project myrepo
다른 한편으로, git은 고유한 프로토콜을 가지고 있고 또는 rsync 나 http 를 사용할 수도 있다. 자세한 사항은 git-pull(1) 을 보라.
git은 또한 다양한 사용자들의 변경을 밀어넣는 중앙의 저장소를 가지고 CVS 스러운 형태로 사용되어 질 수도 있다. git-push(1) 과 gitcvs-migration(7) 을 보라.
이력내역 조회하기
Git 변경이력(history)은 서로 관련있는 커밋들의 연속으로 표시되어진다. 우리는 이미 git-log 명령이 그러한 커밋들의 목록을 보여줄수 있다는것을 살펴봤다. 각 git log 항목의 첫번째 줄은 또한 커밋의 이름을 보여준다.
$ git log
commit c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
Author: Junio C Hamano <junkio@cox.net>
Date: Tue May 16 17:18:22 2006 -0700
merge-base: Clarify the comments on post processing.
이 커밋에 대한 자세한 사항을 보기위해서 git-show에 이 이름을 넘겨줄수 있다.
$ git show c82a22c39cbc32576f64f5c6b3f24b99ea8149c7
그러나 커밋들을 가르키는 다른 방법들이 있다. 초기 커밋을 유일하게 구분하기에 충분히 긴, 이름의 어떤 일부분을 사용할 수 있다.
$ git show c82a22c39c # 이름의 첫 얼마간의 문자들은
# 대개 충분하다.
$ git show HEAD # 현재 분기의 꼭대기
$ git show experimental # "experimental" 분기의 꼭대기
모든 커밋은 대개 프로젝트의 이전 상태를 가르키는 하나의 "부모" 커밋을 가진다.
$ git show HEAD^ # HEAD 의 부모 보기
$ git show HEAD^^ # HEAD 의 조부모 보기
$ git show HEAD~4 # HEAD 의 고조부모 보기
병합커밋은 하나의 부모보다 많이 가질 수 있음에 주의하라.
$ git show HEAD^1 # HEAD 의 첫번째 부모보기( HEAD^ 와 같음)
$ git show HEAD^2 # HEAD 의 두번째 부모보기
커밋이름을 만들어 줄수도 있다. 이렇게 구동한 후에
$ git tag v2.5 1b2e1d63ff
1b2e1d63ff 를 언급하는 대신에 "v2.5" 라는 이름을 사용할 수 있다. 만약 이 이름을 다른사람들과 공유하려고한다면,(예를 들어 배포버전을 구분하기 위해) "꼬리표(tag)" 라는 객체를 만들어야 하고 가능하다면 그것에 사인해야 한다. 자세한 것은 git-tag(1) 을 보라.
몇몇 git 명령은 커밋을 분간하기 위해 이러한 이름들을 가질 수 있다. 예를 들어,
$ git diff v2.5 HEAD # 현재 HEAD 와 v2.5 를 비교한다
$ git branch stable v2.5 # v2.5 기반으로 "stable" 이라는 새 분기를
# 시작한다
$ git reset --hard HEAD^ # 현재 분기와 작업 디렉토리를
# HEAD^ 상태로 초기화한다
마지막 명령에 유의하라. 작업 디렉토리 안의 어떠한 변경이든지 잃어버리는것에 덧붙여, 현 분기의 모든 추가된 커밋들을 제거할 것이다. 현 분기가 그러한 커밋들을 포함하는 유일한 분기라면, 사라질것이다. 또한, 다른 개발자들에게 이력내역을 정리하는 쓸모없는 병합을 하게 만들것이기 때문에다른 개발자들이 끌어간 공개적으로 개방된 분기에 git-reset 를 사용하지 마라. 당신이 밀어넣은 변경사항들을 되돌릴 필요가 있을때는 git-revert 를 대신해서 사용해라. git-grep 명령은 프로젝트의 어떠한 버전 안에서도 문자열에 대한 검색을 수행할 수 있다. 따라서
$ git grep "hello" v2.5
"hello"의 모든 일치여부를 v2.5 에서 검색한다.
커밋 이름을 비워둔다면, git-grep 은 현재 디렉토리에서 관리되는 어떤 파일이던지 검색한다. 따라서
$ git grep "hello"
이는 git 에 의해 추적되는 파일들만 검색하는 빠른 방법이다.
많은 git 명령들은 또한 커밋들의 집합들도 받아들이고, 그것은 수많은 방법들로 지정할 수 있다. git-log 에서의 몇몇 예제이다.
$ git log v2.5..v2.6 # v2.5 와 v2.6 사이의 커밋들
$ git log v2.5.. # v2.5 이후의 커밋들
$ git log --since="2 weeks ago" # 마지막 2 주부터 지금까지의 커밋들
$ git log v2.5.. Makefile # Makefile을 수정하는 v2.5 이후의
# 커밋들
git-log 에 커밋의 "범위" 또한 줄 수 있다. 첫번째 것이 꼭 두번째보다 앞선 것일 필요는 없다. 예를 들면, 분기들의 끝인 "stable-release" 와 "master" 가 얼마간의 시간전에 공통의 커밋으로 갈라져 나왔다면,
$ git log stable..experimental
stable 분기에는 없고 experimental 분기에 있는 커밋들의 목록을 보여줄 것이다. 반면
$ git log experimental..stable
experimental 분기에는 없고 stable 분기에 있는 커밋들의 목록을 보여줄 것이다.
The git-log command has a weakness: it must present commits in a list. When the history has lines of development that diverged and then merged back together, the order in which git-log presents those commits is meaningless.
git-log 명령은 약점을 가진다. 한 목록에 커밋들을 표시해야 한다. 이력내역에 갈라졌다가 다시 하나로 합쳐진 개발의 라인들이 있을때, git-log 가 그런 커밋들을 표시하는 순서는 의미없다.
여러 공헌자들이 참여하는 대부분의 프로젝트들( 리눅스 커널 또는 git 자신 등)은 자주 병합되므로 gitk 은 그들의 이력내역을 보여주는데 있어 더 낫다. 예를 들어,
$ gitk --since="2 weeks ago" drivers/
"drivers" 디렉토리 아래 있는 변경된 파일들에 대한 최근 2 주간의 커밋들에서 아무 커밋이나 훑어 볼수 있다.(정보: "-" 나 "+" 를 누르는 동안 컨트롤 키를 눌름으로써 gitk의 글자체를 조절할 수 있다.)
마지막으로, 대부분의 파일이름을 인수로 가지는 명령들은 파일의 특정 버전을 구분하기 위해 선택적으로 어떠한 파일이름 앞에 커밋을 둘 수 있게 한다.
$ git diff v2.5:Makefile HEAD:Makefile.in
어떤 그런 파일을 보기 위해 git-show 를 또한 사용할 수 있다.
$ git show v2.5:Makefile
다음 단계들
This tutorial should be enough to perform basic distributed revision control for your projects. However, to fully understand the depth and power of git you need to understand two simple ideas on which it is based:
이 튜토리얼은 여러분의 프로젝트들에 대한 기본 분산된 이력 관리를 수행하는데 충분할 것이다. 하지만, git 의 힘과 깊이에 대해 충분히 이해하기 위해서는 git 이 기반하는 두가지 간단한 아이디어를 이해할 필요가 있다.
- The object database is the rather elegant system used to store the history of your project--files, directories, and commits.
- 객체 데이터베이스가 보다 정교한 시스템이다.
-
The index file is a cache of the state of a directory tree, used to create commits, check out working directories, and hold the various trees involved in a merge.
Part two of this tutorial explains the object database, the index file, and a few other odds and ends that you'll need to make the most of git. You can find it at gittutorial-2(7).
If you don't want to continue with that right away, a few other digressions that may be interesting at this point are:
-
git-format-patch(1), git-am(1): These convert series of git commits into emailed patches, and vice versa, useful for projects such as the linux kernel which rely heavily on emailed patches.
-
git-bisect(1): When there is a regression in your project, one way to track down the bug is by searching through the history to find the exact commit that's to blame. Git bisect can help you perform a binary search for that commit. It is smart enough to perform a close-to-optimal search even in the case of complex non-linear history with lots of merged branches.
-
gitcvs-migration(7): Git for CVS users.
SEE ALSO
gittutorial-2(7), gitcvs-migration(7), gitcore-tutorial(7), gitglossary(7), Everyday git, The Git User's Manual
GIT
Part of the git(1) suite.
Comments (0)