-
1. 시작하기
-
2. Git의 기초
- 2.1 Git 저장소 만들기
- 2.2 수정하고 저장소에 저장하기
- 2.3 커밋 히스토리 조회하기
- 2.4 되돌리기(Undo)
- 2.5 리모트 저장소
- 2.6 Tag(Tag)
- 2.7 팁과 트릭
- 2.8 요약
-
3. Git 브랜치
- 3.1 브랜치란 무엇인가?
- 3.2 브랜치와 Merge의 기초
- 3.3 브랜치 관리
- 3.4 브랜치 Workflow
- 3.5 리모트 브랜치
- 3.6 Rebase하기
- 3.7 요약
-
4. Git 서버
- 4.1 프로토콜
- 4.2 서버에 Git 설치하기
- 4.3 SSH 공개키 만들기
- 4.4 서버 설정하기
- 4.5 공개하기
- 4.6 GitWeb
- 4.7 Gitosis
- 4.8 Gitolite
- 4.9 Git 데몬
- 4.10 Hosted Git
- 4.11 요약
-
5. 분산 환경에서의 Git
- 5.1 분산 환경에서의 Workflow
- 5.2 프로젝트에 기여하기
- 5.3 프로젝트 운영하기
- 5.4 요약
-
6. Git 도구
- 6.1 리비전 조회하기
- 6.2 대화형 명령어
- 6.3 Stashing
- 6.4 히스토리 단장하기
- 6.5 Git으로 버그 찾기
- 6.6 서브모듈
- 6.7 Subtree Merge
- 6.8 요약
-
7. Customizing Git
- 7.1 Git 설정하기
- 7.2 Git Attribute
- 7.3 Git 훅
- 7.4 정책 구현하기
- 7.5 요약
-
8. Git과 다른 VCS
- 8.1 Git과 Subversion
- 8.2 Git으로 옮기기
- 8.3 요약
-
9. Git의 내부구조
- 9.1 Plumbing 명령과 Porcelain 명령
- 9.2 Git 개체
- 9.3 Git 레퍼런스
- 9.4 Packfile
- 9.5 Refspec
- 9.6 데이터 전송 프로토콜
- 9.7 운영 및 데이터 복구
- 9.8 요약
9.5 Git의 내부구조 - Refspec
Refspec
이 책에서 리모트 브랜치와 로컬 레퍼런스로 연결하는 것이 간단하다고 배웠지만 실제로는 좀 더 복잡하다. 다음과 같은 리모트 저장소를 추가해보자:
$ git remote add origin git@github.com:schacon/simplegit-progit.git
이 명령은 origin이라는 저장소가 있고, 그 URL은 무엇인지, Fetch할 Refspec은 무엇인지를 .git/config 파일에 추가한다.
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
Refspec 형식은 +와 <src>:<dest>로 돼 있다. +는 생략 가능하고, <src>은 리모트 저장소의 레퍼런스 패턴이고, <dst>는 매핑될 로컬 저장소의 레퍼런스 패턴이다. +가 없으면 Fast-forward가 아니면 업데이트되지 않는다.
git remote add 명령은 알아서 생성한 설정대로 서버의 refs/heads/에 있는 레퍼런스를 가져다 refs/remotes/origin/ 디렉토리에 만든다. 서버에 있는 master 브랜치는 로컬에서 다음과 같이 접근해 사용할 수 있다:
$ git log origin/master
$ git log remotes/origin/master
$ git log refs/remotes/origin/master
Git은 이 세 개를 모두 refs/remotes/origin/master라고 해석하기 때문에 모두 같다.
master 브랜치만 Pull할 수 있게 만들려면 fetch 부분을 다음과 같이 바꿔준다. 그러면 다른 브랜치는 Pull할 수 없다:
fetch = +refs/heads/master:refs/remotes/origin/master
이것은 해당 리모트 저장소에 git fetch 명령이 사용하는 자동 Refspec일 뿐이다. 명령을 실행할 때 다른 Refspec이 필요하면 그냥 인자로 넘기면 된다. 리모트 브랜치 master를 로컬 브랜치 origin/mymaster로 가져오려면 다음과 같이 실행한다.
$ git fetch origin master:refs/remotes/origin/mymaster
동시에 Refspec을 여러 개 줄 수도 있다. 다음과 같이 한꺼번에 브랜치 여러 개를 가져온다:
$ git fetch origin master:refs/remotes/origin/mymaster \
topic:refs/remotes/origin/topic
From git@github.com:schacon/simplegit
! [rejected] master -> origin/mymaster (non fast forward)
* [new branch] topic -> origin/topic
여기서 master 브랜치는 Fast-forward가 아니라서 거절된다. Refspec 앞에 +를 추가하면 강제로 덮어쓴다.
설정 파일에도 Refspec을 여러 개 적을 수 있다. 항상 master와 experiment 브랜치를 함께 가져오려면 둘 다 적어 준다:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/experiment:refs/remotes/origin/experiment
하지만, Glob 패턴은 사용할 수 없다:
fetch = +refs/heads/qa*:refs/remotes/origin/qa*
그 대신 일종의 네임스페이스를 사용할 수 있다. 만약 QA 팀이 Push하는 브랜치가 있고 이 브랜치를 가져오고 싶으면 다음과 같이 설정한다. 다음은 master 브랜치와 QA 팀의 브랜치만 가져오는 설정이다:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/master:refs/remotes/origin/master
fetch = +refs/heads/qa/*:refs/remotes/origin/qa/*
이 방법으로 좀 더 복잡한 것도 가능하다. QA 팀뿐만 아니라, 일반 개발자, 통합 팀 등등이 사용하는 브랜치를 네임스페이스 별로 구분해 놓으면 좀 더 Git을 편리하게 사용할 수 있다.
Refspec Push하기
네임스페이스 별로 가져오는 방법은 끝내 주지만 어떻게 Push할까? QA 팀은 qa/ 네임스페이스에 자신의 브랜치를 어떻게 올릴 수 있을까? Push할 때도 Refspec을 사용할 수 있다.
QA 팀은 master 브랜치를 리모트 저장소에 qa/master로 Push할 수 있다:
$ git push origin master:refs/heads/qa/master
git push origin을 실행할 때마다 Git이 자동으로 Push하게 하려면 다음과 같이 설정 파일에 push 항목을 추가한다:
[remote "origin"]
url = git@github.com:schacon/simplegit-progit.git
fetch = +refs/heads/*:refs/remotes/origin/*
push = refs/heads/master:refs/heads/qa/master
다시 말하지만 git push origin을 실행하면 로컬 브랜치 master가 리모트 브랜치 qa/master로 Push된다.
레퍼런스 삭제하기
Refspec으로 서버에 있는 레퍼런스를 삭제할 수 있다:
$ git push origin :topic
Refspec의 형식은 <src>:<dst>이니까 <src>를 비우면 <dst>를 비우라는 의미가 된다. 그래서 <dst>는 삭제된다.