DevToolBoxGRATIS
Blog

Convenzione di nomi dei branch Git e strategia

8 min di letturadi DevToolBox

A well-defined git branch naming convention is the backbone of efficient team collaboration. When every developer follows the same naming pattern, code reviews become faster, CI/CD pipelines can automate deployments by branch type, and the entire commit history becomes self-documenting. This comprehensive guide covers the most popular branch naming strategies, enforcement techniques, and real-world examples for teams of every size.

Generate Git commands interactively with our Git Command Generator โ†’

Create URL-friendly slugs with our Slug Generator โ†’

Why Branch Naming Conventions Matter

Branch names are not just labels. They are communication tools that tell your team what work is happening, where it belongs, and how it should be handled. Without a consistent naming convention, repositories quickly become cluttered with branches like "fix", "test2", "johns-branch", and "final-final-v3". Here is why conventions matter:

Team collaboration: When a colleague sees feature/PROJ-123-add-oauth-login, they immediately know it is a feature branch, tied to ticket PROJ-123, and related to OAuth login. No Slack message needed.

CI/CD automation: Build systems can trigger different pipelines based on branch prefixes. Feature branches run tests only, release branches deploy to staging, and hotfix branches fast-track to production.

Readability and searchability: With hundreds of branches, consistent naming makes git branch --list "feature/*" and pull request filters actually useful. You can instantly find all work related to a specific area.

Automated cleanup: Scripts can identify and delete stale branches based on naming patterns, keeping your repository clean without manual intervention.

# Without conventions - chaos:
git branch
  fix
  test2
  johns-branch
  final-final-v3
  new-feature
  temp

# With conventions - clarity:
git branch
  feature/PROJ-101-user-dashboard
  feature/PROJ-102-search-api
  bugfix/PROJ-200-login-redirect
  hotfix/PROJ-301-payment-timeout
  release/2.1.0
  chore/upgrade-dependencies

Common Branch Prefixes

The most widely adopted convention uses a type prefix followed by a slash. Each prefix signals the intent and scope of the branch, making it immediately clear what kind of work the branch contains.

feature/ โ€” New functionality or enhancements. This is the most common prefix. Example: feature/user-profile-page, feature/JIRA-456-search-api

bugfix/ โ€” Non-urgent bug fixes scheduled for the next release. Example: bugfix/fix-login-redirect, bugfix/PROJ-789-null-pointer

hotfix/ โ€” Critical production fixes that need immediate deployment. Example: hotfix/payment-gateway-timeout, hotfix/security-patch-xss

release/ โ€” Release preparation branches for versioning and final testing. Example: release/2.1.0, release/2024-q1-sprint

chore/ โ€” Maintenance tasks, dependency updates, config changes. Example: chore/upgrade-node-20, chore/update-ci-config

docs/ โ€” Documentation-only changes. Example: docs/update-api-reference, docs/add-contributing-guide

test/ โ€” Adding or updating tests. Example: test/add-e2e-checkout-flow, test/increase-coverage-auth

refactor/ โ€” Code restructuring without changing behavior. Example: refactor/extract-payment-service, refactor/simplify-middleware

# Creating branches with proper prefixes
git checkout -b feature/add-user-authentication
git checkout -b bugfix/fix-cart-total-calculation
git checkout -b hotfix/critical-security-patch
git checkout -b release/3.0.0
git checkout -b chore/update-eslint-config
git checkout -b docs/add-api-documentation
git checkout -b test/add-integration-tests
git checkout -b refactor/extract-auth-module

Format Patterns and Examples

The most effective branch naming format combines a type prefix, an optional ticket number, and a short kebab-case description. Here are the most common patterns used across the industry:

Pattern 1: type/description โ€” Simple and clean, ideal for small teams or open-source projects without a ticketing system.

Pattern 2: type/TICKET-123-description โ€” The gold standard for enterprise teams. Links branches directly to issue trackers like Jira, Linear, or GitHub Issues.

Pattern 3: username/type/description โ€” Useful in large organizations where you need to know who owns a branch at a glance.

# Pattern 1: type/description (simple)
feature/add-dark-mode
bugfix/fix-email-validation
hotfix/patch-sql-injection

# Pattern 2: type/TICKET-ID-description (enterprise)
feature/PROJ-123-add-oauth-login
bugfix/PROJ-456-fix-null-pointer
hotfix/PROJ-789-fix-payment-gateway

# Pattern 3: username/type/description (large teams)
john/feature/add-search-filters
sarah/bugfix/fix-timezone-offset
alex/hotfix/fix-rate-limiter

# Creating a branch with ticket ID
git checkout -b feature/PROJ-123-add-oauth-login

# Listing branches by prefix
git branch --list "feature/*"
git branch --list "hotfix/*"
git branch --list "*/PROJ-123*"

Branch Naming Rules

Git has specific technical constraints on branch names, and teams add their own conventions on top. Following these rules prevents errors and keeps your repository consistent:

No spaces: Git does not allow spaces in branch names. Use hyphens (-) or underscores (_) as separators. Hyphens are the industry standard.

Allowed characters: Use lowercase alphanumeric characters, hyphens, underscores, and forward slashes. Avoid special characters like ~, ^, :, ?, *, [, \, and consecutive dots (..).

Max length: While Git technically allows up to 255 characters, keep branch names under 50-60 characters for readability. Long names are truncated in most Git UIs and become difficult to type.

Case convention: Use lowercase for everything. Mixing cases causes confusion and can create issues on case-insensitive file systems (like macOS and Windows). The only exception is the ticket ID, which is typically uppercase (e.g., PROJ-123).

No trailing dots or locks: Branch names cannot end with .lock or a period. They also cannot start with a hyphen.

# VALID branch names
feature/add-login-page
bugfix/PROJ-123-fix-null-check
release/2.1.0
chore/update-deps
john/feature/dark-mode

# INVALID branch names
feature/add login page       # spaces not allowed
feature/add..login           # consecutive dots not allowed
-feature/login               # cannot start with hyphen
feature/login.lock           # cannot end with .lock
feature/add~login            # tilde not allowed
feature/add:login            # colon not allowed

# Check if a branch name is valid before creating
git check-ref-format --branch "feature/my-new-branch"

# Rename a poorly named branch
git branch -m "bad name" feature/proper-name

Git Flow Branching Strategy

Git Flow, introduced by Vincent Driessen in 2010, is the most structured branching model. It uses multiple long-lived branches and a strict workflow that is ideal for projects with scheduled releases.

main (or master) โ€” Always reflects the production-ready state. Every commit on main should be a release that has been tested.

develop โ€” The integration branch where features come together. This branch always contains the latest delivered development changes for the next release.

feature/* โ€” Branched from develop, merged back into develop. Each feature gets its own branch.

release/* โ€” Branched from develop when features are complete. Used for final testing, version bumps, and documentation before merging into both main and develop.

hotfix/* โ€” Branched from main for critical production fixes. Merged back into both main and develop.

# Git Flow branch structure:
#
#  main โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ–ถ (production releases)
#                โ”‚            โ–ฒ          โ–ฒ
#                โ”‚         merge      merge
#                โ”‚            โ”‚          โ”‚
#  release/ โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€ release/2.0 โ”€โ”€โ”€โ”€โ”˜
#                โ”‚            โ–ฒ
#                โ”‚         merge
#                โ”‚            โ”‚
#  develop โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ–ถ (integration)
#            โ”‚       โ–ฒ   โ”‚        โ–ฒ
#         branch  merge branch  merge
#            โ”‚       โ”‚   โ”‚        โ”‚
#  feature/ โ”€โ”ดโ”€โ”€โ”€โ—โ”€โ”€โ”€โ”˜   โ””โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”˜
#
#  hotfix/ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ (from main, merge to main + develop)

# Start a new feature
git checkout develop
git checkout -b feature/PROJ-100-user-auth

# Complete a feature
git checkout develop
git merge --no-ff feature/PROJ-100-user-auth
git branch -d feature/PROJ-100-user-auth

# Start a release
git checkout develop
git checkout -b release/2.0.0

# Complete a release
git checkout main
git merge --no-ff release/2.0.0
git tag -a v2.0.0 -m "Release 2.0.0"
git checkout develop
git merge --no-ff release/2.0.0
git branch -d release/2.0.0

# Start a hotfix
git checkout main
git checkout -b hotfix/fix-critical-bug

# Complete a hotfix
git checkout main
git merge --no-ff hotfix/fix-critical-bug
git tag -a v2.0.1 -m "Hotfix 2.0.1"
git checkout develop
git merge --no-ff hotfix/fix-critical-bug
git branch -d hotfix/fix-critical-bug

GitHub Flow: Simplified Branching

GitHub Flow is a lightweight alternative to Git Flow. It has only one rule: anything on main is deployable. All work happens in feature branches that are merged via pull requests. This model works best for teams practicing continuous deployment.

The workflow is simple: (1) Create a branch from main, (2) Add commits, (3) Open a pull request, (4) Discuss and review code, (5) Deploy from the branch for testing, (6) Merge to main. There are no develop, release, or hotfix branches โ€” just main and feature branches.

# GitHub Flow workflow:
#
#  main โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—โ”€โ”€โ–ถ (always deployable)
#         โ”‚              โ–ฒ              โ–ฒ
#      branch         merge          merge
#         โ”‚              โ”‚              โ”‚
#         โ””โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€PRโ”€โ”˜    โ””โ”€โ”€โ—โ”€โ”€PRโ”€โ”€โ”˜
#           feature/login    feature/search

# Step 1: Create a feature branch from main
git checkout main
git pull origin main
git checkout -b feature/add-search-functionality

# Step 2: Work on your feature, commit often
git add .
git commit -m "Add search input component"
git add .
git commit -m "Implement search API endpoint"
git add .
git commit -m "Add search results pagination"

# Step 3: Push and open a pull request
git push -u origin feature/add-search-functionality
# Then open a PR on GitHub

# Step 4: After PR approval, merge to main
# (Usually done via GitHub UI with "Squash and merge" or "Merge")

# Step 5: Clean up
git checkout main
git pull origin main
git branch -d feature/add-search-functionality
git push origin --delete feature/add-search-functionality

Trunk-Based Development

Trunk-based development takes simplicity even further. Developers commit directly to a single branch (trunk/main) or use very short-lived feature branches that last hours, not days. This strategy requires strong test coverage and feature flags to manage unreleased code.

Short-lived branches: Feature branches exist for a few hours to at most two days. They are small, focused, and merged frequently to avoid divergence.

Feature flags: Incomplete features are hidden behind feature flags (also called feature toggles), allowing the code to be merged into main without being visible to users. This eliminates the need for long-running branches.

Continuous integration: Every commit to trunk triggers the full CI pipeline. The trunk is always in a releasable state. This is the model used by Google, Meta, and many high-performing engineering teams.

# Trunk-based development workflow:
#
#  main โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ—โ”€โ”€โ–ถ (trunk, always releasable)
#         โ”‚     โ–ฒ  โ”‚  โ–ฒ     โ”‚  โ–ฒ
#       branch  โ”‚ branch โ”‚  branch โ”‚
#         โ”‚  merge โ”‚  merge  โ”‚  merge
#         โ””โ”€โ”€โ—โ”€โ”€โ”˜  โ””โ”€โ”€โ—โ”€โ”€โ”˜  โ””โ”€โ”€โ—โ”€โ”€โ”˜
#        (hours)   (hours)   (hours)
#     short-lived feature branches

# Create a short-lived branch (will merge within hours)
git checkout main
git pull origin main
git checkout -b feature/add-tooltip-component

# Work quickly, commit small changes
git add src/components/Tooltip.tsx
git commit -m "Add Tooltip component with feature flag"

# Merge back quickly (same day)
git checkout main
git pull origin main
git merge feature/add-tooltip-component
git push origin main
git branch -d feature/add-tooltip-component

# Feature flag example (code merged but hidden)
# if (featureFlags.isEnabled('new-tooltip')) {
#   return <NewTooltip />;
# }
# return <OldTooltip />;

Automated Enforcement with Git Hooks

Conventions are only as good as their enforcement. Git hooks let you automatically validate branch names before code is pushed, ensuring every branch follows your team's naming rules.

The pre-push hook runs locally before any push reaches the remote. It can check the branch name against a regex pattern and reject pushes from non-conforming branches.

Git Hook: pre-push

Create a .git/hooks/pre-push script that validates branch names before pushing:

#!/bin/bash
# .git/hooks/pre-push - Validate branch naming convention

BRANCH=$(git symbolic-ref --short HEAD)

# Allow main, develop, and HEAD (detached)
if [[ "$BRANCH" == "main" || "$BRANCH" == "develop" || "$BRANCH" == "HEAD" ]]; then
  exit 0
fi

# Regex pattern for valid branch names
# Matches: feature/PROJ-123-description, bugfix/description, etc.
PATTERN="^(feature|bugfix|hotfix|release|chore|docs|test|refactor)/[a-zA-Z0-9._-]+(/?[a-zA-Z0-9._-]+)*$"

if [[ ! "$BRANCH" =~ $PATTERN ]]; then
  echo "ERROR: Branch name '$BRANCH' does not match naming convention."
  echo ""
  echo "Branch names must follow the pattern:"
  echo "  type/description"
  echo "  type/TICKET-123-description"
  echo ""
  echo "Valid prefixes: feature, bugfix, hotfix, release, chore, docs, test, refactor"
  echo ""
  echo "Examples:"
  echo "  feature/PROJ-123-add-login"
  echo "  bugfix/fix-email-validation"
  echo "  hotfix/critical-security-patch"
  exit 1
fi

exit 0

Husky is the most popular tool for managing Git hooks in JavaScript/TypeScript projects. It makes hook installation and sharing across the team effortless.

Husky + commitlint Setup

# Install Husky and set up hooks
npm install --save-dev husky
npx husky init

# Create the pre-push hook
cat > .husky/pre-push << 'EOF'
#!/bin/bash
BRANCH=$(git symbolic-ref --short HEAD)

if [[ "$BRANCH" == "main" || "$BRANCH" == "develop" ]]; then
  exit 0
fi

PATTERN="^(feature|bugfix|hotfix|release|chore|docs|test|refactor)/[a-zA-Z0-9._-]+$"

if [[ ! "$BRANCH" =~ $PATTERN ]]; then
  echo "Branch name '$BRANCH' does not follow naming convention."
  echo "Use: type/description (e.g., feature/add-login)"
  exit 1
fi
EOF

chmod +x .husky/pre-push

# Verify it works
git checkout -b invalid-name
git push  # Will be rejected by the hook

git checkout -b feature/valid-branch-name
git push  # Will succeed

CI/CD Integration with Branch Patterns

Modern CI/CD systems use branch patterns to trigger different workflows. By following a consistent branch naming convention, you can automate your entire build, test, and deploy pipeline based on branch prefixes.

GitHub Actions uses on.push.branches and glob patterns to match branch names. You can run different jobs for feature, release, and hotfix branches.

GitHub Actions

# .github/workflows/ci.yml
name: CI Pipeline

on:
  push:
    branches:
      - main
      - develop
      - 'feature/**'
      - 'bugfix/**'
      - 'hotfix/**'
      - 'release/**'
  pull_request:
    branches: [main, develop]

jobs:
  # Run tests on ALL branches
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci
      - run: npm test

  # Deploy to staging only on release branches
  deploy-staging:
    needs: test
    if: startsWith(github.ref, 'refs/heads/release/')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: ./deploy.sh staging

  # Deploy to production only on main
  deploy-production:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: ./deploy.sh production

  # Fast-track hotfixes
  deploy-hotfix:
    needs: test
    if: startsWith(github.ref, 'refs/heads/hotfix/')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - run: ./deploy.sh hotfix-staging

  # Validate branch name
  validate-branch:
    runs-on: ubuntu-latest
    steps:
      - name: Check branch name
        run: |
          BRANCH=${GITHUB_REF#refs/heads/}
          PATTERN="^(main|develop|(feature|bugfix|hotfix|release|chore|docs|test|refactor)/.+)$"
          if [[ ! "$BRANCH" =~ $PATTERN ]]; then
            echo "::error::Branch '$BRANCH' does not follow naming convention"
            exit 1
          fi

GitLab CI uses the rules keyword with regex patterns to control which jobs run on which branches. This allows fine-grained pipeline control based on branch naming.

GitLab CI

# .gitlab-ci.yml
stages:
  - validate
  - test
  - deploy

validate-branch-name:
  stage: validate
  script:
    - |
      PATTERN="^(main|develop|(feature|bugfix|hotfix|release|chore|docs|test|refactor)/.+)$"
      if [[ ! "$CI_COMMIT_BRANCH" =~ $PATTERN ]]; then
        echo "Branch name does not follow convention: $CI_COMMIT_BRANCH"
        exit 1
      fi
  rules:
    - if: $CI_PIPELINE_SOURCE == "push"

test:
  stage: test
  script:
    - npm ci
    - npm test
  rules:
    - if: $CI_COMMIT_BRANCH

deploy-staging:
  stage: deploy
  script:
    - ./deploy.sh staging
  rules:
    - if: $CI_COMMIT_BRANCH =~ /^release\/.+$/

deploy-production:
  stage: deploy
  script:
    - ./deploy.sh production
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

Protected Branch Rules

Protected branches prevent direct pushes and enforce code review. Combined with naming conventions, they create a robust workflow where critical branches cannot be accidentally modified.

Protect main and develop: Require pull request reviews before merging. No direct pushes allowed. Enable status checks (CI must pass) and require up-to-date branches before merging.

Branch protection patterns: GitHub and GitLab both support wildcard patterns. You can protect all release branches with release/* and all hotfix branches with hotfix/*.

# GitHub CLI: Configure branch protection rules
# Protect main branch
gh api repos/{owner}/{repo}/branches/main/protection \
  --method PUT \
  --field required_status_checks='{"strict":true,"contexts":["test"]}' \
  --field enforce_admins=true \
  --field required_pull_request_reviews='{"required_approving_review_count":2}' \
  --field restrictions=null

# List protected branches
gh api repos/{owner}/{repo}/branches --jq '.[] | select(.protected) | .name'

# View protection rules for a branch
gh api repos/{owner}/{repo}/branches/main/protection

# GitHub branch ruleset (newer approach, supports wildcards)
# Settings > Rules > Rulesets > New ruleset
# Target branches: main, develop, release/*, hotfix/*
# Rules:
#   - Require pull request before merging (2 approvals)
#   - Require status checks to pass
#   - Require branches to be up to date
#   - Block force pushes
#   - Block deletions

Examples by Project Type

Different project types and team sizes benefit from different conventions. Here are practical recommendations:

Open Source Projects: Use simple prefixes without ticket numbers. Contributors should not need access to your issue tracker to name a branch. Pattern: feature/add-dark-mode, fix/broken-link-readme. Keep the CONTRIBUTING.md updated with naming rules.

Startups (2โ€“10 developers): Use GitHub Flow with short prefixes and optional ticket IDs. Speed matters more than ceremony. Pattern: feat/onboarding-flow, fix/signup-validation. Use Linear or GitHub Issues for lightweight tracking.

Enterprise Teams (50+ developers): Use Git Flow with mandatory ticket IDs and owner prefixes. Automate enforcement with hooks and CI. Pattern: feature/PROJ-1234-payment-refund-api, hotfix/PROJ-5678-fix-rate-limiter. Every branch must map to a tracked issue.

# Open Source Project
feature/add-dark-mode
feature/improve-accessibility
fix/broken-link-readme
fix/typo-contributing-guide
docs/update-installation-guide
chore/upgrade-to-react-19

# Startup (GitHub Flow)
feat/onboarding-flow
feat/stripe-integration
fix/signup-validation
fix/mobile-responsive-nav
chore/setup-sentry

# Enterprise (Git Flow + Jira)
feature/PROJ-1234-payment-refund-api
feature/PROJ-1235-admin-dashboard-v2
bugfix/PROJ-2001-currency-rounding-error
hotfix/PROJ-3001-fix-rate-limiter
release/4.2.0
chore/PROJ-4001-upgrade-java-21
john.doe/feature/PROJ-1236-audit-logging

Frequently Asked Questions

What is the best git branch naming convention?

The best convention depends on your team size and workflow. For most teams, the pattern type/TICKET-123-short-description works well. Use prefixes like feature/, bugfix/, hotfix/, release/, and chore/ to categorize work. The key is consistency โ€” pick a format and enforce it across the entire team with Git hooks or CI checks.

Should I use slashes or hyphens in branch names?

Use both, but for different purposes. Slashes (/) separate the branch type prefix from the description (e.g., feature/add-login). Hyphens (-) separate words within the description. This creates a clear hierarchy that Git UIs display as folders. Avoid underscores as the primary separator, though they are valid.

How long should a git branch name be?

Keep branch names under 50-60 characters. While Git allows up to 255 characters, shorter names are easier to read in terminal output, Git GUIs, and pull request lists. A good branch name should be descriptive enough to understand at a glance but concise enough to type without errors. Example: feature/PROJ-123-add-oauth is better than feature/PROJ-123-add-oauth-login-with-google-and-github-providers.

Can I rename a git branch after creating it?

Yes. Use "git branch -m old-name new-name" to rename a local branch, or "git branch -m new-name" if you are on the branch you want to rename. If you have already pushed the old branch, you need to push the new name and delete the old one on the remote: "git push origin new-name" followed by "git push origin --delete old-name". Be careful with branches that have open pull requests, as the PR will still reference the old name.

How do I enforce branch naming conventions in a team?

Use a combination of Git hooks and CI checks. Locally, set up a pre-push hook (using Husky for JS projects or a custom script) that validates the branch name against a regex pattern. On the server side, configure branch protection rules in GitHub or GitLab to only allow branches matching specific patterns. You can also add a CI job that fails if the branch name does not match your convention. Document the rules in your CONTRIBUTING.md file.

A consistent git branch naming convention transforms a messy repository into an organized, automated, and self-documenting codebase. Start with the basics, enforce with hooks, and iterate as your team grows. Try our tools below to streamline your Git workflow.

Try the Git Command Generator โ†’

Create URL-friendly branch names with Slug Generator โ†’

๐• Twitterin LinkedIn
รˆ stato utile?

Resta aggiornato

Ricevi consigli dev e nuovi strumenti ogni settimana.

Niente spam. Cancella quando vuoi.

Prova questi strumenti correlati

๐Ÿ”€Git Command Generator๐Ÿ”—URL Slug Generator.gi.gitignore Generator

Articoli correlati

Git Commands Cheat Sheet: Comandi essenziali per ogni sviluppatore

Cheat sheet completo dei comandi Git: setup, branching, merging, rebasing, stashing e workflow avanzati.

Git Rebase vs Merge: Quando usare quale (con esempi visivi)

Comprendere la differenza tra git rebase e merge. Quando usare ciascuno ed evitare errori comuni.