@git / git-reference / commits / f8ded16

branch, checkout, merge docs

Scott Chacon committed Jun 4, 2010 at 13:24 UTC f8ded1604a2f64a6d4766fcab85234736940dc92
2 files changed +469 -1
_layouts/reference.html
+1 -1
@@ -58,8 +58,8 @@
58 <h3><a href="/branching">Branching and Merging</a></h3>
59 <ul>
60 <li><a href="/branching/#branch">branch</a></li>
61 + <li><a href="/branching/#branch">checkout</a></li>
62 <li><a href="/branching/#merge">merge</a></li>
62 - <li><a href="/branching/#checkout">checkout</a></li>
63 <li><a href="/branching/#log">log</a></li>
64 <li><a href="/branching/#reset">reset</a></li>
65 </ul>
branching/index.html new
+468
@@ -0,0 +1,468 @@
1 +---
2 +layout: reference
3 +---
4 +
5 +<div class="box">
6 + <h2>
7 + <span class="docs">
8 + <a target="new" href="http://progit.org/book/ch2-2.html">book</a>
9 + </span>
10 + Branching and Merging
11 + </h2>
12 + <div class="block">
13 + <p>Branching in Git is one of my favorite features. If you have used other
14 + version control systems, it's probably helpful to forget most of what you
15 + think about branches - in fact, it may be more helpful to think of them
16 + practically as <i>contexts</i> since that is how you will most often be
17 + using them. When you checkout different branches, you change contexts
18 + that you are working in and you can quickly context-switch back and forth
19 + between several different branches.
20 + </p>
21 +
22 + <p class="nutshell">
23 + <b>In a nutshell</b> you can create a branch with
24 + <code>git branch (branchname)</code>, switch into that context with
25 + <code>git checkout (branchname)</code>, record commit snapshots while
26 + in that context, then can switch back and forth easily. When you switch
27 + branches, Git replaces your working directory with the snapshot of the
28 + latest commit on that branch so you don't have to have multiple directories
29 + for multiple branches. You merge branches together with
30 + <code>git merge</code>. You can easily merge multiple times from the same
31 + branch over time, or alternately you can choose to delete a branch
32 + immediately after merging it.
33 + </p>
34 +
35 + </div>
36 +</div>
37 +
38 +<div class="box">
39 + <h2>
40 + <span class="docs">
41 + <a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-branch.html">docs</a> &nbsp;
42 + <a target="new" href="http://progit.org/book/">book</a>
43 + </span>
44 + <a name="branch">git branch</a>
45 + <span class="desc">list, create and manage working contexts</span>
46 + </h2>
47 +
48 + <br/>
49 +
50 + <h2>
51 + <span class="docs">
52 + <a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-checkout.html">docs</a> &nbsp;
53 + <a target="new" href="http://progit.org/book/">book</a>
54 + </span>
55 + <a name="checkout">git checkout</a>
56 + <span class="desc">switch to a new branch context</span>
57 + </h2>
58 +
59 + <div class="block">
60 + <p>The <code>git branch</code> command is a general branch management tool
61 + for Git and can do several different things. We'll cover the basic ones
62 + that you'll use most - listing branches, creating branches and deleting
63 + branches. We will also cover basic <code>git checkout</code> here which
64 + switches you between your branches.
65 + </p>
66 +
67 + <h4>
68 + git branch
69 + <small>list your available branches</small>
70 + </h4>
71 +
72 + <p>Without arguments, <code>git branch</code> will list out the local
73 + branches that you have. The branch that you are currently working on will
74 + have a star next to it and if you have
75 + <a href="http://progit.org/book/ch7-1.html#colors_in_git">coloring turned on</a>,
76 + will show the current branch in green.
77 + </p>
78 +
79 +<pre>
80 +$ git branch
81 +* <span class="green">master</span>
82 +</pre>
83 +
84 + <p>This means that we have a 'master' branch and we are currently on it.
85 + When you run <code>git init</code> it will automatically create a 'master'
86 + branch for you by default, however there is nothing special about the name -
87 + you don't actually have to have a 'master' branch but since it's the default
88 + that is created, most projects do.
89 + </p>
90 +
91 + <h4>
92 + git branch (branchname)
93 + <small>create a new branch</small>
94 + </h4>
95 +
96 + <p>So let's start by creating a new branch and switching to it. You can do
97 + that by running <code>git branch (branchname)</code>.
98 +
99 +<pre>
100 +$ git branch testing
101 +$ git branch
102 +* <span class="green">master</span>
103 + testing
104 +</pre>
105 +
106 + <p>Now we can see that we have a new branch. When you create a branch this
107 + way it creates the branch at your last commit so if you record some commits
108 + at this point and then switch to 'testing', it will revert your working
109 + directory context back to when you created the branch in the first place -
110 + you can think of it like a bookmark for where you currently are. Let's see
111 + this in action - we use <code>git checkout (branch)</code> to switch the
112 + branch we're currently on.
113 + </p>
114 +
115 +<pre>
116 +<b>$ ls</b>
117 +README hello.rb
118 +<b>$ echo 'test content' > test.txt</b>
119 +<b>$ echo 'more content' > more.txt</b>
120 +<b>$ git add *.txt</b>
121 +<b>$ git commit -m 'added two files'</b>
122 +[master 8bd6d8b] added two files
123 + 2 files changed, 2 insertions(+), 0 deletions(-)
124 + create mode 100644 more.txt
125 + create mode 100644 test.txt
126 +<b>$ ls</b>
127 +README hello.rb more.txt test.txt
128 +<b>$ git checkout testing</b>
129 +Switched to branch 'testing'
130 +<b>$ ls</b>
131 +README hello.rb
132 +</pre>
133 +
134 + <p>So now we can see that when we switch to the 'testing' branch, our new
135 + files were removed. We could switch back to the 'master' branch and see
136 + them re-appear.</p>
137 +
138 +<pre>
139 +<b>$ ls</b>
140 +README hello.rb
141 +<b>$ git checkout master</b>
142 +Switched to branch 'master'
143 +<b>$ ls</b>
144 +README hello.rb more.txt test.txt
145 +</pre>
146 +
147 + <h4>
148 + git checkout -b (branchname)
149 + <small>create and immediately switch to a branch</small>
150 + </h4>
151 +
152 + <p>
153 + In most cases you will be wanting to switch to the branch immediately, so
154 + you can do work in it and then merging into a branch that only contains
155 + stable work (such as 'master') at a later point when the work in your new
156 + context branch is stable. You can do this pretty easily with
157 + <code>git branch newbranch; git checkout newbranch</code>, but Git gives
158 + you a shortcut for this: <code>git checkout -b newbranch</code>.
159 + </p>
160 +
161 +<pre>
162 +<b>$ git branch</b>
163 +* master
164 +<b>$ ls</b>
165 +README hello.rb more.txt test.txt
166 +<b>$ git checkout -b removals</b>
167 +Switched to a new branch 'removals'
168 +<b>$ git rm more.txt </b>
169 +rm 'more.txt'
170 +<b>$ git rm test.txt </b>
171 +rm 'test.txt'
172 +<b>$ ls</b>
173 +README hello.rb
174 +<b>$ git commit -am 'removed useless files'</b>
175 +[removals 8f7c949] removed useless files
176 + 2 files changed, 0 insertions(+), 2 deletions(-)
177 + delete mode 100644 more.txt
178 + delete mode 100644 test.txt
179 +<b>$ git checkout master</b>
180 +Switched to branch 'master'
181 +<b>$ ls</b>
182 +README hello.rb more.txt test.txt
183 +</pre>
184 +
185 + <p>You can see there how we created a branch, removed some of our files
186 + while in the context of that branch, then switched back to our main branch
187 + and we see the files return. Branching safely isolates work that we do into
188 + contexts we can switch between.</p>
189 +
190 + <p>
191 + If you start on work it is very useful to
192 + always start it in a branch (because it's fast and easy to do) and then
193 + merge it in and delete the branch when you're done. That way if what you're
194 + working on doesn't work out you can easily discard it and if you're forced
195 + to switch back to a more stable context your work in progress is easy to put
196 + aside and then come back to.</p>
197 +
198 + <h4>
199 + git branch -d (branchname)
200 + <small>delete a branch</small>
201 + </h4>
202 +
203 + <p>If we want to delete a branch (such as the 'testing' branch in the
204 + previous example, since there is no unique work on it),
205 + we can run <code>git branch -d (branch)</code> to remove it.
206 +
207 +<pre>
208 +<b>$ git branch</b>
209 +* <span class="green">master</span>
210 + testing
211 +<b>$ git branch -d testing</b>
212 +Deleted branch testing (was 78b2670).
213 +<b>$ git branch</b>
214 +* <span class="green">master</span>
215 +</pre>
216 +
217 + <p class="nutshell">
218 + <b>In a nutshell</b> you use <code>git branch</code> to list your
219 + current branches, create new branches and delete unnecessary or
220 + already merged branches.
221 + </p>
222 +
223 + </div>
224 +</div>
225 +
226 +<div class="box">
227 + <h2>
228 + <span class="docs">
229 + <a target="new" href="http://www.kernel.org/pub/software/scm/git/docs/git-merge.html">docs</a> &nbsp;
230 + <a target="new" href="http://progit.org/book/">book</a>
231 + </span>
232 + <a name="merge">git merge</a>
233 + <span class="desc">merge a branch context into your current one</span>
234 + </h2>
235 +
236 + <div class="block">
237 + <p>Once you have work isolated in a branch, you will eventually want to
238 + incorporate it into your main branch. You can merge any branch into your
239 + current branch with the <code>git merge</code> command. Let's take as a
240 + simple example the 'removals' branch from above. If we create a branch
241 + and remove files in it and commit our removals to that branch, it is
242 + isolated from our main ('master', in this case) branch. To include those
243 + deletions in your 'master' branch, you can just merge in the 'removals'
244 + branch.
245 + </p>
246 +
247 +<pre>
248 +<b>$ git branch</b>
249 +* <span class="green">master</span>
250 + removals
251 +<b>$ ls</b>
252 +README hello.rb more.txt test.txt
253 +<b>$ git merge removals</b>
254 +Updating 8bd6d8b..8f7c949
255 +Fast-forward
256 + more.txt | 1 -
257 + test.txt | 1 -
258 + 2 files changed, 0 insertions(+), 2 deletions(-)
259 + delete mode 100644 more.txt
260 + delete mode 100644 test.txt
261 +<b>$ ls</b>
262 +<span class="hl">README hello.rb</span>
263 +</pre>
264 +
265 + <h4>
266 + more complex merges
267 + </h4>
268 +
269 + <p>Of course, this doesn't just work for simple file additions and
270 + deletions. Git will merge file modifications as well - in fact, it's very
271 + good at it. For example, let's see what happens when we edit a file in
272 + one branch and in another branch we rename it and then edit it and then
273 + merge these branches together. Chaos, you say? Let's see.
274 + </p>
275 +
276 +<pre>
277 +<b>$ git branch</b>
278 +* master
279 +<b>$ cat hello.rb </b>
280 +class HelloWorld
281 + def self.hello
282 + puts "Hello World"
283 + end
284 +end
285 +
286 +HelloWorld.hello
287 +</pre>
288 +
289 + <p>So first we're going to create a new branch named 'change_class' and
290 + switch to it so your class renaming changes are isolated. I'm going to
291 + change each instance of 'HelloWorld' to 'HiWorld'.</p>
292 +
293 +<pre>
294 +<b>$ git checkout -b change_class</b>
295 +M hello.rb
296 +Switched to a new branch 'change_class'
297 +<b>$ vim hello.rb </b>
298 +<b>$ head -1 hello.rb </b>
299 +class HiWorld
300 +<b>$ git commit -am 'changed the class name'</b>
301 +[change_class 3467b0a] changed the class name
302 + 1 files changed, 2 insertions(+), 4 deletions(-)
303 +</pre>
304 +
305 + <p>So now I've committed the class renaming changes to the 'change_class'
306 + branch. If I now switch back to the 'master' branch my class name will
307 + revert to what it was before I switched branches. Here I can change
308 + something different (in this case the printed output) and at the same
309 + time rename the file from <code>hello.rb</code> to <code>ruby.rb</code>.
310 + </b>
311 +
312 +<pre>
313 +<b>$ git checkout master</b>
314 +Switched to branch 'master'
315 +<b>$ git mv hello.rb ruby.rb</b>
316 +<b>$ vim ruby.rb </b>
317 +<b>$ git diff</b>
318 +<span class="umber">diff --git a/ruby.rb b/ruby.rb
319 +index 2aabb6e..bf64b17 100644
320 +--- a/ruby.rb
321 ++++ b/ruby.rb</span>
322 +<span class="lblue">@@ -1,7 +1,7 @@</span>
323 + class HelloWorld
324 +
325 + def self.hello
326 +<span class="red">- puts "Hello World"</span>
327 +<span class="green">+ puts "Hello World from Ruby"</span>
328 + end
329 +
330 + end
331 +<b>$ git commit -am 'added from ruby'</b>
332 +[master b7ae93b] added from ruby
333 + 1 files changed, 1 insertions(+), 1 deletions(-)
334 + rename hello.rb => ruby.rb (65%)
335 +</pre>
336 +
337 + <p>Now those changes are recorded in my 'master' branch. Notice that the
338 + class name is back to 'HelloWorld', not 'HiWorld'. Now I want to
339 + incorporate the 'HiWorld' change so I can just merge in my 'change_class'
340 + branch. However, I've changed the name of the file since I branched,
341 + what will Git do?</p>
342 +
343 +<pre>
344 +<b>$ git branch</b>
345 + change_class
346 +* master
347 +<b>$ git merge change_class</b>
348 +Renaming hello.rb => ruby.rb
349 +Auto-merging ruby.rb
350 +Merge made by recursive.
351 + ruby.rb | 6 ++----
352 + 1 files changed, 2 insertions(+), 4 deletions(-)
353 +<b>$ cat ruby.rb</b>
354 +class HiWorld
355 + def self.hello
356 + puts "Hello World from Ruby"
357 + end
358 +end
359 +
360 +HiWorld.hello
361 +</pre>
362 +
363 + <p>Well, it will just figure it out. Notice that I had no merge conflicts
364 + and the file that had been renamed now has the 'HiWorld' class name change
365 + that was done in the other branch. Pretty cool.</p>
366 +
367 + <h4>
368 + merge conflicts
369 + </h4>
370 +
371 + <p>So, Git merges are magical, we never ever have to deal with merge
372 + conflicts again, right? Not quite. In situations where the same block
373 + of code is edited in different branches there is no way for a computer
374 + to figure it out, so it's up to us. Let's see another example of changing
375 + the same line in two branches.
376 + <p>
377 +
378 +<pre>
379 +<b>$ git branch</b>
380 +* master
381 +<b>$ git checkout -b fix_readme</b>
382 +Switched to a new branch 'fix_readme'
383 +<b>$ vim README </b>
384 +<b>$ git commit -am 'fixed readme title'</b>
385 +[fix_readme 3ac015d] fixed readme title
386 + 1 files changed, 1 insertions(+), 1 deletions(-)
387 +</pre>
388 +
389 + <p>Now we have committed a change to one line in our README file in a
390 + branch. Now let's change the same line in a different way back on
391 + our 'master' branch.</p>
392 +
393 +<pre>
394 +<b>$ git checkout master</b>
395 +Switched to branch 'master'
396 +<b>$ vim README </b>
397 +<b>$ git commit -am 'fixed readme title differently'</b>
398 +[master 3cbb6aa] fixed readme title differently
399 + 1 files changed, 1 insertions(+), 1 deletions(-)
400 +</pre>
401 +
402 + <p>Now is the fun part - we will merge the first branch into our master
403 + branch, causing a merge conflict.</p>
404 +
405 +<pre>
406 +<b>$ git merge fix_readme</b>
407 +Auto-merging README
408 +CONFLICT (content): Merge conflict in README
409 +Automatic merge failed; fix conflicts and then commit the result.
410 +<b>$ cat README </b>
411 +<<<<<<< HEAD
412 +Many Hello World Examples
413 +=======
414 +Hello World Lang Examples
415 +>>>>>>> fix_readme
416 +
417 +This project has examples of hello world in
418 +nearly every programming language.
419 +</pre>
420 +
421 + <p>You can see that Git inserts standard merge conflict markers, much like
422 + Subversion, into files when it gets a merge conflict. Now it's up to us
423 + to resolve them. We will do it manually here, but check out
424 + <a href="http://www.kernel.org/pub/software/scm/git/docs/git-mergetool.html">git mergetool</a>
425 + if you want Git to fire up a graphical mergetool
426 + (like kdiff3, emerge, p4merge, etc) instead.
427 + </p>
428 +
429 +<pre>
430 +<b>$ vim README </b> <span class="exp"># here I'm fixing the conflict</span>
431 +<b>$ git diff</b>
432 +<span class="umber">diff --cc README
433 +index 9103e27,69cad1a..0000000
434 +--- a/README
435 ++++ b/README</span>
436 +<span class="lblue">@@@ -1,4 -1,4 +1,4 @@@</span>
437 +<span class="red">- Many Hello World Examples</span>
438 + <span class="red">-Hello World Lang Examples</span>
439 +<span class="green">++Many Hello World Lang Examples</span>
440 +
441 + This project has examples of hello world in
442 +</pre>
443 +
444 + <p>A cool tip in doing merge conflict resolution in Git is that if you
445 + run <code>git diff</code>, it will show you both sides of the conflict
446 + and how you've resolved it as I've shown here. Now it's time to mark
447 + the file as resolved. In Git we do that with <code>git add</code> -
448 + to tell Git the file has been resolved, you have to stage it.</p>
449 +
450 +<pre>
451 +<b>$ git status -s</b>
452 +UU README
453 +<b>$ git add README </b>
454 +<b>$ git status -s</b>
455 +M README
456 +<b>$ git commit </b>
457 +[master 8d585ea] Merge branch 'fix_readme'
458 +</pre>
459 +
460 + <p>And now we've successfully resolved our merge conflict and committed
461 + the result.</p>
462 +
463 + </div>
464 +
465 +</div>
466 +
467 +<p><a href="/basic">On to Sharing and Updating Projects &#187;</a></p>
468 +