Logo
HomeAbout MeProjectsBlogsMemoriesContact
HomeAbout MeProjectsBlogsMemoriesContact

The Complete Git Guide: Enterprise Workflows, Best Practices & Cheat Sheet

Whether you are an entry-level software engineer, a senior tech lead, or a DevOps specialist, mastering Git is a core requirement for modern software development. Git is more than just a tool to back up code; it is an environment for team collaboration, quality control, and automated deployment.

This document serves as an end-to-end guide and production-grade cheatsheet covering Git architecture, branch management, commit conventions, release workflows, safety mechanisms, and advanced flag options.

Overview

Estimated Reading Time

35–40 minutes

Prerequisites

  • Basic command line knowledge
  • Git installed
  • A GitHub, GitLab, or Bitbucket account
  • Basic understanding of software development workflows (recommended but not required)

What You'll Learn

By the end of this guide, you will be able to:

  • Understand Git's internal architecture
  • Set up SSH authentication and configure productivity aliases on macOS and Windows
  • Choose the right branching strategy for your team
  • Work confidently with branches, commits, merges, and rebases
  • Recover from common Git mistakes and lost commits
  • Follow enterprise-grade Git workflows and best practices

Table of Contents

  • 1. The Git Mental Model

  • 2. Configuration & Repository Initialization

    • 2.1 First-Time Identity Configuration
    • 2.2 Authentication Methods: HTTPS vs. SSH
    • 2.3 Setting Up Git Aliases (macOS & Windows)
    • 2.4 Initializing and Cloning
    • 2.5 Ignoring Files (.gitignore)
  • 3. Enterprise Branching Strategies

    • 3.1 Comparing Branching Strategies
    • 3.2 Gitflow Branch Structure
  • 4. Branch Navigation & Cleanup

  • 5. Staging, Status & File Inspection

  • 6. Commit Conventions & Issue Linking

  • 7. Syncing, Merging & Rebasing

  • 8. Releases & Semantic Versioning (git tag)

  • 9. End-to-End Enterprise Workflow Execution

    • 9.1 Developing a New Feature
    • 9.2 Emergency Production Hotfix
  • 10. Emergency Room: Undoing Mistakes & Recovery

  • 11. Git Command Reference & Cheatsheet

  • 12. Core Operational Rules

1. The Git Mental Model

To use Git effectively, you must understand its four primary areas:

+-------------------+       git add       +------------------+
| Working Directory | ------------------> |   Staging Area   |
| (Unstaged Files)  | <------------------ |     (Index)      |
+-------------------+     git restore     +------------------+
                                                   |
                                                   | git commit
                                                   v
+-------------------+      git push       +------------------+
| Remote Repository | <------------------ | Local Repository |
| (GitHub/GitLab)   | ------------------> |      (.git)      |
+-------------------+      git fetch      +------------------+

  1. Working Directory: Your local workspace where you create, edit, and delete files.
  2. Staging Area (Index): A draft zone where you organize changes before committing them to history.
  3. Local Repository (.git): The local database containing all committed history and branch pointers on your machine.
  4. Remote Repository: The central server (e.g., GitHub, GitLab, Bitbucket) that facilitates team collaboration.

2. Configuration & Repository Initialization

2.1 First-Time Configuration

Set your identity globally across all repositories on your system:

# Set global identity
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"

# Set default main branch name
git config --global init.defaultBranch main

# Set default push behavior to push only current branch
git config --global push.default simple

# Verify configurations
git config --list

2.2 Authentication Methods

To interact with remote platforms like GitHub or GitLab, you must authenticate using either HTTPS or SSH.

MethodProsConsRecommendation
HTTPSEasy setup; works everywhere behind corporate firewalls.Requires Personal Access Tokens (PAT); passwords are no longer supported.Good for quick setup or read-only access.
SSHSeamless authentication via key-pair; no token expiration prompts.Requires initial key generation and setup.Recommended for daily development.

Option A: HTTPS Configuration

When cloning via HTTPS ([https://github.com/org/repo.git](https://github.com/org/repo.git)), modern Git clients use credential helpers to store your Personal Access Token (PAT):

# Enable credential helper (macOS Keychain)
git config --global credential.helper osxkeychain

# Enable credential helper (Windows Credential Manager)
git config --global credential.helper manager

Option B: SSH Configuration (Recommended)

  1. Generate an SSH Key (Ed25519 recommended):
ssh-keygen -t ed25519 -C "your.email@example.com"

  1. Start the SSH agent and add your private key:
# macOS / Linux / Windows Git Bash
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

  1. Copy the Public Key to Clipboard:
  • macOS: pbcopy < ~/.ssh/id_ed25519.pub
  • Windows (Git Bash): cat ~/.ssh/id_ed25519.pub | clip
  • Windows (PowerShell): Get-Content~\.ssh\id_ed25519.pub | Set-Clipboard
  1. Add Key to Remote Platform:
  • Go to GitHub / GitLab Settings -> SSH and GPG Keys -> New SSH Key and paste the content.
  1. Test SSH Connection:
ssh -T git@github.com
# Expected output: Hi username! You've successfully authenticated...

2.3 Setting Up Git Aliases

Aliases create short commands to increase daily development velocity.

Method 1: Git-Native Aliases (Cross-Platform)

These work universally across macOS, Linux, and Windows:

git config --global alias.st status
git config --global alias.co checkout
git config --global alias.sw switch
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.lg "log --oneline --graph --all"
git config --global alias.unstage "restore --staged"

Now you can run git st instead of git status.

Method 2: OS Shell Shortcuts

On macOS / Linux (Zsh / Bash)

Add shortcuts to your shell configuration file (~/.zshrc or ~/.bashrc):

# Open profile file
nano ~/.zshrc

# Add the following aliases:
alias g="git"
alias gst="git status"
alias gsw="git switch"
alias gcb="git switch -c"
alias gcm="git commit -m"
alias gpr="git pull --rebase"
alias glog="git log --oneline --graph --all"

# Reload profile
source ~/.zshrc

On Windows (Git Bash)

Edit or create ~/.bashrc in your user directory (C:\Users\YourName\.bashrc):

alias g="git"
alias gst="git status"
alias gsw="git switch"
alias gcb="git switch -c"
alias gcm="git commit -m"
alias gpr="git pull --rebase"
alias glog="git log --oneline --graph --all"

On Windows (PowerShell)

Open your PowerShell profile (notepad $PROFILE) and append:

function g { git $args }
function gst { git status $args }
function gsw { git switch $args }
function gcb { git switch -c $args }
function gcm { git commit -m $args }
function gpr { git pull --rebase $args }

2.4 Initializing and Cloning

# Initialize a new local Git repository in current directory
git init

# Clone a remote repository via HTTPS or SSH
git clone https://github.com/organization/repository.git
git clone git@github.com:organization/repository.git

2.5 Ignoring Files

Always create a .gitignore file at the root of your project to prevent sensitive or build files from entering the repository (e.g., node_modules/, .env, dist/, .DS_Store).

3. Enterprise Branching Strategies

3.1 Comparing Branching Strategies

There is no single "best" branching strategy for every team. Different organizations adopt different workflows depending on their release cadence, deployment model, team size, and compliance requirements.

The four most common strategies are:

StrategyBest ForCharacteristics
GitHub FlowStartups, SaaS, Continuous DeploymentSimple workflow using a single production branch and short-lived feature branches.
GitLab FlowTeams with staging environmentsExtends GitHub Flow with environment branches such as staging or production.
GitflowEnterprise products with scheduled releasesUses dedicated develop, release, and hotfix branches for controlled release cycles.
Trunk-Based DevelopmentLarge engineering organizations and CI/CDDevelopers integrate into a shared trunk frequently using short-lived branches or direct commits behind feature flags.

Which one should you choose?

  • Choose GitHub Flow if you deploy frequently and maintain a simple workflow.
  • Choose GitLab Flow if your deployment pipeline includes multiple environments such as staging and production.
  • Choose Gitflow if your organization follows scheduled release cycles and requires dedicated release management.
  • Choose Trunk-Based Development if your team practices Continuous Integration and Continuous Deployment (CI/CD) with frequent integrations.

3.2 Gitflow Branch Structure

This guide primarily uses Gitflow because it is still widely adopted by enterprises that maintain scheduled releases and multiple testing environments.


main (Production)
        ▲
        │
release/*
        ▲
        │
develop
   ▲
   │
feature/*

main

The production branch containing stable, production-ready code.

  • Protected branch
  • No direct commits
  • Deployment source
  • Tagged with release versions

develop

The integration branch where completed features are merged and tested before a release.

feature/*

Short-lived branches created from develop to implement individual features or bug fixes.

Examples:

feature/user-auth
feature/payment
feature/search

release/*

Created from develop when preparing a production release.

Typical activities include:

  • Final QA
  • Bug fixes
  • Documentation updates
  • Version bumping

hotfix/*

Created directly from main to fix critical production issues.

After deployment, the hotfix should be merged back into both:

  • main
  • develop

to prevent future releases from reintroducing the bug.

4. Branch Navigation & Cleanup

Git introduced git switch to replace the multi-purpose git checkout command for branch navigation, reserving git restore for file operations.

Listing Branches

git branch             # List local branches
git branch -r          # List remote branches (-r = --remotes)
git branch -a          # List both local and remote branches (-a = --all)

Branch Creation & Navigation

# Modern Approach (Recommended)
git switch dev                              # Switch to existing branch
git switch -c feature/user-auth             # Create (-c = create) and switch to new branch

# Legacy Approach
git checkout dev                            # Switch to existing branch
git checkout -b feature/user-auth           # Create (-b = branch) and switch to new branch

Deleting Branches

When work on a branch is merged and completed, clean up local and remote environments:

# Local Branch Deletion
git branch -d feature/user-auth             # Safe delete (-d): Fails if unmerged changes exist
git branch -D feature/user-auth             # Force delete (-D = -d --force): Overrides safety check

# Remote Branch Deletion
git push origin --delete feature/user-auth  # Delete branch on remote repository

5. Staging, Status, & File Inspection

Inspecting Changes

git status                                  # Display working tree and staging area state
git status -s                               # Compact status output (-s = --short)
git diff                                    # Show unstaged changes against staging area
git diff --staged                           # Show staged changes against last commit

Staging Files (git add)

git add file.js                             # Stage specific file
git add .                                   # Stage all new, modified, and deleted files in current dir
git add -A                                  # Stage all changes across entire repository (-A = --all)
git add -p                                  # Interactively stage chunks of code (-p = --patch)

Discarding Local Changes (git restore)

git restore file.js                         # Discard unstaged changes in local file
git restore .                               # Discard ALL unstaged local changes (DESTRUCTIVE)
git restore --staged file.js                # Unstage file (move back to working directory)

6. Commit Conventions & Issue Linking

Commit Flags (git commit)

  • -m "message": Inline commit message.
  • -a / --all: Automatically stage modified/deleted tracked files before committing.
  • -am "message": Combined shortcut for -a and -m.
  • --amend: Overwrite or modify the most recent commit.
# Standard Commit
git commit -m "feat(auth): add JWT token validation"

# Stage tracked files and commit in one command
git commit -am "fix(cart): correct price rounding error"

# Modify last commit message or add forgotten files
git add forgotten-file.js
git commit --amend --no-edit               # Keep original message, add new changes

Conventional Commit Specification

Follow standard commit formatting: <type>(<scope>): <short summary>

  • feat: A new feature for the user.
  • fix: A bug fix.
  • docs: Documentation only changes.
  • style: Changes that do not affect code logic (formatting, white-space).
  • refactor: Code change that neither fixes a bug nor adds a feature.
  • test: Adding or correcting existing tests.
  • chore: Maintenance tasks, updates to build tools, or dependencies.

Linking Issues (GitHub / GitLab / Jira)

Use trigger keywords in your commit message or Pull Request description to close linked issues automatically when merged into the main branch:

Keywords: Fixes #123, Closes #123, Resolves #123, Refs #123

git commit -m "fix(checkout): resolve Stripe API key exposure issue

Closes #104"

7. Syncing, Merging & Rebasing

Synchronizing Remote Changes

git fetch origin                            # Fetch remote metadata without modifying local code
git pull origin dev                         # Fetch and automatically merge remote branch into local
git pull --rebase origin dev                # Fetch and apply local commits ON TOP of remote commits

Why git pull --rebase?

By default, git pull performs a fetch followed by a merge. If both you and the remote branch have new commits, Git creates an additional merge commit, which can clutter the commit history over time.

Using git pull --rebase instead rewrites your local commits so they are replayed on top of the latest remote commits, resulting in a cleaner and more linear history.

Example:

Before pulling:

origin/dev

A──B──C

local

A──B──D──E

Using git pull:

A──B──C────────M
      \      /
       D────E

Using git pull --rebase:

A──B──C──D'──E'

The second history is easier to read, debug, and review because it avoids unnecessary merge commits.

Enterprise Best Practice

Use git pull --rebase on your local feature branches to keep commit history clean and minimize unnecessary merge commits.

When NOT to use it

Avoid rebasing commits that have already been shared with your team on a public branch, as rebasing rewrites commit history. Once a branch is shared, prefer merging unless your team's workflow explicitly allows rebasing.

Merging Strategies

# Standard Merge (creates a explicit merge commit)
git switch dev
git merge --no-ff feature/user-auth -m "merge: feature/user-auth into dev"

# Squash Merge (combines all branch commits into a single unified commit)
git switch dev
git merge --squash feature/user-auth
git commit -m "feat(auth): complete user authentication module"

  • --no-ff (No Fast-Forward): Ensures a merge commit is recorded even if the merge could be fast-forwarded. Preserves the history of the feature branch.
  • --squash: Flattens multiple micro-commits on a feature branch into one single commit before integrating.

8. Releases & Semantic Versioning

8.1 Versioning Format

Deployments are tracked using Git tags using Semantic Versioning (vMAJOR.MINOR.PATCH):

  • MAJOR: Incompatible API changes.
  • MINOR: Added functionality in a backward-compatible manner.
  • PATCH: Backward-compatible bug fixes.

8.2 Managing Tags

# Create an annotated tag (-a = annotated, -m = message)
git tag -a v1.0.0 -m "Production Release v1.0.0"

# List tags
git tag -l                                  # List all tags (-l = --list)

# Push tags to remote
git push origin v1.0.0                      # Push specific tag
git push origin --tags                      # Push all local tags to remote

9. End-to-End Enterprise Workflow

9.1 Scenario A: Developing a New Feature

# 1. Update dev branch
git switch dev
git pull --rebase origin dev

# 2. Create feature branch
git switch -c feature/payment-gateway

# 3. Work, stage, and commit changes
git add .
git commit -m "feat(payment): implement Stripe payment intent handler Closes #45"

# 4. Sync with dev before pushing (to catch potential conflicts early)
git fetch origin
git rebase origin/dev

# 5. Push branch and set upstream tracking (-u = --set-upstream)
git push -u origin feature/payment-gateway

# 6. Open Pull Request (PR) on GitHub/GitLab targeting 'dev'
# 7. Once approved and merged, clean up local branch
git switch dev
git pull origin dev
git branch -d feature/payment-gateway

9.2 Scenario B: Emergency Production Hotfix

# 1. Branch directly from production main
git switch main
git pull origin main
git switch -c hotfix/auth-bypass-vulnerability

# 2. Apply fix and commit
git commit -am "fix(security): patch authentication bypass vulnerability Closes #911"

# 3. Merge hotfix into main, tag it, and push
git switch main
git merge --no-ff hotfix/auth-bypass-vulnerability -m "merge: hotfix v1.0.1"
git tag -a v1.0.1 -m "Hotfix Release v1.0.1"
git push origin main --tags

# 4. Backport hotfix into dev so changes aren't lost in future releases
git switch dev
git merge --no-ff hotfix/auth-bypass-vulnerability -m "merge: backport hotfix v1.0.1 to dev"
git push origin dev

# 5. Clean up hotfix branch
git branch -d hotfix/auth-bypass-vulnerability
git push origin --delete hotfix/auth-bypass-vulnerability

10. Emergency Room: Undoing Mistakes & Data Recovery

Undoing Commits (git reset)

CommandWorking DirectoryStaging AreaCommit HistoryUse Case
git reset --soft HEAD~1KeptKept (Staged)UndoneRedo commit message or group commits.
git reset --mixed HEAD~1 (Default)KeptClearedUndoneModify staged files before re-committing.
git reset --hard HEAD~1DestroyedClearedUndoneDangerous. Completely destroy last commit and all local changes.

Reverting Public Commits (git revert)

If a bad commit is already pushed to a shared remote branch (main or dev), do not use reset. Use git revert to create a new inverse commit safely:

# Create a new commit that safely reverses changes from specified commit
git revert <commit-hash>
git push origin main

Temporary Workspace Storage (git stash)

Save dirty working directory state temporarily without committing:

git stash save "Work in progress on user checkout" # Save unstaged/staged changes
git stash list                                      # List saved stashes
git stash pop                                       # Apply last stash and remove it from stash list
git stash apply                                     # Apply last stash but keep it in stash list
git stash drop                                      # Remove last stash

Recovery of Lost Commits (git reflog)

Git keeps a log of every HEAD position movement. Even if you perform a git reset --hard, you can recover lost commits via reflog:

git reflog                                  # Display history of HEAD moves
# Output example: HEAD@{1}: reset: moving to HEAD~1
# Output example: HEAD@{2}: commit: feat(user): add user page

# Restore lost commit using hash or reference
git reset --hard HEAD@{2}

11. Git Command Reference & Cheatsheet

CategoryCommandCommon FlagsDescription
Configurationgit config--global<br>--listConfigure Git globally or locally, and display current configuration.
Repositorygit init—Initialize a new Git repository.
git clone<url>Clone an existing remote repository.
Branchinggit switch-c <branch>Create and switch to a new branch.
git branch-a<br>-r<br>-d<br>-DList all branches, list remote branches, safely delete a merged branch, or force delete a branch.
Inspectiongit status-sDisplay repository status in short format.
git diff--stagedCompare unstaged or staged changes.
git log--oneline<br>--graph<br>--allView commit history in a compact graph format.
Staginggit add.<br>-A<br>-pStage all files, all repository changes, or interactively stage selected hunks.
git restore--staged<br>.Unstage files or discard unstaged changes.
Commitgit commit-m<br>-am<br>--amendCreate commits, commit tracked changes directly, or modify the latest commit.
Synchronizationgit fetch--prune (-p)Fetch remote changes and remove deleted remote-tracking branches.
git pull--rebaseFetch and replay local commits on top of the latest remote commits.
git push-u<br>--tags<br>--delete<br>--force-with-leaseSet upstream branch, push tags, delete remote branches, or safely force-push.
Merginggit merge--no-ff<br>--squashCreate explicit merge commits or squash commits into a single commit.
Tagginggit tag-a<br>-lCreate annotated tags or list existing tags.
Recoverygit reset--soft<br>--mixed<br>--hardUndo commits while preserving, unstaging, or discarding local changes.
git revert<commit>Safely reverse a commit by creating a new commit.
git reflog—View HEAD history and recover lost commits.
git stashpush<br>pop<br>list<br>applyTemporarily save and restore uncommitted work.

12. Core Operational Rules for Engineers

  1. **Protect main and dev**: Require Pull Requests and mandatory code reviews before merging.
  2. Pull with Rebase: Keep your local history clean using git pull --rebase origin dev.
  3. Commit Atomically: Each commit should address a single, logical change.
  4. **Use force-with-lease over force**: When pushing rebased branches, use git push --force-with-lease to avoid overwriting a teammate's remote work.
  5. Clean up Merged Branches: Keep remote and local repositories free of abandoned feature branches using git branch -d and git push origin --delete.
© 2026 thisisduykhanh. All rights reserved.