Git & GitOps
Duration: 100 min
Git is the foundation of modern software development and DevOps. GitOps extends Git principles to infrastructure management—treating infrastructure as code and using Git as the single source of truth. This module covers Git workflows, branching strategies, and GitOps tools like ArgoCD and Flux.
Git Fundamentals for DevOps
DevOps engineers must master Git beyond basic commits. Key concepts include:
- Branching strategies: How teams organize work
- Merge vs rebase: Different approaches to integrating changes
- Tags and releases: Marking stable versions
- Hooks: Automating checks before commits and pushes
- Collaboration: Pull requests, code review, and conflict resolution
Branching Strategies
GitFlow
GitFlow is a structured branching model suitable for scheduled releases:
# Create a feature branch from develop
git checkout -b feature/new-api develop
# Make changes and commit
git add .
git commit -m "Add new API endpoint"
# Create a pull request to develop
git push origin feature/new-api
# After review, merge to develop
git checkout develop
git merge --no-ff feature/new-api
# Create a release branch
git checkout -b release/1.0.0 develop
# Merge to main for production
git checkout main
git merge --no-ff release/1.0.0
git tag -a v1.0.0 -m "Release version 1.0.0"Trunk-Based Development
Trunk-based development uses short-lived branches and frequent merges to main:
# Create a short-lived feature branch
git checkout -b feature/quick-fix main
# Make minimal changes
git add .
git commit -m "Fix critical bug"
# Merge back to main quickly
git checkout main
git pull origin main
git merge --squash feature/quick-fix
git commit -m "Fix critical bug"
git push origin mainGit Workflows
Rebase vs Merge
# Merge: Creates a merge commit, preserves history
git checkout main
git merge feature/my-feature
# Result: Linear history with merge commit
# Rebase: Replays commits on top of main, cleaner history
git checkout feature/my-feature
git rebase main
git checkout main
git merge --ff-only feature/my-feature
# Result: Linear history without merge commitInteractive Rebase for Clean History
# Squash multiple commits into one
git rebase -i HEAD~3
# In the editor, change 'pick' to 'squash' for commits to combine
# pick abc1234 First commit
# squash def5678 Second commit
# squash ghi9012 Third commit
# Result: Single commit with combined changesGit Hooks for Automation
Git hooks run scripts at specific points in the Git workflow:
# Create a pre-commit hook to run linters
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
set -e
echo "Running linters..."
npm run lint
npm run format
echo "Running tests..."
npm test
echo "Pre-commit checks passed"
EOF
chmod +x .git/hooks/pre-commit
# Create a pre-push hook to prevent pushing to main
cat > .git/hooks/pre-push << 'EOF'
#!/bin/bash
protected_branch='main'
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [[ "$current_branch" == "$protected_branch" ]]; then
echo "ERROR: Cannot push directly to $protected_branch"
exit 1
fi
EOF
chmod +x .git/hooks/pre-pushGitOps Principles
GitOps treats infrastructure and application configuration as code stored in Git. The core principles are:
- Declarative: Infrastructure is described declaratively in Git
- Versioned & Immutable: All changes are tracked in Git history
- Pulled Automatically: A controller watches Git and applies changes
- Continuously Reconciled: The system continuously ensures actual state matches desired state
ArgoCD for GitOps
ArgoCD is a declarative, GitOps continuous delivery tool for Kubernetes:
# ArgoCD Application manifest
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-app
namespace: argocd
spec:
project: default
source:
repoURL: https://github.com/myorg/my-app
targetRevision: main
path: k8s/
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueDeploy with:
# Install ArgoCD
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
# Apply the application
kubectl apply -f argocd-app.yaml
# Access ArgoCD UI
kubectl port-forward svc/argocd-server -n argocd 8080:443
# Login at https://localhost:8080Flux for GitOps
Flux is another GitOps tool that continuously reconciles cluster state with Git:
# Flux HelmRelease for deploying a Helm chart
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: my-app
namespace: production
spec:
interval: 5m
chart:
spec:
chart: my-app
sourceRef:
kind: HelmRepository
name: myrepo
namespace: flux-system
values:
replicas: 3
image:
tag: v1.2.3Install Flux:
# Install Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash
# Bootstrap Flux on cluster
flux bootstrap github \
--owner=myorg \
--repo=my-cluster \
--branch=main \
--path=./clusters/production \
--personalGit Best Practices for DevOps
Commit Messages
# Good commit message format
git commit -m "feat: Add health check endpoint
- Implements /health endpoint for load balancers
- Returns 200 OK with service status
- Includes database connectivity check"
# Conventional Commits format
# feat: new feature
# fix: bug fix
# docs: documentation
# style: formatting
# refactor: code restructuring
# test: adding tests
# chore: maintenanceTag Management
# Create annotated tags for releases
git tag -a v1.0.0 -m "Release version 1.0.0"
# Push tags to remote
git push origin v1.0.0
git push origin --tags
# List tags
git tag -l
git show v1.0.0GitHub Actions for CI/CD
GitHub Actions integrates with Git to automate workflows:
name: Deploy on Push to Main
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Push to ECR
run: |
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin ${{ secrets.ECR_REGISTRY }}
docker push ${{ secrets.ECR_REGISTRY }}/myapp:${{ github.sha }}
- name: Deploy to ECS
run: |
aws ecs update-service \
--cluster production \
--service myapp \
--force-new-deployment❓ What is the main advantage of trunk-based development?
❓ What does a Git pre-commit hook allow you to do?
❓ What is the core principle of GitOps?
❓ What does ArgoCD do in a Kubernetes cluster?
❓ What is the benefit of using annotated tags in Git?