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>
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>
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>
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 »</a></p>
468
+