Eliminate Workflow Friction with Git Joel Clermont @jclermont I come from the distant land of Milwaukee. Organizer of Milwaukee PHP and Milwaukee FP. Feel free to reach out to me on Twitter.
World s problems to be solved today Developers step on each other s changes Deployment gets blocked by a bad commit An irrational fear of git rebase Deployment is slow and clunky Works for me Good to set goals so you can know if this talk will be valuable to you. Only somewhat facetious in my goal. These are very common problems and can cause significant grief. If they can t be solved completely, we can certainly reduce the impact.
Assumptions
You use version control Please say you do. I won t shame you if you don t, but who isn t using any VCS? Maybe this talk will give you added incentive to start using VCS.
You use git Not an intro to git talk. You may be able to adapt this to Mercurial (I ve never tried). It will not be possible to do follow most of these suggestions with SVN or other centralized VCS.
Your mileage may vary Your problems may require a slightly different solution. These solutions are based on my experience and my specific problems. You will likely need to tweak them to work for your specific problems.
Developers step on each other s changes Even if you are a solo developer, this can happen to you. Future you can step on past you s changes.
Branches Other VCS have branching, but git is built around branching. I rarely used branches in SVN. I used them enough to realize how badly they break on merge.
master Fix bug 1234 Add captcha Git as SVN All work done in master Log authentication errors http://nvie.com/posts/a-successful-git-branching-model/ Evolution step one: all commits in master branch. Especially tempting when you are the only developer. Note reference to blog post. Source of some of my workflow ideas and the keynote template for generate git diagrams.
master Initial commit Feature Branches Add captcha work on more than one thing Log authentication errors Development is rarely 100% linear. Multiple devs, competing priorities, it becomes useful to be able to develop more than one feature at a time. Using feature branches facilitates this.
develop master Cleaner separation develop branch as sandbox Sometimes feature branches won t merge cleanly. If this happens in master, it can cause a more critical problem. Using a develop branch isolates master from most of these merge conflicts.
develop staging master Even more safety introduce a staging branch Adding a staging branch gives even more protection. Also useful if you have a formal QA/testing phase after development, but before deployment to production. This diagram is very simplified. Merging from dev to staging to master isn t usually this linear.
Go nuts! Here is the full workflow as proposed by the author of that blog post. This was more complex than what I needed, but it demonstrates how far you can go with branching.
Developers step on each other s changes Obviously not completely solved, but this technique makes it far less common and less difficult to resolve when it happens.
Deployment gets blocked by a bad commit Problem two! This happened to me all the time. Multiple features pending deployment, but an earlier feature failed testing or needs signoff, blocking everything merged after it. Bottlenecks are bad!
develop staging master Local QA Production Each branch becomes a deployment target First, it s important to recognize the correlation between branches and deployment targets. You can know what is deployed in each environment by looking at the corresponding branch. Normally I deploy the tip of a branch, but some choose to deploy a specific commit based on a tag.
How do we move feature branches? If things are merged chronologically, it s very easy. Life is far more messy however.
Scenario: Deploy a newer feature branch, skipping other pending features Dev finishes a large feature, but it needs time for thorough testing and review. Meanwhile, two bugs are fixed and need to get to production as soon as possible.
Option 1: hotfixes In the formal git flow model, things that need to be deployed to production ASAP get branched off of master. Called hotfixes. Then get back ported to dev later. Sometimes we don t know something is urgent when we start though.
Option 2: rebase/cherry-pick my preferred option Feature branches all still originate off develop branch.
Merge as late as possible Feature testing within feature branch This one is sort of obvious. Why even consider merging until you ve done basic testing.
Merge as late as possible Feature testing within feature branch Integration testing ALSO done in feature branch This one may seem counter-intuitive. How can we do integration testing without integrating it (merging it) back into develop so it can interact with all the new commits since we branched?
git rebase stay with me Rebase is something many git users fear. It s the source of scary campfire stories, but it has a useful place in my normal workflow.
Move forward in time not always about rewriting history Many describe rebase in terms of changing history. In a sense, that is what you are doing. Makes it as if you created a branch off current tip of develop, even if you really created it weeks ago. Hat tip to atlassian for image. (ref at end)
DANGER Only do this in feature branches no one else is working in DO NOT rebase your long running branches, only feature branches. DO NOT rebase a feature branch if others are adding new commits (okay if they are simply reviewing).
git push -f origin <branch> It s scary, but you re going to be okay.
You still may need to deploy out of order. No matter how late you try to merge a feature to develop, priorities change quickly and mistakes can be made. You still may want to deploy a newer feature but not an older feature.
git merge includes all history You will get those older features if you merge a newer feature. Merge is not the answer.
git cherry-pick one of the neglected git commands Basic idea: take a commit (or series of commits) and apply them to a specific branch. Unlike a merge, these are copied commits (new SHAs).
cherry-pick the merge commit requires the -m <n> flag (usually -m 1) A normal commit is clear. With a merge commit, you need to specify the parent (m is for main line). It will replay the commit based on the parent. You want the develop branch (usually -m 1). Compare SHAs to be sure.
use -n for greater sanity n = no-commit, many commands have a similar flag Let s you sanity check the cherry-pick before committing it. With git, you can easily undo before pushing, but -n just makes me feel better about myself.
Deployment gets blocked by a bad commit Now you can cherry-pick features out of order. Depending on the nature of the feature, you still may have dependencies, so you still may get blocked. But this will reduce many blocks. I will occasionally merge develop into staging into master as I get caught up
Deployment is slow and clunky This section is going to depend a lot on your hosting environment. Describe pain of deploying with FTP. Pick specific files, upload, wait, rinse, repeat. Have fun rewinding.
Sidebar: Shared Hosting Many people use shared hosting. Many shared hosts only offer FTP (no SSH) FTP is completely insecure. Find a new host. ServerGrove is a sponsor and offers a few shared hosting plans with SSH access. FTP is a very bad idea. I ve seen countless FTP accounts compromised with no failed attempts. Captured in the clear.
Alternative: VMs or PaaS VMs are cheap (Digital Ocean, ServerGrove) Often cheaper than many shared hosts PaaS - many have free tier (dotcloud, AppFog, AWS)
Life is too short for FTP My consulting company is No Compromises. One of the things I will not compromise on is bad shared hosting. I have turned down projects and fired clients who only have FTP.
PaaS deployment Most support monitoring a git repo / branch Staging server monitors staging branch, and so on. I do have some clients on PaaS and it works well, but it s not usually my favorite option. (unless you need to do dynamic auto-scaling with minimal effort)
VMs: my favorite VMs provisioned with Vagrant Exact same env on local, staging, production Exact same across team Solves a lot of works for me Don t get burned by OS X being case insensitive and Linux being case sensitive. One of many examples. VirtualBox (or VMWare) local, Digital Ocean / AWS in production.
Vagrant and git best of friends Vagrant is really just a few text files: Vagrantfile,.vagrant files. Even Puppet (my provisioner of choice) is just text. Easy to version for different environments.
Copying code rsync or git Vagrant will sync folders with rsync. I prefer to issue a Puppet command to git pull from my repo. Can also leverage git hooks with this approach.
Deployment is slow and clunky Push button deployment. Easy to roll back. Easy to manage separate environments. Consistent across team and environments.
So much more... Automatic options on branch checkout Hooks on commit or push to enforce style/tests Export git log to client invoices or work logs
Questions?
Feedback please! https://joind.in/talk/view/10061 First time giving this particular talk. Need help refining
References http://nvie.com/posts/a-successful-git-branching-model/ https://www.atlassian.com/git/tutorial/rewriting-git-history#! rebase http://think-like-a-git.net http://blog.doh.ms/2013/11/15/using-git-hooks-to-delegateroutine-tasks/ http://palantir.net/blog/how-git-what-you-want http://palantir.net/blog/git-workflow-2-features-boogaloo
Thank you!! https://joind.in/talk/view/10061 Catch me later or on Twitter to discuss in more depth.