<!DOCTYPE html>
<html lang="en">
	<head>
		<meta charset="utf-8">

		<title>Never Commit to Master: An Introduction to Git Flow | DrupalCamp London 2014</title>

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">

    <link rel="stylesheet" href="css/reveal.min.css">
    <link rel="stylesheet" href="css/theme/night.css" id="theme">
    <link rel="stylesheet" href="lib/css/zenburn.css">

    <link rel="stylesheet" href="lib/css/pdf.css">

    <script>
      document.write( '<link rel="stylesheet" href="css/print/' + ( window.location.search.match( /print-pdf/gi ) ? 'pdf' : 'paper' ) + '.css" type="text/css" media="print">' );
    </script>

    <!--[if lt IE 9]>
    <script src="lib/js/html5shiv.js"></script>
    <![endif]-->
	</head>
	<body>
		<div class="reveal">
			<div class="slides">

        <section>
          <h1>Never Commit to Master</h1>
          <h3>An Introduction to Git Flow</h3>
          <p>
            <small>By <a href="http://www.oliverdavies.co.uk">Oliver Davies</a> / <a href="http://twitter.com/opdavies">@opdavies</a></small>
          </p>
          <aside class="notes">
            Drupal for 8 years, Git since for 4 years, Git Flow for a year
          </aside>
        </section>

        <section>
          <h2>Me</h2>
          <ul>
            <li class="fragment">Oliver Davies</li>
            <li class="fragment">Developer and Systems Administrator</li>
            <li class="fragment"><a href="http://twitter.com/opdavies">@opdavies</a> (Twitter, D.O., IRC)</li>
            <li class="fragment"><a href="http://dgo.to/@opdavies">http://dgo.to/@opdavies</a></li>
            <li class="fragment">PHPer and Drupalista since 2007 (full time since 2010)</li>
            <li class="fragment">Git user since 2010</li>
            <li class="fragment">Git Flow user since 2013</li>
          </ul>
        </section>

        <section>
          <img src="images/precedent-white.png" style="background: none; border: none;">
        </section>

        <section>
          <h2>Git Flow is:</h2>
          <blockquote>"A collection of Git extensions to provide high-level repository operations for <a href="http://nvie.com/git-model">Vincent Driessen's branching model</a>."</blockquote>
          <p><small>From <a href="https://github.com/nvie/gitflow">https://github.com/nvie/gitflow</a></small></p>
          <aside class="notes">
* Read quote from slide *
Provides a wrapper around standard Git functionality
Everything in Git Flow can be done manually
          </aside>
        </section>

        <section>
          <h2>The Branching Model</h2>
          <div class="image">
            <img src="images/nvie.png" style="border: none;">
          </div>
          <p><small>From <a href=""></a></small></p>
          <aside class="notes">
            Separates production code from development code<br>
            Encourages feature driven development<br>
            Allows for releasing and tagging of code<br>
            Multiple opportunities for QA and review
          </aside>
        </section>

        <section>
          <h2>Branches</h2>
          <ul>
            <li class="fragment"><code>master</code>: production code</li>
            <li class="fragment"><code>develop</code>: development code</li>
            <li class="fragment"><code>feature/</code>: a specific task or ticket (multiple)</li>
            <li class="fragment"><code>release/</code>: temporary release branch for testing (single)</li>
            <li class="fragment"><code>hotfix/</code>: temporary branch for emergency fixes</li>
            <li class="fragment"><code>support/</code>: experimental</li>
          </ul>
          <aside class="notes">
            master: stable production code, tagged at the end of each release (stable)<br>
            develop: stores tested and verified development code, awaiting deployment (fairly stable)<br>
            feature: unstable code relating to a specific task, bug or user story<br>
            release: <br>
            hotfix: Used to apply urgent fixes to production code
          </aside>
        </section>

        <section>
          <h2>Why use Git Flow?</h2>
          <ul>
            <li class="fragment">Separation of production and development code</li>
            <li class="fragment">Flexibility</li>
            <li class="fragment">Better code quality</li>
            <li class="fragment">Encourages collaboration</li>
            <li class="fragment">Encourages peer code reviews</li>
          </ul>
          <aside class="notes">
            Separates code by using different branches<br>
            Being able to easily switch between features<br>
            Continuous testing of feature and release branches<br>
            Collaboration through sharing of standard branch names<br>
            Code reviews
          </aside>
        </section>

        <section>
          <h2>My rules of Git Flow</h2>
          <ol>
            <li class="fragment">Never, ever commit code directly to <code>master</code></li>
            <li class="fragment">Only commit stable code to <code>develop</code></li>
            <li class="fragment">Try not to commit directly to <code>develop</code></li>
            <li class="fragment">One feature branch per user story/bug</li>
            <li class="fragment">Commit early, commit often, push often</li>
          </ol>
        </section>

        <section>
          <h2>How do I use it?</h2>
          <ul>
            <li class="fragment">CLI
              <ul>
                <li class="fragment"><code>~ $ brew install git-flow</code></li>
                <li class="fragment"><code>~ $ apt-get install git-flow</code></li>
                <li class="fragment"><code>~ $ yum install gitflow</code></li>
              </ul>
            </li>
            <li class="fragment"><a href="http://www.sourcetreeapp.com/">SourceTree</a> (free, cross-platform GUI)</li>
          </ul>
          <aside class="notes">
            You can install and use Git Flow on the command line.<br>
            There are packages for Ubuntu (apt), Red Hat and CentOS (yum) and OS X (Homebrew).<br>
            You can also download SourceTree from Atlassian which is cross-platform
          </aside>
        </section>

        <section>
          <h2>Need Help?</h2>
          <pre><code data-trim>
~ $ git flow help
# Shows the standard help menu

~ $ git flow {subcommand} help
# Shows the help menu for a specific subcommand
          </code></pre>
        </section>

        <section>
          <h2>Initialise Git Flow</h2>
          <pre><code data-trim>
~ $ git flow init
          </code></pre>
          <aside class="notes">
            This can be done at any time, with existing commits
          </aside>
        </section>

        <section>
          <h2>Create your default branches</h2>
          <pre><code data-trim>
~ $ git flow init

No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]
          </code></pre>
        </section>

        <section>
          <h2>Configure branch prefixes</h2>
          <pre><code data-trim>
~ $ git flow init

No branches exist yet. Base branches must be created now.
Branch name for production releases: [master]
Branch name for "next release" development: [develop]

How to name your supporting branch prefixes?
Feature branches? [feature/]
Release branches? [release/]
Hotfix branches? [hotfix/]
Support branches? [support/]
Version tag prefix? []
          </code></pre>
        </section>

        <section>
          <h2>Tip: Automatically accept the <br>default branch names</h2>
          <pre><code data-trim>
~ $ git flow init -d
# Accepts the default branch names.
          </code></pre>
          <aside class="notes">
            <p>Adding -d accepts the default branch names.</p>
          </aside>
        </section>

        <section>
          <h2>Features</h2>
          <p><code>$ git flow feature</code></p>
          <ul>
            <li class="fragment"><code>list</code>: lists all features</li>
            <li class="fragment"><code>checkout</code>: checks out an existing feature</li>
            <li class="fragment"><code>start</code>: starts a new feature</li>
            <li class="fragment"><code>finish</code>: finishes a feature</li>
            <li class="fragment"><code>publish</code>: pushes a feature into a remote repo</li>
            <li class="fragment"><code>pull</code>: pulls a feature from a remote repo</li>
          </ul>
          <aside class="notes">
            Checkout can be a full feature name or a prefix
          </aside>
        </section>

        <section>
          <h2>Start a new feature branch</h2>

          <pre><code data-trim>
~ $ git flow feature start {name}
          </code></pre>

          <div class="fragment">
            <pre><code data-trim>
~ $ git flow feature start foo

Switched to a new branch 'feature/foo'

Summary of actions:
- A new branch 'feature/foo' was created, based on 'develop'
- You are now on branch 'feature/foo'

Now, start committing on your feature. When done, use:

git flow feature finish foo
            </code></pre>
          </div>

          <aside class="notes">
            * Branches from develop
          </aside>
        </section>

        <section>
          <h2>Add and commit changes</h2>
          <pre><code data-trim>
~ $ drush dl admin_menu
~ $ git add sites/all/modules/contrib/admin_menu
~ $ git commit -m "Added admin_menu"
          </code></pre>
        </section>

<!--
        <section>
          <h2>Features</h2>
          <pre><code data-trim>
* 267dd3f - (HEAD, feature/foo, develop) Added admin_menu (8 minutes ago) [Oliver Davies]
* f3108db - Initial commit (9 minutes ago) [Oliver Davies]
* 2581201 - (master) Initial commit (9 minutes ago) [Oliver Davies]
          </code></pre>
        </section>
-->

        <section>
          <h2>Recommended: Rebase Your Feature</h2>
          <p>Ensure that your feature is up-to-date</p>
          <pre><code data-trim>
~ $ git flow feature rebase

Will try to rebase 'foo'...
First, rewinding head to replay your work on top of it...
Applying: Added admin_menu
          </code></pre>
          <aside class="notes">
            Rewinds the feature, updates from develop and re-applies the feature changes<br>
            Ensures that the feature code is up to date and will merge correctly.
          </aside>
        </section>

        <section>
          <h2>Finish a feature</h2>

          <pre><code data-trim>
~ $ git flow feature finish {name}
          </code></pre>

          <div class="fragment">
           <pre><code data-trim>
~ $ git flow feature finish foo

Switched to branch 'develop'
Updating 5c04d5a..6487134
Fast-forward
...
31 files changed, 5051 insertions(+)
Deleted branch feature/foo (was 6487134).

Summary of actions:
- The feature branch 'feature/foo' was merged into 'develop'
- Feature branch 'feature/foo' has been removed
- You are now on branch 'develop'
            </code></pre>
          </div>

          <p class="fragment">And repeat...</p>
        </section>

        <section>
          <h2>Releases</h2>
          <p><code>$ git flow release</code></p>
          <ul>
            <li class="fragment"><code>list</code>: lists existing releases</li>
            <li class="fragment"><code>start</code>: starts a new release</li>
            <li class="fragment"><code>finish</code>: finishes a release</li>
          </ul>
          <aside class="notes">
            Creates a new version of the prod code<br>
            I tend to do this at the end of each sprint
          </aside>
        </section>

        <section>
          <h2>Start a new release</h2>

          <pre><code data-trim>
~ $ git flow release start {version}
          </code></pre>

          <div class="fragment">
            <pre><code data-trim>
~ $ git flow release start 2014-03-02.0

Switched to a new branch 'release/2014-03-02.0'

Summary of actions:
- A new branch 'release/2014-03-02.0' was created, based on 'develop'
- You are now on branch 'release/2014-03-02.0'

Follow-up actions:
- Bump the version number now!
- Start committing last-minute fixes in preparing your release
- When done, run:

     git flow release finish '2014-03-02.0'
            </code></pre>
          </div>

          <aside class="notes">
            Final commits or bug fixes<br>
            Database export
          </aside>
        </section>

        <section>
          <h2>Finish a release</h2>
          <pre><code data-trim>
~ $ git flow release finish {version}
          </code></pre>
          <div class="fragment">
            <pre><code data-trim>
  ~ $ git flow release finish 2014-03-02.0

  ...

  Deleted branch release/2014-03-02.0 (was f2aee7d).

  Summary of actions:
  - Latest objects have been fetched from 'origin'
  - Release branch has been merged into 'master'
  - The release was tagged '2014-03-02.0'
  - Release branch has been back-merged into 'develop'
  - Release branch 'release/2014-03-02.0' has been deleted
            </code></pre>
          </div>

          <aside class="notes">
            Merges develop into master<br>
            Enter a tag message<br>
            Tags the release with the specified tag<br>
            Advanced options for release tag singing with GPG
          </aside>
        </section>

        <section>
          <h2>Pushing changes remotely</h2>
          <pre><code data-trim>
~ $ git push --all
# Push the changes to the remote branches.

~ $ git push --tags
# Push the tags.
          </code></pre>
        </section>

        <section>
          <h2>Tip: Finish a release in one command</h2>
          <pre><code data-trim>
~ $ git flow release finish -pm {message} {version}
# Specify a commit message and automatically push the changes.
          </code></pre>
          <div class="fragment">
            <pre><code data-trim>
~ $ git flow release finish -pm 2014-03-02.0 2014-03-02.0
            </code></pre>
          </div>
          <aside class="notes">
$ git flow release finish -pm "tag message" {branch}
          </aside>
        </section>

        <section>
          <h2>finish-sprint.sh</h2>
          <p><code>~ $ ./finish-sprint.sh 2014-03-02.1</code></p>
          <pre><code data-trim>
#!/bin/bash

DRUPAL_DIR="/path/to/drupal/docroot"
TAG=$1

if [ -z $TAG ]; then
  # A tag must be specified.
  echo 'You must specify a tag.'
fi

# Go into the Drupal directory
cd $DRUPAL_DIR

# Start a new Git Flow release.
git flow release start $TAG -F

# Flush the cache.
drush cc all

# Export the database
drush sql-dump --gzip --result-file=../db/$TAG.sql
git add ../db/$TAG.sql
git commit -m "Exported database for $TAG"

# Finish and push the release
git flow release finish -pm $TAG $TAG
          </code></pre>
        </section>

        <section>
          <h2>Hotfixes</h2>
          <p><code>$ git flow hotfix</code></p>
          <ul>
            <li class="fragment"><code>list</code>: list all hotfixes</li>
            <li class="fragment"><code>start</code>: start a hotfix</li>
            <li class="fragment"><code>finish</code>: finish a hotfix</li>
          </ul>
          <aside class="notes">
            Applies an emergency fix to your production code<br>
            Branches from master (by default)<br>
            Merges back into master and develop
          </aside>
        </section>

        <section>
          <h2>Create a new hot fix</h2>
          <pre class="fragment"><code data-trim>
~ $ git flow hotfix start {version}
          </code></pre>
          <pre class="fragment"><code data-trim>
~ $ git flow hotfix start 2014-03-02.2

Switched to a new branch 'hotfix/2014-03-02.2'

Summary of actions:
- A new branch 'hotfix/2014-03-02.2' was created, based on 'master'
- You are now on branch 'hotfix/2014-03-02.2'

Follow-up actions:
- Bump the version number now!
- Start committing your hot fixes
- When done, run:

     git flow hotfix finish '2014-03-02.2'
          </code></pre>
        </section>

        <section>
          <h2>Commit your fixes</h2>
          <pre><code data-trim>
~ $ git ci -am 'Updated .htaccess'
[hotfix/2014-03-02.2 6d04738] Updated .htaccess
 1 file changed, 4 insertions(+), 4 deletions(-)
        </code></pre>
        </section>

        <section>
          <h2>Finish the hot fix</h2>
          <pre><code data-trim>
~ $ git flow hotfix finish 2014-03-02.2
Switched to branch 'master'
Merge made by the 'recursive' strategy.
 .htaccess | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
Switched to branch 'develop'
Merge made by the 'recursive' strategy.
 .htaccess | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
Deleted branch hotfix/2014-03-02.2 (was 6d04738).

Summary of actions:
- Latest objects have been fetched from 'origin'
- Hotfix branch has been merged into 'master'
- The hotfix was tagged '2014-03-02.2'
- Hotfix branch has been back-merged into 'develop'
- Hotfix branch 'hotfix/2014-03-02.2' has been deleted
          </code></pre>
        </section>

        <section>
          <h2>Resources</h2>
          <ul>
            <li><a href="http://nvie.com/posts/a-successful-git-branching-model/">http://nvie.com/posts/a-successful-git-branching-model/</a></li>
            <li><a href="http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/">http://jeffkreeftmeijer.com/2010/why-arent-you-using-git-flow/</a></li>
            <li><a href="http://danielkummer.github.io/git-flow-cheatsheet/">http://danielkummer.github.io/git-flow-cheatsheet/</a></li>
            <li><a href="https://github.com/nvie/gitflow">https://github.com/nvie/gitflow</a></li>
            <li><a href="https://github.com/nvie/gitflow/wiki">https://github.com/nvie/gitflow/wiki</a></li>
          </ul>
        </section>

        <section>
          <h2>Demo</h2>
        </section>

        <section>
          <h2>Questions?</h2>
        </section>

        <section>
          <h2>Thanks</h2>
          <p>Feedback appreciated!</p>
          <ul>
            <li>Slides: <a href="http://www.oliverdavies.co.uk/git-flow">http://www.oliverdavies.co.uk/git-flow</a></li>
            <li>Session evaluation: <a href="http://2014.drupalcamplondon.co.uk/node/add/session-evaluation?nid=86">http://2014.drupalcamplondon.co.uk/node/add/session-evaluation?nid=86</a></li>
          </ul>
        </section>


			</div> <!-- /.slides -->
		</div> <!-- /.reveal -->

		<script src="lib/js/head.min.js"></script>
    <script src="js/reveal.min.js"></script>

    <script>
      // Full list of configuration options available here:
      // https://github.com/hakimel/reveal.js#configuration
      Reveal.initialize({
        controls: true,
        progress: true,
        history: true,
        center: true,

        theme: Reveal.getQueryHash().theme, // available themes are in /css/theme
        transition: Reveal.getQueryHash().transition || 'fade', // default/cube/page/concave/zoom/linear/fade/none

        // Parallax scrolling
        // parallaxBackgroundImage: 'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg',
        // parallaxBackgroundSize: '2100px 900px',

        // Optional libraries used to extend on reveal.js
        dependencies: [
          { src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
          { src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
          { src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
          { src: 'plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } },
          { src: 'plugin/zoom-js/zoom.js', async: true, condition: function() { return !!document.body.classList; } },
          { src: 'plugin/notes/notes.js', async: true, condition: function() { return !!document.body.classList; } }
        ]
      });
    </script>
	</body>
</html>