| 1 | --- |
| 2 | layout: reference |
| 3 | --- |
| 4 | |
| 5 | <div class="box"> |
| 6 | <h2> |
| 7 | <span class="docs"> |
| 8 | <a target="new" href="http://git-scm.com/book/en/Git-Branching">book</a> |
| 9 | </span> |
| 10 | Branching and Merging |
| 11 | </h2> |
| 12 | <div class="block"> |
| 13 | <p>Branching in Git is one of its many great 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://git-scm.com/docs/git-branch">docs</a> |
| 42 | <a target="new" href="http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is">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://git-scm.com/docs/git-checkout">docs</a> |
| 53 | <a target="new" href="http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging">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 id="branch-list"> |
| 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://git-scm.com/book/en/Customizing-Git-Git-Configuration#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 id="branch-create"> |
| 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 | </p> |
| 99 | |
| 100 | <pre> |
| 101 | $ git branch testing |
| 102 | $ git branch |
| 103 | * <span class="green">master</span> |
| 104 | testing |
| 105 | </pre> |
| 106 | |
| 107 | <p>Now we can see that we have a new branch. When you create a branch this |
| 108 | way it creates the branch at your last commit so if you record some commits |
| 109 | at this point and then switch to 'testing', it will revert your working |
| 110 | directory context back to when you created the branch in the first place - |
| 111 | you can think of it like a bookmark for where you currently are. Let's see |
| 112 | this in action - we use <code>git checkout (branch)</code> to switch the |
| 113 | branch we're currently on. |
| 114 | </p> |
| 115 | |
| 116 | <pre> |
| 117 | <b>$ ls</b> |
| 118 | README hello.rb |
| 119 | <b>$ echo 'test content' > test.txt</b> |
| 120 | <b>$ echo 'more content' > more.txt</b> |
| 121 | <b>$ git add *.txt</b> |
| 122 | <b>$ git commit -m 'added two files'</b> |
| 123 | [master 8bd6d8b] added two files |
| 124 | 2 files changed, 2 insertions(+), 0 deletions(-) |
| 125 | create mode 100644 more.txt |
| 126 | create mode 100644 test.txt |
| 127 | <b>$ ls</b> |
| 128 | README hello.rb more.txt test.txt |
| 129 | <b>$ git checkout testing</b> |
| 130 | Switched to branch 'testing' |
| 131 | <b>$ ls</b> |
| 132 | README hello.rb |
| 133 | </pre> |
| 134 | |
| 135 | <p>So now we can see that when we switch to the 'testing' branch, our new |
| 136 | files were removed. We could switch back to the 'master' branch and see |
| 137 | them re-appear.</p> |
| 138 | |
| 139 | <pre> |
| 140 | <b>$ ls</b> |
| 141 | README hello.rb |
| 142 | <b>$ git checkout master</b> |
| 143 | Switched to branch 'master' |
| 144 | <b>$ ls</b> |
| 145 | README hello.rb more.txt test.txt |
| 146 | </pre> |
| 147 | |
| 148 | <h4 id="branch-last-commit"> |
| 149 | git branch -v |
| 150 | <small>see the last commit on each branch</small> |
| 151 | </h4> |
| 152 | |
| 153 | <p>If we want to see last commits on each branch |
| 154 | we can run <code>git branch -v</code> to see them.</p> |
| 155 | |
| 156 | <pre> |
| 157 | <b>$ git branch -v</b> |
| 158 | * <span class="green">master</span> 54b417d fix javascript issue |
| 159 | development 74c111d modify component.json file |
| 160 | testing 62a557a update test scripts |
| 161 | </pre> |
| 162 | |
| 163 | <h4 id="branch-create-switch"> |
| 164 | git checkout -b (branchname) |
| 165 | <small>create and immediately switch to a branch</small> |
| 166 | </h4> |
| 167 | |
| 168 | <p> |
| 169 | In most cases you will be wanting to switch to the branch immediately, so |
| 170 | you can do work in it and then merging into a branch that only contains |
| 171 | stable work (such as 'master') at a later point when the work in your new |
| 172 | context branch is stable. You can do this pretty easily with |
| 173 | <code>git branch newbranch; git checkout newbranch</code>, but Git gives |
| 174 | you a shortcut for this: <code>git checkout -b newbranch</code>. |
| 175 | </p> |
| 176 | |
| 177 | <pre> |
| 178 | <b>$ git branch</b> |
| 179 | * master |
| 180 | <b>$ ls</b> |
| 181 | README hello.rb more.txt test.txt |
| 182 | <b>$ git checkout -b removals</b> |
| 183 | Switched to a new branch 'removals' |
| 184 | <b>$ git rm more.txt </b> |
| 185 | rm 'more.txt' |
| 186 | <b>$ git rm test.txt </b> |
| 187 | rm 'test.txt' |
| 188 | <b>$ ls</b> |
| 189 | README hello.rb |
| 190 | <b>$ git commit -am 'removed useless files'</b> |
| 191 | [removals 8f7c949] removed useless files |
| 192 | 2 files changed, 0 insertions(+), 2 deletions(-) |
| 193 | delete mode 100644 more.txt |
| 194 | delete mode 100644 test.txt |
| 195 | <b>$ git checkout master</b> |
| 196 | Switched to branch 'master' |
| 197 | <b>$ ls</b> |
| 198 | README hello.rb more.txt test.txt |
| 199 | </pre> |
| 200 | |
| 201 | <p>You can see there how we created a branch, removed some of our files |
| 202 | while in the context of that branch, then switched back to our main branch |
| 203 | and we see the files return. Branching safely isolates work that we do into |
| 204 | contexts we can switch between.</p> |
| 205 | |
| 206 | <p> |
| 207 | If you start on work it is very useful to |
| 208 | always start it in a branch (because it's fast and easy to do) and then |
| 209 | merge it in and delete the branch when you're done. That way if what you're |
| 210 | working on doesn't work out you can easily discard it and if you're forced |
| 211 | to switch back to a more stable context your work in progress is easy to put |
| 212 | aside and then come back to.</p> |
| 213 | |
| 214 | <h4 id="branch-delete"> |
| 215 | git branch -d (branchname) |
| 216 | <small>delete a branch</small> |
| 217 | </h4> |
| 218 | |
| 219 | <p>If we want to delete a branch (such as the 'testing' branch in the |
| 220 | previous example, since there is no unique work on it), |
| 221 | we can run <code>git branch -d (branch)</code> to remove it.</p> |
| 222 | |
| 223 | <pre> |
| 224 | <b>$ git branch</b> |
| 225 | * <span class="green">master</span> |
| 226 | testing |
| 227 | <b>$ git branch -d testing</b> |
| 228 | Deleted branch testing (was 78b2670). |
| 229 | <b>$ git branch</b> |
| 230 | * <span class="green">master</span> |
| 231 | </pre> |
| 232 | |
| 233 | <h4 id="branch-delete-remote"> |
| 234 | git push (remote-name) :(branchname) |
| 235 | <small>delete a remote branch</small> |
| 236 | </h4> |
| 237 | |
| 238 | <p>When you're done with a remote branch, whether it's been merged |
| 239 | into the remote master or you want to abandon it and sweep it under |
| 240 | the rug, you'll issue a <code>git push</code> command with a specially |
| 241 | placed colon symbol to remove that branch.</p> |
| 242 | |
| 243 | <pre> |
| 244 | <b>$ git push origin :tidy-cutlery</b> |
| 245 | To git@github.com:octocat/Spoon-Knife.git |
| 246 | - [deleted] tidy-cutlery |
| 247 | </pre> |
| 248 | |
| 249 | <p>In the above example you've deleted the "tidy-cutlery" branch |
| 250 | of the "origin" remote. A way to remember this is to think of the |
| 251 | <code>git push remote-name local-branch:remote-branch</code> syntax. |
| 252 | This states that you want to push your local branch to match that |
| 253 | of the remote. When you remove the <code>local-branch</code> portion |
| 254 | you're now matching nothing to the remote, effectively telling the |
| 255 | remote branch to become nothing. |
| 256 | </p> |
| 257 | |
| 258 | <p>Alternatively, you can run |
| 259 | <code>git push remote-name --delete branchname</code> |
| 260 | which is a wrapper for the colon refspec (a <code>source:destination</code> pair) |
| 261 | of deleting a remote branch. |
| 262 | </p> |
| 263 | |
| 264 | <p class="nutshell"> |
| 265 | <b>In a nutshell</b> you use <code>git branch</code> to list your |
| 266 | current branches, create new branches and delete unnecessary or |
| 267 | already merged branches. |
| 268 | </p> |
| 269 | |
| 270 | </div> |
| 271 | </div> |
| 272 | |
| 273 | <div class="box"> |
| 274 | <h2> |
| 275 | <span class="docs"> |
| 276 | <a target="new" href="http://git-scm.com/docs/git-merge">docs</a> |
| 277 | <a target="new" href="http://git-scm.com/book/en/Git-Branching-Basic-Branching-and-Merging#Basic-Merging">book</a> |
| 278 | </span> |
| 279 | <a name="merge">git merge</a> |
| 280 | <span class="desc">merge a branch context into your current one</span> |
| 281 | </h2> |
| 282 | |
| 283 | <div class="block"> |
| 284 | <p>Once you have work isolated in a branch, you will eventually want to |
| 285 | incorporate it into your main branch. You can merge any branch into your |
| 286 | current branch with the <code>git merge</code> command. Let's take as a |
| 287 | simple example the 'removals' branch from above. If we create a branch |
| 288 | and remove files in it and commit our removals to that branch, it is |
| 289 | isolated from our main ('master', in this case) branch. To include those |
| 290 | deletions in your 'master' branch, you can just merge in the 'removals' |
| 291 | branch. |
| 292 | </p> |
| 293 | |
| 294 | <pre> |
| 295 | <b>$ git branch</b> |
| 296 | * <span class="green">master</span> |
| 297 | removals |
| 298 | <b>$ ls</b> |
| 299 | README hello.rb more.txt test.txt |
| 300 | <b>$ git merge removals</b> |
| 301 | Updating 8bd6d8b..8f7c949 |
| 302 | Fast-forward |
| 303 | more.txt | 1 - |
| 304 | test.txt | 1 - |
| 305 | 2 files changed, 0 insertions(+), 2 deletions(-) |
| 306 | delete mode 100644 more.txt |
| 307 | delete mode 100644 test.txt |
| 308 | <b>$ ls</b> |
| 309 | <span class="hl">README hello.rb</span> |
| 310 | </pre> |
| 311 | |
| 312 | <h4 id="merge-complex"> |
| 313 | more complex merges |
| 314 | </h4> |
| 315 | |
| 316 | <p>Of course, this doesn't just work for simple file additions and |
| 317 | deletions. Git will merge file modifications as well - in fact, it's very |
| 318 | good at it. For example, let's see what happens when we edit a file in |
| 319 | one branch and in another branch we rename it and then edit it and then |
| 320 | merge these branches together. Chaos, you say? Let's see. |
| 321 | </p> |
| 322 | |
| 323 | <pre> |
| 324 | <b>$ git branch</b> |
| 325 | * master |
| 326 | <b>$ cat hello.rb </b> |
| 327 | class HelloWorld |
| 328 | def self.hello |
| 329 | puts "Hello World" |
| 330 | end |
| 331 | end |
| 332 | |
| 333 | HelloWorld.hello |
| 334 | </pre> |
| 335 | |
| 336 | <p>So first we're going to create a new branch named 'change_class' and |
| 337 | switch to it so your class renaming changes are isolated. We're going to |
| 338 | change each instance of 'HelloWorld' to 'HiWorld'.</p> |
| 339 | |
| 340 | <pre> |
| 341 | <b>$ git checkout -b change_class</b> |
| 342 | Switched to a new branch 'change_class' |
| 343 | <b>$ vim hello.rb </b> |
| 344 | <b>$ head -1 hello.rb </b> |
| 345 | class HiWorld |
| 346 | <b>$ git commit -am 'changed the class name'</b> |
| 347 | [change_class 3467b0a] changed the class name |
| 348 | 1 files changed, 2 insertions(+), 4 deletions(-) |
| 349 | </pre> |
| 350 | |
| 351 | <p>So now we've committed the class renaming changes to the 'change_class' |
| 352 | branch. To switch back to the 'master' branch the class name will |
| 353 | revert to what it was before we switched branches. Here we can change |
| 354 | something different (in this case the printed output) and at the same |
| 355 | time rename the file from <code>hello.rb</code> to <code>ruby.rb</code>. |
| 356 | </p> |
| 357 | |
| 358 | <pre> |
| 359 | <b>$ git checkout master</b> |
| 360 | Switched to branch 'master' |
| 361 | <b>$ git mv hello.rb ruby.rb</b> |
| 362 | <b>$ vim ruby.rb </b> |
| 363 | <b>$ git diff</b> |
| 364 | <span class="umber">diff --git a/ruby.rb b/ruby.rb |
| 365 | index 2aabb6e..bf64b17 100644 |
| 366 | --- a/ruby.rb |
| 367 | +++ b/ruby.rb</span> |
| 368 | <span class="lblue">@@ -1,7 +1,7 @@</span> |
| 369 | class HelloWorld |
| 370 | |
| 371 | def self.hello |
| 372 | <span class="red">- puts "Hello World"</span> |
| 373 | <span class="green">+ puts "Hello World from Ruby"</span> |
| 374 | end |
| 375 | |
| 376 | end |
| 377 | <b>$ git commit -am 'added from ruby'</b> |
| 378 | [master b7ae93b] added from ruby |
| 379 | 1 files changed, 1 insertions(+), 1 deletions(-) |
| 380 | rename hello.rb => ruby.rb (65%) |
| 381 | </pre> |
| 382 | |
| 383 | <p>Now those changes are recorded in the 'master' branch. Notice that the |
| 384 | class name is back to 'HelloWorld', not 'HiWorld'. To incorporate |
| 385 | the 'HiWorld' change we can just merge in the 'change_class' |
| 386 | branch. However, the name of the file has changed since we branched, |
| 387 | what will Git do?</p> |
| 388 | |
| 389 | <pre> |
| 390 | <b>$ git branch</b> |
| 391 | change_class |
| 392 | * master |
| 393 | <b>$ git merge change_class</b> |
| 394 | Renaming hello.rb => ruby.rb |
| 395 | Auto-merging ruby.rb |
| 396 | Merge made by recursive. |
| 397 | ruby.rb | 6 ++---- |
| 398 | 1 files changed, 2 insertions(+), 4 deletions(-) |
| 399 | <b>$ cat ruby.rb</b> |
| 400 | class HiWorld |
| 401 | def self.hello |
| 402 | puts "Hello World from Ruby" |
| 403 | end |
| 404 | end |
| 405 | |
| 406 | HiWorld.hello |
| 407 | </pre> |
| 408 | |
| 409 | <p>Well, it will just figure it out. Notice that there are no merge conflicts |
| 410 | and the file that had been renamed now has the 'HiWorld' class name change |
| 411 | that was done in the other branch. Pretty cool.</p> |
| 412 | |
| 413 | <h4 id="merge-conflicts"> |
| 414 | merge conflicts |
| 415 | </h4> |
| 416 | |
| 417 | <p>So, Git merges are magical, we never ever have to deal with merge |
| 418 | conflicts again, right? Not quite. In situations where the same block |
| 419 | of code is edited in different branches there is no way for a computer |
| 420 | to figure it out, so it's up to us. Let's see another example of changing |
| 421 | the same line in two branches. |
| 422 | </p> |
| 423 | |
| 424 | <pre> |
| 425 | <b>$ git branch</b> |
| 426 | * master |
| 427 | <b>$ git checkout -b fix_readme</b> |
| 428 | Switched to a new branch 'fix_readme' |
| 429 | <b>$ vim README </b> |
| 430 | <b>$ git commit -am 'fixed readme title'</b> |
| 431 | [fix_readme 3ac015d] fixed readme title |
| 432 | 1 files changed, 1 insertions(+), 1 deletions(-) |
| 433 | </pre> |
| 434 | |
| 435 | <p>Now we have committed a change to one line in our README file in a |
| 436 | branch. Now let's change the same line in a different way back on |
| 437 | our 'master' branch.</p> |
| 438 | |
| 439 | <pre> |
| 440 | <b>$ git checkout master</b> |
| 441 | Switched to branch 'master' |
| 442 | <b>$ vim README </b> |
| 443 | <b>$ git commit -am 'fixed readme title differently'</b> |
| 444 | [master 3cbb6aa] fixed readme title differently |
| 445 | 1 files changed, 1 insertions(+), 1 deletions(-) |
| 446 | </pre> |
| 447 | |
| 448 | <p>Now is the fun part - we will merge the first branch into our master |
| 449 | branch, causing a merge conflict.</p> |
| 450 | |
| 451 | <pre> |
| 452 | <b>$ git merge fix_readme</b> |
| 453 | Auto-merging README |
| 454 | CONFLICT (content): Merge conflict in README |
| 455 | Automatic merge failed; fix conflicts and then commit the result. |
| 456 | <b>$ cat README </b> |
| 457 | <<<<<<< HEAD |
| 458 | Many Hello World Examples |
| 459 | ======= |
| 460 | Hello World Lang Examples |
| 461 | >>>>>>> fix_readme |
| 462 | |
| 463 | This project has examples of hello world in |
| 464 | nearly every programming language. |
| 465 | </pre> |
| 466 | |
| 467 | <p>You can see that Git inserts standard merge conflict markers, much like |
| 468 | Subversion, into files when it gets a merge conflict. Now it's up to us |
| 469 | to resolve them. We will do it manually here, but check out |
| 470 | <a href="http://git-scm.com/docs/git-mergetool">git mergetool</a> |
| 471 | if you want Git to fire up a graphical mergetool |
| 472 | (like kdiff3, emerge, p4merge, etc) instead. |
| 473 | </p> |
| 474 | |
| 475 | <pre> |
| 476 | <b>$ vim README </b> <span class="exp"># here I'm fixing the conflict</span> |
| 477 | <b>$ git diff</b> |
| 478 | <span class="umber">diff --cc README |
| 479 | index 9103e27,69cad1a..0000000 |
| 480 | --- a/README |
| 481 | +++ b/README</span> |
| 482 | <span class="lblue">@@@ -1,4 -1,4 +1,4 @@@</span> |
| 483 | <span class="red">- Many Hello World Examples</span> |
| 484 | <span class="red">-Hello World Lang Examples</span> |
| 485 | <span class="green">++Many Hello World Lang Examples</span> |
| 486 | |
| 487 | This project has examples of hello world in |
| 488 | </pre> |
| 489 | |
| 490 | <p>A cool tip in doing merge conflict resolution in Git is that if you |
| 491 | run <code>git diff</code>, it will show you both sides of the conflict |
| 492 | and how you've resolved it as shown here. Now it's time to mark |
| 493 | the file as resolved. In Git we do that with <code>git add</code> - |
| 494 | to tell Git the file has been resolved you have to stage it.</p> |
| 495 | |
| 496 | <pre> |
| 497 | <b>$ git status -s</b> |
| 498 | UU README |
| 499 | <b>$ git add README </b> |
| 500 | <b>$ git status -s</b> |
| 501 | M README |
| 502 | <b>$ git commit </b> |
| 503 | [master 8d585ea] Merge branch 'fix_readme' |
| 504 | </pre> |
| 505 | |
| 506 | <p>And now we've successfully resolved our merge conflict and committed |
| 507 | the result.</p> |
| 508 | |
| 509 | <p class="nutshell"> |
| 510 | <b>In a nutshell</b> you use <code>git merge</code> to combine another |
| 511 | branch context into your current branch. It automatically figures out |
| 512 | how to best combine the different snapshots into a new snapshot with the |
| 513 | unique work of both. |
| 514 | </p> |
| 515 | |
| 516 | </div> |
| 517 | </div> |
| 518 | |
| 519 | <div class="box"> |
| 520 | <h2> |
| 521 | <span class="docs"> |
| 522 | <a target="new" href="http://git-scm.com/docs/git-log">docs</a> |
| 523 | <a target="new" href="http://git-scm.com/book/en/Git-Tools-Revision-Selection#Commit-Ranges">book</a> |
| 524 | </span> |
| 525 | <a name="log">git log</a> |
| 526 | <span class="desc">show commit history of a branch</span> |
| 527 | </h2> |
| 528 | |
| 529 | <div class="block"> |
| 530 | |
| 531 | <p>So far we have been committing snapshots of your project and switching |
| 532 | between different isolated contexts, but what if we've forgotten how we've |
| 533 | got to where we are? Or what if we want to know how one branch differs |
| 534 | from another? Git provides a tool that shows you all the commit messages |
| 535 | that have lead up to the snapshot you are currently on, which is called |
| 536 | <code>git log</code>.</p> |
| 537 | |
| 538 | <p>To understand the log command, you have to understand what information |
| 539 | is stored when you run the <code>git commit</code> command to store a |
| 540 | snapshot. In addition to the manifest of files and commit message and |
| 541 | information about the person who committed it, Git also stores the commit |
| 542 | that you based this snapshot on. That is, if you clone a project, what was |
| 543 | the snapshot that you modified to get to the snapshot that you saved? This |
| 544 | is helpful to give context to how the project got to where it is and allows |
| 545 | Git to figure out who changed what. If Git has the snapshot you save and |
| 546 | the one you based it on, then it can automatically figure out what you |
| 547 | changed. The commit that a new commit was based on is called the "parent". |
| 548 | </p> |
| 549 | |
| 550 | <p>To see a chronological list of the parents of any branch, you can run |
| 551 | <code>git log</code> when you are in that branch. For example, if we run |
| 552 | <code>git log</code> in the Hello World project that we have been working |
| 553 | on in this section, we'll see all the commit messages that we've done. |
| 554 | </p> |
| 555 | |
| 556 | <pre> |
| 557 | <b>$ git log</b> |
| 558 | <span class="yellow">commit 8d585ea6faf99facd39b55d6f6a3b3f481ad0d3d</span> |
| 559 | Merge: 3cbb6aa 3ac015d |
| 560 | Author: Scott Chacon <schacon@gmail.com> |
| 561 | Date: Fri Jun 4 12:59:47 2010 +0200 |
| 562 | |
| 563 | Merge branch 'fix_readme' |
| 564 | |
| 565 | Conflicts: |
| 566 | README |
| 567 | |
| 568 | <span class="yellow">commit 3cbb6aae5c0cbd711c098e113ae436801371c95e</span> |
| 569 | Author: Scott Chacon <schacon@gmail.com> |
| 570 | Date: Fri Jun 4 12:58:53 2010 +0200 |
| 571 | |
| 572 | fixed readme title differently |
| 573 | |
| 574 | <span class="yellow">commit 3ac015da8ade34d4c7ebeffa2053fcac33fb495b</span> |
| 575 | Author: Scott Chacon <schacon@gmail.com> |
| 576 | Date: Fri Jun 4 12:58:36 2010 +0200 |
| 577 | |
| 578 | fixed readme title |
| 579 | |
| 580 | <span class="yellow">commit 558151a95567ba4181bab5746bc8f34bd87143d6</span> |
| 581 | Merge: b7ae93b 3467b0a |
| 582 | Author: Scott Chacon <schacon@gmail.com> |
| 583 | Date: Fri Jun 4 12:37:05 2010 +0200 |
| 584 | |
| 585 | Merge branch 'change_class' |
| 586 | ... |
| 587 | </pre> |
| 588 | |
| 589 | <p>To see a more compact version of the same history, we can use the |
| 590 | <code>--oneline</code> option.</p> |
| 591 | |
| 592 | <pre> |
| 593 | <b>$ git log --oneline</b> |
| 594 | 8d585ea Merge branch 'fix_readme' |
| 595 | 3cbb6aa fixed readme title differently |
| 596 | 3ac015d fixed readme title |
| 597 | 558151a Merge branch 'change_class' |
| 598 | b7ae93b added from ruby |
| 599 | 3467b0a changed the class name |
| 600 | 17f4acf first commit |
| 601 | </pre> |
| 602 | |
| 603 | <p>What this is telling us is that this is the history of the development |
| 604 | of this project. If the commit messages are descriptive, this can inform |
| 605 | us as to what all changes have been applied or have influenced the current |
| 606 | state of the snapshot and thus what is in it.</p> |
| 607 | |
| 608 | <p>We can also use it to see when the history was branched and merged with |
| 609 | the very helpful <code>--graph</code> option. Here is the same command |
| 610 | but with the topology graph turned on:</p> |
| 611 | |
| 612 | <pre> |
| 613 | <b>$ git log --oneline --graph</b> |
| 614 | * 8d585ea Merge branch 'fix_readme' |
| 615 | |\ |
| 616 | | * 3ac015d fixed readme title |
| 617 | * | 3cbb6aa fixed readme title differently |
| 618 | |/ |
| 619 | * 558151a Merge branch 'change_class' |
| 620 | |\ |
| 621 | | * 3467b0a changed the class name |
| 622 | * | b7ae93b added from ruby |
| 623 | |/ |
| 624 | * 17f4acf first commit |
| 625 | </pre> |
| 626 | |
| 627 | <p>Now we can more clearly see when effort diverged and then was merged |
| 628 | back together. This is very nice for seeing what has happened or what |
| 629 | changes are applied, but |
| 630 | it is also incredibly useful for managing your branches. Let's create a new |
| 631 | branch, do some work in it and then switch back and do some work in our |
| 632 | master branch, then see how the <code>log</code> command can help us figure |
| 633 | out what is happening on each.</p> |
| 634 | |
| 635 | <p>First we'll create a new branch to add the Erlang programming language |
| 636 | Hello World example - we want to do this in a branch so that we don't |
| 637 | muddy up our stable branch with code that may not work for a while so we |
| 638 | can cleanly switch in and out of it.</p> |
| 639 | |
| 640 | <pre> |
| 641 | <b>$ git checkout -b erlang</b> |
| 642 | Switched to a new branch 'erlang' |
| 643 | <b>$ vim erlang_hw.erl</b> |
| 644 | <b>$ git add erlang_hw.erl </b> |
| 645 | <b>$ git commit -m 'added erlang'</b> |
| 646 | [erlang ab5ab4c] added erlang |
| 647 | 1 files changed, 5 insertions(+), 0 deletions(-) |
| 648 | create mode 100644 erlang_hw.erl |
| 649 | </pre> |
| 650 | |
| 651 | <p>Since we're having fun playing in functional programming languages we |
| 652 | get caught up in it and also add a Haskell example program while still in |
| 653 | the branch named 'erlang'.</p> |
| 654 | |
| 655 | <pre> |
| 656 | <b>$ vim haskell.hs</b> |
| 657 | <b>$ git add haskell.hs </b> |
| 658 | <b>$ git commit -m 'added haskell'</b> |
| 659 | [erlang 1834130] added haskell |
| 660 | 1 files changed, 4 insertions(+), 0 deletions(-) |
| 661 | create mode 100644 haskell.hs |
| 662 | </pre> |
| 663 | |
| 664 | <p>Finally, we decide that we want to change the class name of our Ruby |
| 665 | program back to the way it was. So, we can go back to the master branch |
| 666 | and change that and we decide to just commit it directly in the master |
| 667 | branch instead of creating another branch.</p> |
| 668 | |
| 669 | <pre> |
| 670 | <b>$ git checkout master</b> |
| 671 | Switched to branch 'master' |
| 672 | <b>$ ls</b> |
| 673 | README ruby.rb |
| 674 | <b>$ vim ruby.rb </b> |
| 675 | <b>$ git commit -am 'reverted to old class name'</b> |
| 676 | [master 594f90b] reverted to old class name |
| 677 | 1 files changed, 2 insertions(+), 2 deletions(-) |
| 678 | </pre> |
| 679 | |
| 680 | <p>So, now say we don't work on the project for a while, we have other |
| 681 | things to do. When we come back we want to know what the 'erlang' branch |
| 682 | is all about and where we've left off on the master branch. Just by looking |
| 683 | at the branch name, we can't know that we made Haskell changes in there, but |
| 684 | using <code>git log</code> we easily can. If you give Git a branch name, |
| 685 | it will show you just the commits that are "reachable" in the history of |
| 686 | that branch, that is the commits that influenced the final snapshot.</p> |
| 687 | |
| 688 | <pre> |
| 689 | <b>$ git log --oneline erlang</b> |
| 690 | <span class="hl">1834130 added haskell</span> |
| 691 | ab5ab4c added erlang |
| 692 | 8d585ea Merge branch 'fix_readme' |
| 693 | 3cbb6aa fixed readme title differently |
| 694 | 3ac015d fixed readme title |
| 695 | 558151a Merge branch 'change_class' |
| 696 | b7ae93b added from ruby |
| 697 | 3467b0a changed the class name |
| 698 | 17f4acf first commit |
| 699 | </pre> |
| 700 | |
| 701 | <p>This way, it's pretty easy to see that we have Haskell code included in |
| 702 | the branch (highlighted in the output). What is even cooler is that we can |
| 703 | easily tell Git that we only are interested in the commits that are |
| 704 | reachable in one branch that are not reachable in another, in other words |
| 705 | which commits are unique to a branch in comparison to another. |
| 706 | </p> |
| 707 | |
| 708 | <p> |
| 709 | In this case if we are interested in merging in the 'erlang' branch we |
| 710 | want to see what commits are going to effect our snapshot when we do |
| 711 | that merge. The way we tell Git that is by putting a <code>^</code> in |
| 712 | front of the branch that we don't want to see. For instance, if we want |
| 713 | to see the commits that are in the 'erlang' branch that are not in the |
| 714 | 'master' branch, we can do <code>erlang ^master</code>, or vice versa. |
| 715 | Note that the Windows command-line treats <code>^</code> as a special |
| 716 | character, in which case you'll need to surround <code>^master</code> |
| 717 | in quotes. |
| 718 | </p> |
| 719 | |
| 720 | <pre> |
| 721 | <b>$ git log --oneline erlang ^master</b> |
| 722 | 1834130 added haskell |
| 723 | ab5ab4c added erlang |
| 724 | <b>$ git log --oneline master ^erlang</b> |
| 725 | 594f90b reverted to old class name |
| 726 | </pre> |
| 727 | |
| 728 | <p>This gives us a nice, simple branch management tool. It allows us to |
| 729 | easily see what commits are unique to which branches so we know what |
| 730 | we're missing and what we would be merging in if we were to do a merge. |
| 731 | </p> |
| 732 | |
| 733 | <p class="nutshell"> |
| 734 | <b>In a nutshell</b> you use <code>git log</code> to list out the commit |
| 735 | history or list of changes people have made that have lead to the snapshot |
| 736 | at the tip of the branch. This allows you to see how the project in that |
| 737 | context got to the state that it is currently in. |
| 738 | </p> |
| 739 | |
| 740 | </div> |
| 741 | </div> |
| 742 | |
| 743 | <div class="box"> |
| 744 | <h2> |
| 745 | <span class="docs"> |
| 746 | <a target="new" href="http://git-scm.com/docs/git-tag">docs</a> |
| 747 | <a target="new" href="http://git-scm.com/book/en/Git-Basics-Tagging">book</a> |
| 748 | </span> |
| 749 | <a name="tag">git tag</a> |
| 750 | <span class="desc">tag a point in history as important</span> |
| 751 | </h2> |
| 752 | |
| 753 | <div class="block"> |
| 754 | |
| 755 | <p> |
| 756 | If you get to a point that is important and you want to forever remember |
| 757 | that specific commit snapshot, you can tag it with <code>git tag</code>. |
| 758 | The <code>tag</code> command will basically put a permanent bookmark at |
| 759 | a specific commit so you can use it to compare to other commits in the |
| 760 | future. This is often done when you cut a release or ship something. |
| 761 | </p> |
| 762 | |
| 763 | <p>Let's say we want to release our Hello World project as version "1.0". |
| 764 | We can tag the last commit (<code>HEAD</code>) as "v1.0" by running |
| 765 | <code>git tag -a v1.0</code>. The <code>-a</code> means "make an annotated |
| 766 | tag", which allows you to add a tag message to it, which is what you almost |
| 767 | always want to do. Running this without the <code>-a</code> works too, but |
| 768 | it doesn't record when it was tagged, who tagged it, or let you add a tag |
| 769 | message. It's recommended you always create annotated tags.</p> |
| 770 | |
| 771 | <pre> |
| 772 | <b>$ git tag -a v1.0 </b> |
| 773 | </pre> |
| 774 | |
| 775 | <p>When you run the <code>git tag -a</code> command, Git will open your editor |
| 776 | and have you write a tag message, just like you would write a commit |
| 777 | message.</p> |
| 778 | |
| 779 | <p>Now, notice when we run <code>git log --decorate</code>, we can see our |
| 780 | tag there.</p> |
| 781 | |
| 782 | <pre> |
| 783 | <b>$ git log --oneline --decorate --graph</b> |
| 784 | * 594f90b (HEAD, <span class="hl">tag: v1.0</span>, master) reverted to old class name |
| 785 | * 8d585ea Merge branch 'fix_readme' |
| 786 | |\ |
| 787 | | * 3ac015d (fix_readme) fixed readme title |
| 788 | * | 3cbb6aa fixed readme title differently |
| 789 | |/ |
| 790 | * 558151a Merge branch 'change_class' |
| 791 | |\ |
| 792 | | * 3467b0a changed the class name |
| 793 | * | b7ae93b added from ruby |
| 794 | |/ |
| 795 | * 17f4acf first commit |
| 796 | </pre> |
| 797 | |
| 798 | <p>If we do more commits, the tag will stay right at that commit, so we have |
| 799 | that specific snapshot tagged forever and can always compare future |
| 800 | snapshots to it.</p> |
| 801 | |
| 802 | <p>We don't have to tag the commit that we're on, however. If we forgot to |
| 803 | tag a commit that we released, we can retroactively tag it by running the |
| 804 | same command, but with the commit SHA at the end. For example, say we had |
| 805 | released commit <code>558151a</code> (several commits back) but forgot to |
| 806 | tag it at the time. We can just tag it now:</p> |
| 807 | |
| 808 | <pre> |
| 809 | <b>$ git tag -a v0.9 558151a</b> |
| 810 | <b>$ git log --oneline --decorate --graph</b> |
| 811 | * 594f90b (HEAD, tag: v1.0, master) reverted to old class name |
| 812 | * 8d585ea Merge branch 'fix_readme' |
| 813 | |\ |
| 814 | | * 3ac015d (fix_readme) fixed readme title |
| 815 | * | 3cbb6aa fixed readme title differently |
| 816 | |/ |
| 817 | * 558151a (<span class="hl">tag: v0.9</span>) Merge branch 'change_class' |
| 818 | |\ |
| 819 | | * 3467b0a changed the class name |
| 820 | * | b7ae93b added from ruby |
| 821 | |/ |
| 822 | * 17f4acf first commit |
| 823 | </pre> |
| 824 | |
| 825 | <p>Tags pointing to objects tracked from branch heads will be |
| 826 | automatically downloaded when you <code>fetch</code> from a remote |
| 827 | repository. However, tags that aren't reachable from branch heads |
| 828 | will be skipped. If you want to make sure <em>all</em> tags are <em>always</em> |
| 829 | included, you must include the <code>--tags</code> option. |
| 830 | </p> |
| 831 | |
| 832 | <pre> |
| 833 | <b>$ git fetch origin --tags</b> |
| 834 | remote: Counting objects: 1832, done. |
| 835 | remote: Compressing objects: 100% (726/726), done. |
| 836 | remote: Total 1519 (delta 1000), reused 1202 (delta 764) |
| 837 | Receiving objects: 100% (1519/1519), 1.30 MiB | 1.21 MiB/s, done. |
| 838 | Resolving deltas: 100% (1000/1000), completed with 182 local objects. |
| 839 | From git://github.com:example-user/example-repo |
| 840 | * [new tag] v1.0 -> v1.0 |
| 841 | * [new tag] v1.1 -> v1.1 |
| 842 | </pre> |
| 843 | |
| 844 | <p>If you just want a single tag, use |
| 845 | <code>git fetch <remote> tag <tag-name></code>. |
| 846 | </p> |
| 847 | |
| 848 | <p>By default, tags are not included when you <code>push</code> to |
| 849 | a remote repository. In order to explicitly update these you must |
| 850 | include the <code>--tags</code> option when using <code>git push</code>. |
| 851 | </p> |
| 852 | |
| 853 | <p class="nutshell"> |
| 854 | <b>In a nutshell</b> you use <code>git tag</code> to mark a |
| 855 | commit or point in your repo as important. This also allows |
| 856 | you to refer to that commit with a more memorable reference |
| 857 | than a SHA. |
| 858 | </p> |
| 859 | |
| 860 | </div> |
| 861 | </div> |
| 862 | |
| 863 | <p><a class="page-button next-page" href="/remotes">On to Sharing and Updating Projects »</a></p> |
| 864 |