Overview
Git workflows define structured approaches to managing branches, commits, and releases in version-controlled software projects. Two prominent workflows address different development contexts: GitFlow provides a comprehensive branching model for projects with scheduled releases, while GitHub Flow offers a simplified deployment-focused approach for continuous delivery environments.
GitFlow emerged in 2010 as a branching model designed around project releases. The workflow establishes specific branch types with defined purposes: long-lived branches for production and development code, supporting branches for features and releases, and hotfix branches for emergency production repairs. Teams using GitFlow maintain parallel development streams that converge at release points, creating a structured path from feature conception to production deployment.
GitHub Flow developed as a response to continuous deployment requirements where code moves to production multiple times daily. This workflow eliminates the complexity of multiple long-lived branches, using a single main branch representing production-ready code. All development occurs in feature branches that merge directly to main after review and testing, triggering immediate deployment.
The distinction between these workflows reflects fundamental differences in release cadence and team structure. GitFlow suits teams releasing on fixed schedules (weekly, monthly, quarterly) with distinct development and release phases. GitHub Flow serves teams practicing continuous deployment where any merged code reaches production within hours.
# GitFlow supports structured gem releases
# Branch: develop -> release/v2.1.0 -> main
# Tag: v2.1.0 after merge to main
# GitHub Flow supports continuous gem updates
# Branch: feature/add-validation -> main (auto-deploy)
# Tag: Generated automatically on merge
Both workflows address core version control challenges: preventing conflicts between concurrent development efforts, maintaining production stability, enabling emergency fixes, and providing clear release management. The choice between them depends on deployment frequency, team coordination requirements, and organizational release processes.
Projects using GitFlow gain explicit separation between development and production states, supporting parallel release preparation while development continues. Projects using GitHub Flow minimize branch management overhead and reduce integration delays, enabling rapid iteration cycles.
Key Principles
GitFlow operates on a dual-branch foundation where main (or master) contains production code and develop holds integrated development work. All changes originate from and eventually return to these core branches through intermediate branch types. Feature branches emerge from develop for new functionality, release branches prepare versions for production, and hotfix branches address critical production issues from main.
The workflow enforces strict merge directionality. Feature branches merge into develop after completion, incorporating new functionality into the integration branch. Release branches split from develop when features for a version complete, allowing final preparation without blocking ongoing development. After testing and bug fixes, release branches merge to both main and develop, synchronizing production deployment with continued development. Hotfix branches follow a similar bidirectional merge pattern, branching from main to fix critical issues and merging back to both main and develop.
# GitFlow branch lifecycle for Ruby gem
git checkout develop
git checkout -b feature/add-caching
# Development work occurs
git checkout develop
git merge feature/add-caching
git branch -d feature/add-caching
# Release preparation
git checkout -b release/1.5.0 develop
# Update version in gemspec
# Fix release-blocking bugs
git checkout main
git merge release/1.5.0
git tag -a v1.5.0 -m "Release version 1.5.0"
git checkout develop
git merge release/1.5.0
git branch -d release/1.5.0
GitHub Flow simplifies to a single principle: main always contains deployable code. Feature branches emerge from main for any change, regardless of size. Developers push branches to the remote repository early and open pull requests to signal work in progress. The pull request becomes a conversation hub for code review, automated testing, and continuous integration feedback.
Merging to main triggers deployment automatically or after brief manual approval. The workflow assumes robust automated testing validates changes before merge, and deployment automation handles the production release. No separate release preparation phase exists because continuous integration validates each change independently.
# GitHub Flow for Rails application
git checkout main
git pull origin main
git checkout -b feature/user-authentication
# Make changes, commit frequently
git push origin feature/user-authentication
# Open pull request on GitHub
# After review and CI passes
git checkout main
git merge feature/user-authentication
git push origin main
# Deployment triggers automatically
git branch -d feature/user-authentication
Both workflows mandate pull requests (or merge requests) for code review, though their timing differs. GitFlow pull requests occur when features complete and merge to develop, then again when releases merge to main. GitHub Flow uses a single pull request cycle from feature branch to main, consolidating review and deployment approval.
Branch protection rules enforce workflow discipline. Protected branches prevent direct commits, require pull request reviews, and mandate passing CI checks before merge. GitFlow typically protects both main and develop, while GitHub Flow focuses protection on main alone.
Tag management differs significantly between workflows. GitFlow creates tags on main after each release merge, marking production versions explicitly. GitHub Flow may tag releases but often relies on commit hashes or automated deployment versioning, as every main commit represents a potential production state.
Design Considerations
Team size influences workflow selection dramatically. Small teams (2-5 developers) often find GitFlow's branch management overhead excessive when everyone understands the current project state. GitHub Flow's simplicity reduces coordination overhead, allowing rapid iteration without formal release planning. Large teams (20+ developers) benefit from GitFlow's structure, as multiple parallel efforts require clear separation between development streams and production-ready code.
Release frequency determines workflow feasibility. Projects deploying multiple times daily cannot accommodate GitFlow's release branch preparation phase, as the delay contradicts continuous deployment goals. Projects releasing on fixed schedules (monthly, quarterly) gain value from GitFlow's explicit release preparation phase, which allows final testing and bug fixing without blocking feature development.
Testing infrastructure requirements differ between workflows. GitHub Flow demands comprehensive automated testing that validates changes completely before merge, as no separate testing phase exists. A passing CI build must guarantee production readiness. GitFlow accommodates less mature testing infrastructure by providing release branches for manual testing, staged deployments, and final validation before production release.
Risk tolerance affects workflow choice. Organizations requiring absolute production stability favor GitFlow's conservative approach where changes reach main only after release branch validation. Organizations accepting occasional production issues in exchange for deployment speed prefer GitHub Flow's rapid iteration, relying on quick rollback capabilities rather than prevention.
# GitFlow suits gem libraries with semantic versioning
# Minor releases every 2-3 months, patches as needed
module MyGem
VERSION = "2.3.0" # Updated in release branch
end
# GitHub Flow suits SaaS applications with continuous updates
# Deployments multiple times daily
module MyApp
VERSION = ENV['GIT_SHA'][0..7] # Generated from commit
end
Feature flag strategies complement workflow selection. GitHub Flow pairs naturally with feature flags that enable deploying incomplete functionality hidden behind toggles, allowing continuous integration while controlling feature visibility. GitFlow's longer feedback cycles make feature flags less critical, as features complete before merging to develop.
Rollback strategies differ significantly. GitHub Flow relies on reverting commits or deploying previous versions rapidly, assuming infrastructure supports quick deployment. GitFlow's tagged releases provide clear rollback targets, with production redeployments pointing to specific release tags rather than arbitrary commits.
Compliance and audit requirements influence workflow viability. Regulated industries requiring deployment approval chains and change documentation align naturally with GitFlow's explicit release branches and tag-based versioning. GitHub Flow's continuous deployment model requires additional tooling to capture deployment decisions and approval records.
Project maturity affects workflow suitability. Early-stage projects benefit from GitHub Flow's flexibility during rapid iteration phases when requirements change frequently. Mature projects with established features and defined release schedules gain value from GitFlow's structure, which supports parallel maintenance of multiple versions.
Geographic distribution impacts workflow selection. Distributed teams across many time zones struggle with GitHub Flow's assumption of rapid review and deployment cycles, as pull requests may await review for extended periods. GitFlow's longer cycles accommodate asynchronous work patterns, with features completing over days rather than hours.
Implementation Approaches
GitFlow implementation begins with initializing the branch structure. Create a develop branch from main to establish the parallel development stream. Configure branch protection for both branches to prevent accidental direct commits and require pull request reviews.
# Initialize GitFlow structure
git checkout main
git pull origin main
git checkout -b develop
git push origin develop
# Configure branch protection (via GitHub/GitLab UI or API)
# - Require pull request reviews
# - Require status checks to pass
# - Require branches to be up to date before merging
# - Restrict who can push to matching branches
Feature branch workflow in GitFlow follows a consistent pattern. Branch from develop, make changes, create a pull request back to develop. Feature branches may live for hours or weeks depending on feature complexity. Regular rebasing or merging from develop prevents integration conflicts.
# Feature development for Rails application
git checkout develop
git pull origin develop
git checkout -b feature/api-rate-limiting
# Implement rate limiting middleware
class RateLimitMiddleware
def initialize(app, limit: 100)
@app = app
@limit = limit
end
def call(env)
# Rate limiting logic
@app.call(env)
end
end
git add app/middleware/rate_limit_middleware.rb
git commit -m "Add API rate limiting middleware"
git push origin feature/api-rate-limiting
# Open pull request: feature/api-rate-limiting -> develop
Release branch creation occurs when develop contains sufficient features for a version. Branch from develop, update version numbers, fix release-blocking bugs, and prepare documentation. Release branches accept only bug fixes, not new features.
# Release preparation for Ruby gem
git checkout develop
git pull origin develop
git checkout -b release/3.0.0
# Update version in gemspec
Gem::Specification.new do |spec|
spec.name = "my_gem"
spec.version = "3.0.0" # Updated from 2.9.0
spec.summary = "My Ruby gem"
end
# Update CHANGELOG
# Fix release-blocking bugs only
git add lib/my_gem/version.rb CHANGELOG.md
git commit -m "Bump version to 3.0.0"
# Merge to main
git checkout main
git merge --no-ff release/3.0.0
git tag -a v3.0.0 -m "Release version 3.0.0"
git push origin main --tags
# Merge to develop
git checkout develop
git merge --no-ff release/3.0.0
git push origin develop
# Delete release branch
git branch -d release/3.0.0
git push origin --delete release/3.0.0
Hotfix branches address critical production issues requiring immediate deployment. Branch from main, fix the issue, merge to both main and develop (or current release branch if one exists).
# Emergency hotfix for production issue
git checkout main
git pull origin main
git checkout -b hotfix/security-patch
# Apply security fix
class UserController < ApplicationController
def show
@user = User.find(params[:id])
authorize! :read, @user # Added authorization check
render json: @user
end
end
git add app/controllers/user_controller.rb
git commit -m "Add authorization check to user show endpoint"
# Merge to main
git checkout main
git merge --no-ff hotfix/security-patch
git tag -a v2.5.1 -m "Security patch"
git push origin main --tags
# Merge to develop
git checkout develop
git merge --no-ff hotfix/security-patch
git push origin develop
git branch -d hotfix/security-patch
GitHub Flow implementation focuses on protecting main and streamlining the feature-to-deployment pipeline. Configure branch protection requiring reviews and passing CI checks. Establish deployment automation that triggers on merges to main.
# GitHub Flow setup
# 1. Protect main branch
# - Require pull request reviews (at least 1)
# - Require status checks (CI/CD) to pass
# - Require conversation resolution before merging
# - No direct pushes allowed
# 2. Configure CI/CD pipeline (example: GitHub Actions)
# .github/workflows/deploy.yml
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy
run: ./deploy.sh
Feature branches in GitHub Flow require descriptive names indicating the change purpose. Push branches early to enable collaboration and continuous integration feedback. Open pull requests while work progresses to facilitate discussion and incremental review.
# GitHub Flow feature development
git checkout main
git pull origin main
git checkout -b add-webhook-notifications
# Implement webhook notification system
class WebhookNotifier
def initialize(url)
@url = url
end
def notify(event, payload)
HTTP.post(@url, json: { event: event, payload: payload })
end
end
git add app/services/webhook_notifier.rb
git commit -m "Add webhook notification service"
git push origin add-webhook-notifications
# Open pull request immediately
# Continue development with additional commits
git commit -m "Add webhook retry logic"
git push origin add-webhook-notifications
Pull request workflow in GitHub Flow emphasizes continuous feedback. Request reviews from teammates, address feedback with additional commits, ensure CI passes completely. Merge only when the change is production-ready, as deployment follows immediately.
Deployment automation forms the critical final step. Configure deployment scripts or services to trigger on main branch updates. Include automated rollback mechanisms for rapid recovery from deployment issues.
Practical Examples
A Ruby gem release using GitFlow demonstrates the complete workflow cycle. The gem provides database query optimization for Rails applications, requiring careful version management and backward compatibility.
# Development phase: Multiple features in parallel
# Developer A: feature/query-caching
git checkout develop
git checkout -b feature/query-caching
class QueryCache
def fetch(key, &block)
@cache[key] ||= block.call
end
end
git commit -am "Implement query result caching"
git push origin feature/query-caching
# Pull request: feature/query-caching -> develop
# Developer B: feature/connection-pooling
git checkout develop
git checkout -b feature/connection-pooling
class ConnectionPool
def initialize(size: 5)
@pool = Array.new(size) { create_connection }
end
def with_connection(&block)
conn = @pool.pop
block.call(conn)
ensure
@pool.push(conn)
end
end
git commit -am "Add connection pooling support"
git push origin feature/connection-pooling
# Pull request: feature/connection-pooling -> develop
# Both features merge to develop
git checkout develop
git merge feature/query-caching
git merge feature/connection-pooling
# Release preparation
git checkout -b release/2.0.0 develop
# Update gemspec
Gem::Specification.new do |spec|
spec.name = "rails_db_optimizer"
spec.version = "2.0.0"
spec.files = Dir["lib/**/*"]
end
# Testing reveals connection leak in pooling
class ConnectionPool
def with_connection(&block)
conn = @pool.pop
block.call(conn)
ensure
@pool.push(conn) if conn # Fix: Check conn exists
end
end
git commit -am "Fix connection leak in pooling"
# Release completion
git checkout main
git merge --no-ff release/2.0.0
git tag -a v2.0.0 -m "Add caching and connection pooling"
git push origin main --tags
# Build and publish gem
gem build rails_db_optimizer.gemspec
gem push rails_db_optimizer-2.0.0.gem
git checkout develop
git merge --no-ff release/2.0.0
A Rails application deployment using GitHub Flow illustrates continuous deployment practices. The application serves API requests for a mobile application, requiring high availability and rapid iteration.
# Feature: Add user profile caching
git checkout main
git checkout -b cache-user-profiles
# Implement caching with feature flag
class UsersController < ApplicationController
def show
@user = if FeatureFlag.enabled?(:cache_profiles)
Rails.cache.fetch("user_#{params[:id]}", expires_in: 1.hour) do
User.find(params[:id])
end
else
User.find(params[:id])
end
render json: @user
end
end
git commit -am "Add user profile caching with feature flag"
git push origin cache-user-profiles
# Open pull request with detailed description
# PR description includes:
# - Performance metrics from staging environment
# - Cache invalidation strategy
# - Rollout plan using feature flag
# CI runs automatically:
# - Unit tests pass
# - Integration tests pass
# - Performance tests show 40% response time improvement
# Code review feedback addressed
git commit -am "Add cache invalidation on user update"
git push origin cache-user-profiles
# Approved and merged
git checkout main
git merge cache-user-profiles
git push origin main
# Deployment triggers automatically
# - Runs migrations (if any)
# - Deploys to production servers
# - Runs smoke tests
# - Feature flag remains disabled initially
# Gradual rollout
FeatureFlag.enable_for_percentage(:cache_profiles, 10)
# Monitor metrics, gradually increase to 100%
A production hotfix scenario demonstrates emergency response procedures. A security vulnerability requires immediate patching across both workflows.
# GitFlow hotfix approach
git checkout main
git pull origin main
git checkout -b hotfix/sql-injection-fix
# Fix SQL injection vulnerability
class SearchController < ApplicationController
def index
# Before: Vulnerable to SQL injection
# @results = User.where("name LIKE '%#{params[:q]}%'")
# After: Parameterized query
@results = User.where("name LIKE ?", "%#{params[:q]}%")
render json: @results
end
end
git commit -am "Fix SQL injection in search endpoint"
# Emergency review process
git push origin hotfix/sql-injection-fix
# Quick review (30 minutes instead of usual 2 hours)
git checkout main
git merge --no-ff hotfix/sql-injection-fix
git tag -a v1.8.1 -m "Security fix for SQL injection"
git push origin main --tags
# Emergency deployment to production
cap production deploy
git checkout develop
git merge --no-ff hotfix/sql-injection-fix
git push origin develop
# GitHub Flow hotfix approach
git checkout main
git checkout -b fix-sql-injection
# Same fix implementation
class SearchController < ApplicationController
def index
@results = User.where("name LIKE ?", "%#{params[:q]}%")
render json: @results
end
end
git commit -am "Fix SQL injection in search endpoint"
git push origin fix-sql-injection
# Emergency pull request with [URGENT] prefix
# Expedited review, CI runs in parallel
# Merge to main
git checkout main
git merge fix-sql-injection
git push origin main
# Deployment triggers immediately
# Production update completes in 5 minutes
Common Patterns
Branch naming conventions establish clarity across team members. GitFlow uses prefixes indicating branch type: feature/, release/, hotfix/. Feature branches include descriptive names: feature/user-authentication, feature/payment-integration. Release branches include version numbers: release/2.1.0, release/1.5.3. Hotfix branches describe the issue: hotfix/memory-leak, hotfix/security-patch.
GitHub Flow emphasizes descriptive branch names without strict prefixes. Names describe the change purpose: add-graphql-api, fix-login-redirect, update-ruby-version. Some teams adopt prefixes for organization: feature/add-graphql-api, bugfix/login-redirect. The key principle remains clarity about the branch's purpose.
# GitFlow naming in Ruby project
# feature/add-redis-caching
# feature/implement-oauth
# release/3.0.0
# hotfix/fix-race-condition
# GitHub Flow naming in Ruby project
# add-redis-caching
# implement-oauth-provider
# fix-authentication-race-condition
# update-dependencies
Commit message patterns improve repository history readability. Conventional commits provide structured messages: feat: add user authentication, fix: resolve memory leak in cache, docs: update API documentation. The pattern includes type (feat, fix, docs, refactor, test), optional scope, and description.
# Structured commit messages
git commit -m "feat(auth): implement JWT token validation"
git commit -m "fix(cache): prevent race condition in Redis operations"
git commit -m "refactor(models): extract validation logic to concern"
git commit -m "test(controllers): add request specs for API endpoints"
git commit -m "docs(readme): add deployment instructions"
Pull request templates standardize review information. Templates prompt authors to describe changes, list testing performed, identify breaking changes, and link related issues. Templates ensure reviewers receive consistent context.
## Description
Brief description of changes
## Type of Change
- [ ] Bug fix
- [ ] New feature
- [ ] Breaking change
- [ ] Documentation update
## Testing Performed
- Unit tests added/updated
- Integration tests pass
- Manual testing in staging environment
## Related Issues
Closes #123
## Deployment Notes
Any special deployment considerations
## Breaking Changes
List any breaking changes
Merge strategies affect repository history structure. GitFlow typically uses --no-ff (no fast-forward) merges to preserve branch history, creating explicit merge commits that show when features integrated. GitHub Flow may use squash merges to collapse feature branch commits into single commits on main, creating cleaner linear history.
# GitFlow merge preserving history
git checkout develop
git merge --no-ff feature/add-caching
# Creates merge commit showing feature integration point
# GitHub Flow squash merge for clean history
git checkout main
git merge --squash feature/add-caching
git commit -m "Add caching layer for API responses"
# Single commit on main, feature branch history discarded
Tag patterns differ between workflows. GitFlow creates semantic version tags on main after release merges: v1.0.0, v2.3.1. Tags correspond to gem versions or application releases. GitHub Flow may tag releases less formally, using continuous versioning: 2024.10.07.1 (date-based), or relying on commit SHAs for deployment references.
# GitFlow versioning in gemspec
Gem::Specification.new do |spec|
spec.version = "2.5.0" # Matches git tag v2.5.0
end
# GitHub Flow versioning with automated generation
Gem::Specification.new do |spec|
spec.version = ENV.fetch('GEM_VERSION') do
"0.0.1.#{`git rev-list --count HEAD`.strip}"
end
end
Release note patterns document changes between versions. GitFlow generates release notes from commits between release tags, organizing by feature, fix, and breaking change. GitHub Flow may generate notes from merged pull requests, using PR titles and labels for categorization.
CI/CD pipeline patterns integrate with workflow structure. GitFlow runs tests on feature branches and develop, with additional deployment validation on release branches. GitHub Flow runs comprehensive testing on every feature branch, treating passing tests as deployment authorization.
Tools & Ecosystem
Git-flow extensions automate GitFlow commands, reducing manual branch management. The git-flow tool provides high-level commands for branch creation and merging following GitFlow conventions.
# Install git-flow
# macOS: brew install git-flow
# Linux: apt-get install git-flow
# Initialize git-flow in repository
git flow init
# Prompts for branch naming conventions
# Defaults: main/develop, feature/, release/, hotfix/
# Feature development
git flow feature start user-authentication
# Creates feature/user-authentication from develop
# Make changes
git flow feature finish user-authentication
# Merges to develop, deletes feature branch
# Release management
git flow release start 2.0.0
# Creates release/2.0.0 from develop
# Update versions, fix bugs
git flow release finish 2.0.0
# Merges to main and develop, creates tag, deletes release branch
# Hotfix handling
git flow hotfix start security-patch
# Creates hotfix/security-patch from main
# Apply fix
git flow hotfix finish security-patch
# Merges to main and develop, creates tag, deletes hotfix branch
GitHub and GitLab provide workflow-supporting features. Branch protection rules enforce review requirements and CI passing before merge. Required status checks mandate specific tests pass. Codeowners files automatically request reviews from designated team members based on changed files.
# .github/CODEOWNERS
# Automatically request reviews based on files changed
# Ruby files reviewed by backend team
*.rb @backend-team
*.rake @backend-team
# Database migrations require additional approval
db/migrate/* @backend-team @database-team
# Configuration files require DevOps review
config/*.yml @devops-team
Dockerfile @devops-team
# Gemfile changes require security review
Gemfile @security-team
Gemfile.lock @security-team
Continuous integration services validate changes before merge. GitHub Actions, GitLab CI, CircleCI, and similar tools run test suites, linters, security scans, and deployment validations. Configuration specifies when tests run and what conditions must pass.
# .github/workflows/ci.yml
name: Ruby CI
on:
pull_request:
branches: [main, develop]
push:
branches: [main, develop]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
ruby-version: ['3.0', '3.1', '3.2']
steps:
- uses: actions/checkout@v2
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby-version }}
bundler-cache: true
- run: bundle exec rspec
- run: bundle exec rubocop
- run: bundle exec brakeman --no-pager
deploy:
needs: test
if: github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to production
run: ./deploy.sh
Gem release automation tools streamline Ruby library publishing. Tools like gem-release and rake-release automate version bumping, tag creation, and gem pushing to RubyGems.
# Rakefile with release automation
require 'bundler/gem_tasks'
# Automates:
# - Version bump in version.rb
# - Git commit and tag creation
# - Gem build
# - Gem push to RubyGems
# Usage with GitFlow:
# On release branch
rake release:guard_clean # Ensure clean working directory
rake release:build # Build gem
rake release:tag # Create git tag
rake release:push # Push to RubyGems
# Custom release task for GitFlow
task :gitflow_release, [:version] do |t, args|
version = args[:version]
sh "git checkout develop"
sh "git pull origin develop"
sh "git checkout -b release/#{version}"
# Update version file
File.write('lib/my_gem/version.rb', <<~RUBY)
module MyGem
VERSION = "#{version}"
end
RUBY
sh "git commit -am 'Bump version to #{version}'"
sh "git checkout main"
sh "git merge --no-ff release/#{version}"
sh "git tag -a v#{version} -m 'Release #{version}'"
sh "gem build my_gem.gemspec"
sh "gem push my_gem-#{version}.gem"
sh "git checkout develop"
sh "git merge --no-ff release/#{version}"
sh "git branch -d release/#{version}"
end
Deployment automation tools manage production releases. Capistrano, Kubernetes, and platform-as-a-service tools deploy code changes to production environments. Integration with GitHub Flow enables automatic deployment on merge to main.
# config/deploy.rb (Capistrano)
set :application, 'my_rails_app'
set :repo_url, 'git@github.com:company/my_rails_app.git'
# GitHub Flow: Deploy main branch
set :branch, 'main'
# Deployment tasks
namespace :deploy do
after :finishing, :restart_app
after :finishing, :notify_team
task :restart_app do
on roles(:app) do
execute :systemctl, 'restart', 'my_rails_app'
end
end
task :notify_team do
on roles(:app), in: :sequence do
revision = capture(:git, 'rev-parse', 'HEAD')
# Send notification with deployed revision
end
end
end
# Rollback capability
# cap production deploy:rollback
Reference
GitFlow Commands
| Operation | Command | Description |
|---|---|---|
| Initialize | git flow init | Set up GitFlow branch structure |
| Start feature | git flow feature start NAME | Create feature branch from develop |
| Finish feature | git flow feature finish NAME | Merge feature to develop |
| Start release | git flow release start VERSION | Create release branch from develop |
| Finish release | git flow release finish VERSION | Merge release to main and develop, create tag |
| Start hotfix | git flow hotfix start NAME | Create hotfix branch from main |
| Finish hotfix | git flow hotfix finish NAME | Merge hotfix to main and develop, create tag |
GitHub Flow Commands
| Operation | Command | Description |
|---|---|---|
| Create feature branch | git checkout -b BRANCH | Create branch from main |
| Push feature branch | git push origin BRANCH | Push to remote for CI/PR |
| Update from main | git pull origin main | Sync with latest main |
| Merge to main | git checkout main && git merge BRANCH | Integrate feature (after PR approval) |
| Delete feature branch | git branch -d BRANCH | Clean up after merge |
| Tag release | git tag -a VERSION -m MESSAGE | Mark production version |
Branch Types Comparison
| Branch Type | GitFlow | GitHub Flow | Lifespan | Merges To |
|---|---|---|---|---|
| main | Production code | Production code | Permanent | Never (receives merges) |
| develop | Integration branch | Not used | Permanent | main (via release) |
| feature | New functionality | New functionality | Days to weeks | develop (GitFlow) or main (GitHub Flow) |
| release | Version preparation | Not used | Hours to days | main and develop |
| hotfix | Emergency fixes | Emergency fixes | Hours | main and develop (GitFlow) or main (GitHub Flow) |
Workflow Selection Matrix
| Factor | GitFlow | GitHub Flow |
|---|---|---|
| Release frequency | Weekly, monthly, quarterly | Continuous, multiple per day |
| Team size | Medium to large (10+ developers) | Small to medium (2-10 developers) |
| Testing maturity | Manual and automated | Comprehensive automated |
| Risk tolerance | Low (prevention-focused) | Medium (recovery-focused) |
| Deployment complexity | Complex, staged rollouts | Simple, automated |
| Compliance requirements | High (audit trails, approvals) | Low to medium |
| Project maturity | Mature, established products | Early stage, rapid iteration |
Ruby Project Configuration
# GitFlow version management (config/version.rb)
module MyApp
MAJOR = 2
MINOR = 5
PATCH = 3
VERSION = [MAJOR, MINOR, PATCH].join('.')
end
# GitHub Flow dynamic versioning
module MyApp
VERSION = begin
sha = `git rev-parse --short HEAD`.strip
count = `git rev-list --count HEAD`.strip
"0.0.#{count}+#{sha}"
rescue
"0.0.0"
end
end
CI/CD Pipeline Stages
| Stage | GitFlow | GitHub Flow | Purpose |
|---|---|---|---|
| Unit tests | On feature branches | On feature branches | Validate individual components |
| Integration tests | On develop | On feature branches | Validate system integration |
| Security scans | On release branches | On feature branches | Identify vulnerabilities |
| Performance tests | On release branches | On main before deploy | Validate performance requirements |
| Deployment | Manual on main | Automatic on main | Release to production |
| Smoke tests | After deployment | After deployment | Verify production health |
Merge Strategy Comparison
| Strategy | Command | Result | Use Case |
|---|---|---|---|
| No fast-forward | git merge --no-ff | Preserves branch history, creates merge commit | GitFlow feature to develop |
| Fast-forward | git merge --ff-only | Linear history, no merge commit | Simple updates |
| Squash | git merge --squash | Single commit, loses branch history | GitHub Flow feature to main |
| Rebase | git rebase | Linear history, rewrites commits | Keeping feature branch current |
Common Branch Naming Patterns
GitFlow:
feature/add-user-authentication
feature/implement-caching
release/2.1.0
release/3.0.0-beta
hotfix/security-patch
hotfix/fix-memory-leak
GitHub Flow:
add-user-authentication
implement-redis-caching
fix-login-redirect-bug
update-dependencies-2024
refactor-user-model
Release Checklist
GitFlow Release Process:
- Verify develop branch tests pass
- Create release branch from develop
- Update version numbers in code
- Update CHANGELOG with release notes
- Run full test suite on release branch
- Fix release-blocking bugs only
- Merge release branch to main with --no-ff
- Create and push version tag
- Build and publish gem/deploy application
- Merge release branch to develop
- Delete release branch
GitHub Flow Release Process:
- Create feature branch from main
- Implement change with tests
- Push branch and open pull request
- Run CI tests automatically
- Request and complete code review
- Address review feedback
- Verify all CI checks pass
- Merge pull request to main
- Deployment triggers automatically
- Monitor deployment metrics
- Create release tag if needed