Skip to content

Instantly share code, notes, and snippets.

@GaryJones
Created March 29, 2013 16:41
Show Gist options
  • Save GaryJones/5271998 to your computer and use it in GitHub Desktop.
Save GaryJones/5271998 to your computer and use it in GitHub Desktop.
Genesis workflow using GitFlow.

Genesis Framework workflow on GitHub

General procedure is to follow the established GitFlow model.

Initial Setup

Assuming the move happens right after 2.0.0 is released.

  • All SVN tags moved in as Git Tags.
  • Code SVN tagged as 2.0.0 moved to Git master branch
  • Git master branch is branched to develop.

If work after 2.0.0 has already been committed to SVN trunk, then SVN trunk is moved to Git develop branch instead.

Workflow

Bug Fixes and Enhancements

  • All normal commits and pull requests made to develop branch.
  • If Joe Dev wants to address a simple bug or enhancement, they fork repo, create a branch on their repo, commit against that, and do a pull request back to develop branch. What Joe Dev calls his branch on his own repo is up to him. Branches created via the GitHub website will be called patch-*, but otherwise, recommendation is to stick with feature/IssueNumber or feature/featurename.
  • If it's a major feature or rewrite (especially from StudioPress folks), then a feature/featurename branch should be created from the develop branch. Once the feature is deemed complete, then it can be merged into develop. This means that if the feature is punted or scrapped, no reversing needs to be done on develop.
  • Consider recommending that all multi-commit branches are squashed into a single (or few if large) atomic commit, since it makes tracking the overall changes to Genesis far easier (i.e. the addition of HTML5 to Genesis, or the CSS re-org could be seen as a single commit, rather than 20+).

Hotfix

If a critical bug is found in a release (say 2.0.0) that warrants an urgent release (2.0.1), then the workflow is slightly different:

  • Create a hotfix/versionnumber branch from the master branch.
  • Fix the bug[s].
  • Proceed with release as below.

Release

GitFlow says that up until this point, all of the develop branch is just working on the next version, whatever that may be. In reality for Genesis, due to the unsemantic versioning, we know the next version after 2.0.0 will be 2.1.0, outside of any bug fix releases.

  • When the code is deemed ready for a release, create a release/releasenumber branch from develop. (If releasing a hotfix, don't create a release branch but stay on the hotfix/* branch)
  • Update the release timestamp, version number, database number, update functions, and whatever other pre-tag tasks Nathan does.
  • When everything is completely done, merge into master AND into develop. This should be the only time the master branch gets updated.
  • Create a tag from master branch.

General

  • Keep the same branch naming format as GitFlow - no explanation is then needed for what branch is for what, for those with familiarity of GitFlow.
  • All commits should include a reference to an Issue. If there's no issue, create it, so there's a place for further discussion or to group related commits. When committing to my feature branch, my commit message can reference an Issue on the Genesis repo, and that gets updated / closed automatically once my branch is merged.
  • If adding a feature may need more than one commit, then that feature should be built in a feature/* branch, then merged into develop when it's complete. That includes when the code is working but a check on the documentation would be beneficial before adding to develop, or when the CSS is being re-organized in stages etc.
@remkus
Copy link

remkus commented Mar 29, 2013

That is 100% what I would recommend. Word for word. Branching, rebasing and merging will become second nature. Also good to know that there are quite a few apps out there that support this gitflow model such as Tower and SourceTree (both Mac apps btw)

@christophercochran
Copy link

Agree with completely. Especially keeping master as the stable version, allowing hot-fixes easily while still developing new features and upgrades for the upcoming version. Work in a simliar fashion for many projects of my own, solo and in groups.

@tnorthcutt
Copy link

+1 From me, this all looks great.

I think following semantic versioning is worth discussing. I don't know if that's a viable option for Genesis, but perhaps we could have that conversation.

@nathanrice
Copy link

Considering our backgrounds (WordPress has been on SVN for years) working with SVN for version control, can someone let me know exactly a system like the one outlined above is overwhelmingly superior to something like:

Use master branch like you would use trunk in SVN
Use tags like you would use tags in SVN
Potentially keep a "stable" branch to indicate latest stable release.

Workflow is this:

  1. Submit pull requests against master
  2. Accepted pull requests go into master
  3. When a new release is ready, tag it.
  4. x.x.x is what you call a hotfix.

If you want to create a temporary branch for a feature, sure, go for it. Let other people pull your fork to test. But once it's verified as working, it goes in master.

I'm not dismissing the possibility of my being very very wrong about all this, or missing some key benefit that will make it all make sense. I've just not heard a compelling reason to do it this way. "People get used to it" isn't compelling.

@GaryJones
Copy link
Author

Maybe try not to think of the definitive terms that are "master" and "develop". Git isn't SVN, so don't try to map your understanding of one workflow or default directory structure directly to the other. The branches could be called anything, but we should keep the defaults as they are to avoid confusing anyone. Apart from that, your workflow can match up quite nicely:

Use develop branch like you would use trunk in SVN
Use tags like you would use tags in SVN
Potentially keep a "stable" branch to indicate latest stable release (yes, called master).

The trouble with "But once it's verified as working, it goes in master." is that you've got no clean source from which to create a hotfix, without checking out your local repo back to a specific commit, then forking from there, otherwise 2.0.1 has bits of 2.1.0 in it as well, which may not be ready, tested or documented.


Had we been doing SVN right, then all features for that should have been done on SVN branches before merging into trunk. SVN branches are heavy though (a full copy of all files), but Git branches are not (single commit identifier in a single file), hence all we're doing is applying a proper range of version control that wasn't practical in a hosted SVN. With local Git repos, I don't need you to create a feature branch and push to Assembla before I can pull it down and work on it.

There's so many projects using develop (or some non-master equivalent) as their head of development - with the formulation of git-flow, it's a common practice for all but the simplest of repos. Sticking with it gives a far more structured repo. The thing about git-flow is that it's pretty much just the way you'll end up using git if you really understand branching and merging. It's not really very far from the workflow for Git itself.

@tnorthcutt
Copy link

Here's a potentially helpful article on how to think about a DVCS (git, mercurial) as compared to SVN: http://www.joelonsoftware.com/items/2010/03/17.html

@nathanrice
Copy link

The trouble with "But once it's verified as working, it goes in master." is that you've got no clean source from which to create a hotfix

Well, that's not technically true. If you maintained a "stable" branch (or perhaps had a "releases" branch with releases/1.9.0, releases/2.0.0, etc.) you could mod against that and tag. But that does start to get convoluted. With SVN, you could just do

svn cp tags/2.0.0 tags/2.0.1
apply fixes
svn ci -m 'Tagging 2.0.1'

You could do this with Git, but it's definitely not as easy.

If master is stable, and develop is trunk, the only issue is making sure that pull requests get done against develop, no master. Which means a clone would have to look like:

git clone [email protected]:your-fork/genesis.git
git checkout develop

The extra step isn't unreasonable, considering the above.

OK (and I'm still learning here), how does this sound ...

  1. master -> stable, latest public release
  2. develop -> trunk, bleeding accepted code
  3. tags -> tag releases, 1.9.0, 1.9.1, 2.0.0, 2.0.1, etc.

When a release is ready, develop is merged into master, and a tag is generated from master.

It's not SVN, but it's not an extreme deviation. People will probably need to rebase a lot, or submit pull requests from temporary branches. If history is any indicator, not every patch will be accepted.

I'll maintain my own fork, just so I'm familiar with the process from the end user's perspective along the way. I really want contribution to be more about the project and less about the process, as much as possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment