1+ ---
2+ ### DO NOT EDIT! Generated by script/update-book2.rb
3+ category: book
4+ section: documentation
5+ subsection: book
6+ sidebar: book
7+ book:
8+ language_code: ko
9+ chapter:
10+ title: Git 도구
11+ number: 7
12+ section:
13+ title: Bundle
14+ number: 12
15+ cs_number: '7.12'
16+ previous: book/ko/v2/Git-도구-서브모듈
17+ next: book/ko/v2/Git-도구-Replace
18+ title: Git - Bundle
19+ url: "/book/ko/v2/Git-도구-Bundle.html"
20+ ---
21+ < h2 id ="_bundling "> Bundle</ h2 >
22+ < div class ="paragraph ">
23+ < p > 앞에서 Git 데이터를 네트워크를 거쳐 전송하는 일반적인 방법(HTTP, SSH등)을 다루었었다. 일반적으로 사용하진 않지만, 꽤 유용한 방법이 하나 더 있다.</ p >
24+ </ div >
25+ < div class ="paragraph ">
26+ < p > Git에는 “Bundle” 이란 것이 있다. 데이터를 한 파일에 몰아넣는 것이다.
27+ 이 방법은 다양한 경우 유용하게 사용할 수 있다.
28+ 예를 들어 네트워크가 불통인데 변경사항을 동료에게 보낼 때,
29+ 출장을 나갔는데 보안상의 이유로 로컬 네트워크에 접속하지 못할 때,
30+ 통신 인터페이스 장비가 고장났을 때,
31+ 갑자기 공용 서버에 접근하지 못할 때, 누군가에게 수정사항을 이메일로 보내야 하는데 40개 씩이나 되는 커밋을 < code > format-patch</ code > 로 보내고 싶지 않을 때를 예로 들 수 있다.</ p >
32+ </ div >
33+ < div class ="paragraph ">
34+ < p > 바로 이럴 때 < code > git bundle</ code > 이 한 줄기 빛이 되어준다.
35+ < code > bundle</ code > 명령은 보통 < code > git push</ code > 명령으로 올려 보낼 모든 것을 감싸서 한 바이너리 파일로 만든다. 이 파일을 이메일로 보내거나 USB로 다른 사람에게 보내서 다른 저장소에 풀어서(Unbundle) 사용한다.</ p >
36+ </ div >
37+ < div class ="paragraph ">
38+ < p > 간단한 예제를 보자.
39+ 이 저장소에는 커밋 두 개가 있다.</ p >
40+ </ div >
41+ < div class ="listingblock ">
42+ < div class ="content ">
43+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git log
44+ commit 9a466c572fe88b195efd356c3f2bbeccdb504102
45+ Author: Scott Chacon <
[email protected] >
46+ Date: Wed Mar 10 07:34:10 2010 -0800
47+
48+ second commit
49+
50+ commit b1ec3248f39900d2a406049d762aa68e9641be25
51+ Author: Scott Chacon <
[email protected] >
52+ Date: Wed Mar 10 07:34:01 2010 -0800
53+
54+ first commit</ code > </ pre >
55+ </ div >
56+ </ div >
57+ < div class ="paragraph ">
58+ < p > 이 저장소를 다른 사람에게 통째로 보내고 싶은데 그 사람의 저장소에 Push 할 권한이 없거나, 그냥 Push 하고 싶지 않을 때, < code > git bundle create</ code > 명령으로 Bundle을 만들 수 있다.</ p >
59+ </ div >
60+ < div class ="listingblock ">
61+ < div class ="content ">
62+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git bundle create repo.bundle HEAD master
63+ Counting objects: 6, done.
64+ Delta compression using up to 2 threads.
65+ Compressing objects: 100% (2/2), done.
66+ Writing objects: 100% (6/6), 441 bytes, done.
67+ Total 6 (delta 0), reused 0 (delta 0)</ code > </ pre >
68+ </ div >
69+ </ div >
70+ < div class ="paragraph ">
71+ < p > 이렇게 < code > repo.bundle</ code > 이라는 이름의 파일을 생성할 수 있다. 이 파일에는 이 저장소의 < code > master</ code > 브랜치를 다시 만드는 데 필요한 모든 정보가 다 들어 있다.
72+ < code > bundle</ code > 명령으로 모든 Refs를 포함하거나 Bundle에 포함할 특정 구간의 커밋을 지정할 수 있다.
73+ 이 Bundle을 다른 곳에서 Clone 하려면 위의 명령처럼 HEAD Refs를 포함해야 한다.</ p >
74+ </ div >
75+ < div class ="paragraph ">
76+ < p > < code > repo.bundle</ code > 파일을 다른 사람에게 이메일로 전송하거나 USB 드라이브에 담아서 나갈 수 있다.</ p >
77+ </ div >
78+ < div class ="paragraph ">
79+ < p > 혹은 < code > repo.bundle</ code > 파일을 일할 곳으로 어떻게든 보내놓으면
80+ 이 Bundle 파일을 마치 URL에서 가져온 것처럼 Clone 해서 사용할 수 있다.</ p >
81+ </ div >
82+ < div class ="listingblock ">
83+ < div class ="content ">
84+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git clone repo.bundle repo
85+ Cloning into 'repo'...
86+ ...
87+ $ cd repo
88+ $ git log --oneline
89+ 9a466c5 second commit
90+ b1ec324 first commit</ code > </ pre >
91+ </ div >
92+ </ div >
93+ < div class ="paragraph ">
94+ < p > Bundle 파일에 HEAD Refs를 포함하지 않으려면 < code > -b master</ code > 옵션을 써주거나 포함시킬 브랜치를 지정해줘야 한다. 그렇지 않으면 Git은 어떤 브랜치로 Checkout 할지 알 수 없다.</ p >
95+ </ div >
96+ < div class ="paragraph ">
97+ < p > 이제 새 커밋 세 개를 추가해서 채운 저장소를 다시 원래 Bundle을 만들었던 저장소로 USB든 메일이든 Bundle로 보내 새 커밋을 옮겨보자.</ p >
98+ </ div >
99+ < div class ="listingblock ">
100+ < div class ="content ">
101+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git log --oneline
102+ 71b84da last commit - second repo
103+ c99cf5b fourth commit - second repo
104+ 7011d3d third commit - second repo
105+ 9a466c5 second commit
106+ b1ec324 first commit</ code > </ pre >
107+ </ div >
108+ </ div >
109+ < div class ="paragraph ">
110+ < p > 먼저 Bundle 파일에 추가시킬 커밋의 범위를 정해야 한다.
111+ 전송할 최소한의 데이터를 알아서 인식하는 네트워크 프로토콜과는 달리 Bundle 명령을 사용할 때는 수동으로 지정해야 한다.
112+ 전체 저장소를 Bundle 파일로 만들 수도 있지만, 차이점만 Bundle로 묶는 게 좋다. 예제에서는 로컬에서 만든 세 개의 커밋만 묶는다.</ p >
113+ </ div >
114+ < div class ="paragraph ">
115+ < p > 우선 차이점을 찾아내야 Bundle 파일을 만들 수 있다.
116+ < a href ="{{< relurl "book /ko/v2/ch00/_commit_ranges" > }}"> 범위로 커밋 가리키기</ a > 에서 살펴본 대로 숫자를 사용하여 커밋의 범위를 지정할 수 있다.
117+ 원래 Clone 한 브랜치인 master에는 없던 세 개의 커밋을 얻어내려면 < code > origin/master..master</ code > 또는 < code > master ^origin/master</ code > 파라미터를 쓰면 된다.
118+ < code > log</ code > 명령으로 시험해볼 수 있다.</ p >
119+ </ div >
120+ < div class ="listingblock ">
121+ < div class ="content ">
122+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git log --oneline master ^origin/master
123+ 71b84da last commit - second repo
124+ c99cf5b fourth commit - second repo
125+ 7011d3d third commit - second repo</ code > </ pre >
126+ </ div >
127+ </ div >
128+ < div class ="paragraph ">
129+ < p > 이제 Bundle 파일에 포함할 커밋을 얻었으니 묶어보자.
130+ < code > git bundle create</ code > 명령에 Bundle 파일의 이름과 묶어 넣을 커밋의 범위를 지정한다.</ p >
131+ </ div >
132+ < div class ="listingblock ">
133+ < div class ="content ">
134+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git bundle create commits.bundle master ^9a466c5
135+ Counting objects: 11, done.
136+ Delta compression using up to 2 threads.
137+ Compressing objects: 100% (3/3), done.
138+ Writing objects: 100% (9/9), 775 bytes, done.
139+ Total 9 (delta 0), reused 0 (delta 0)</ code > </ pre >
140+ </ div >
141+ </ div >
142+ < div class ="paragraph ">
143+ < p > 이제 디렉토리에 < code > commits.bundle</ code > 파일이 생겼다.
144+ 이 파일을 동료에게 보내면 원래의 저장소에 일이 얼마나 진행되었든 간에 파일 내용을 적용할 수 있다.</ p >
145+ </ div >
146+ < div class ="paragraph ">
147+ < p > 이 Bundle 파일을 동료가 받았으면 원래 저장소에 적용하기 전에 무엇이 들어 있는지 살펴볼 수 있다.
148+ 우선 < code > bundle verify</ code > 명령으로 파일이 올바른 Git Bundle인가, 제대로 적용하는 데 필요한 모든 히스토리가 현재 저장소에 있는가 확인한다.</ p >
149+ </ div >
150+ < div class ="listingblock ">
151+ < div class ="content ">
152+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git bundle verify ../commits.bundle
153+ The bundle contains 1 ref
154+ 71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master
155+ The bundle requires these 1 ref
156+ 9a466c572fe88b195efd356c3f2bbeccdb504102 second commit
157+ ../commits.bundle is okay</ code > </ pre >
158+ </ div >
159+ </ div >
160+ < div class ="paragraph ">
161+ < p > 만약 앞에서 Bundle 파일을 만들 때 커밋 세 개로 만들지 않고 마지막 두 커밋으로만 Bundle 파일을 만들면 커밋이 모자라기 때문에 최초에 Bundle을 만들었던 저장소에 새 Bundle 파일을 합칠 수 없다.
162+ 이런 문제를 < code > verify</ code > 명령으로 확인할 수 있다.</ p >
163+ </ div >
164+ < div class ="listingblock ">
165+ < div class ="content ">
166+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git bundle verify ../commits-bad.bundle
167+ error: Repository lacks these prerequisite commits:
168+ error: 7011d3d8fc200abe0ad561c011c3852a4b7bbe95 third commit - second repo</ code > </ pre >
169+ </ div >
170+ </ div >
171+ < div class ="paragraph ">
172+ < p > 제대로 만든 Bundle 파일이라면 커밋을 가져와서 최초 저장소에 합칠 수 있다.
173+ 데이터를 가져올 Bundle 파일에 어떤 브랜치를 포함하고 있는지 살펴보려면 아래와 같은 명령으로 확인할 수 있다.</ p >
174+ </ div >
175+ < div class ="listingblock ">
176+ < div class ="content ">
177+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git bundle list-heads ../commits.bundle
178+ 71b84daaf49abed142a373b6e5c59a22dc6560dc refs/heads/master</ code > </ pre >
179+ </ div >
180+ </ div >
181+ < div class ="paragraph ">
182+ < p > 앞에서 < code > verify</ code > 명령을 실행했을 때도 브랜치 정보를 확인할 수 있다.
183+ 여기서 중요하게 짚을 부분은 < code > fetch</ code > 명령이나 < code > pull</ code > 명령으로 가져올 대상이 되는 브랜치를 Bundle 파일에서 확인하는 것이다.
184+ 예를 들어 Bundle 파일의 master 브랜치를 작업하는 저장소의 'other-master' 브랜치로 가져오는 명령은 아래와 같이 실행한다.</ p >
185+ </ div >
186+ < div class ="listingblock ">
187+ < div class ="content ">
188+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git fetch ../commits.bundle master:other-master
189+ From ../commits.bundle
190+ * [new branch] master -> other-master</ code > </ pre >
191+ </ div >
192+ </ div >
193+ < div class ="paragraph ">
194+ < p > 이런 식으로 작업하던 저장소의 'master' 브랜치에 어떤 작업을 했든 상관없이 Bundle 파일로부터 커밋을 독립적으로 'other-master' 브랜치로 가져올 수 있다.</ p >
195+ </ div >
196+ < div class ="listingblock ">
197+ < div class ="content ">
198+ < pre class ="highlight "> < code class ="language-console " data-lang ="console "> $ git log --oneline --decorate --graph --all
199+ * 8255d41 (HEAD, master) third commit - first repo
200+ | * 71b84da (other-master) last commit - second repo
201+ | * c99cf5b fourth commit - second repo
202+ | * 7011d3d third commit - second repo
203+ |/
204+ * 9a466c5 second commit
205+ * b1ec324 first commit</ code > </ pre >
206+ </ div >
207+ </ div >
208+ < div class ="paragraph ">
209+ < p > < code > git bundle</ code > 명령으로 데이터를 전송할 네트워크 상황이 여의치 않거나 쉽게 공유할 수 있는 저장소를 준비하기 어려울 때도 히스토리를 쉽게 공유할 수 있다.</ p >
210+ </ div >
211+ < div id ="nav "> < a href ="{{< previous-section >}} "> prev</ a > | < a href ="{{< next-section >}} "> next</ a > </ div >
0 commit comments