Version control with Git for efficient collaboration and code management

Git Complete Guide

15 min read

Introduction to Git

Git is a distributed version control system that enables multiple developers to work on the same codebase without conflicts. It tracks changes, maintains history, and facilitates collaboration, making it essential for modern software development and DevOps practices.

Git Architecture and Core Concepts

Key Terminology

  • Repository: Storage location for your project and its history
  • Commit: Snapshot of changes at a specific point in time
  • Branch: Independent line of development
  • Merge: Combining changes from different branches
  • Remote: Repository hosted on a server or service
  • Clone: Creating a local copy of a remote repository

Git Installation and Setup

Installing Git

# Ubuntu/Debian
sudo apt update
sudo apt install git

# RHEL/CentOS
sudo yum install git

# macOS
brew install git

# Windows
# Download from https://git-scm.com/download/win

# Verify installation
git --version

Basic Configuration

# Global configuration
git config --global user.name "Your Name"
git config --global user.email "your.email@example.com"
git config --global init.defaultBranch main

# Editor preferences
git config --global core.editor "code --wait"  # VS Code
git config --global core.editor "vim"          # Vim

# Useful aliases
git config --global alias.co checkout
git config --global alias.br branch
git config --global alias.ci commit
git config --global alias.st status
git config --global alias.unstage 'reset HEAD --'
git config --global alias.last 'log -1 HEAD'

# View configuration
git config --list

Basic Git Workflow

Repository Initialization

# Create new repository
mkdir my-project
cd my-project
git init

# Clone existing repository
git clone https://github.com/username/repository.git
git clone https://github.com/username/repository.git my-local-folder

# Check repository status
git status

Basic Commands

# Adding files to staging area
git add filename.txt           # Add specific file
git add .                      # Add all files in current directory
git add *.js                   # Add all JavaScript files
git add -A                     # Add all changes (new, modified, deleted)

# Committing changes
git commit -m "Initial commit"
git commit -m "Add user authentication feature"

# Good commit message structure:
# feat: add user authentication
# 
# - Implement JWT token-based authentication
# - Add login/logout endpoints
# - Include password hashing with bcrypt
# 
# Fixes #123

# Viewing history
git log
git log --oneline
git log --graph --oneline --all
git log -p filename.txt        # Show changes for specific file

Branching Strategies

GitFlow Workflow

# Main branches
main/master    - Production-ready code
develop        - Integration branch for features

# Supporting branches
feature/*      - New features
release/*      - Release preparation
hotfix/*       - Production fixes

# Example workflow
git checkout -b feature/user-auth    # Create feature branch
# ... develop feature ...
git checkout develop
git merge --no-ff feature/user-auth  # Merge feature
git branch -d feature/user-auth      # Delete feature branch

Trunk-Based Development

# Short-lived feature branches
git checkout -b feature/quick-fix
# ... make changes ...
git checkout main
git merge feature/quick-fix

# Or using rebase
git checkout feature/quick-fix
git rebase main
git checkout main
git merge feature/quick-fix

Advanced Branch Management

Branch Operations

# Creating and switching branches
git branch feature/new-feature     # Create branch
git checkout feature/new-feature   # Switch to branch
git checkout -b feature/new-feature # Create and switch

# Listing branches
git branch                         # Local branches
git branch -r                      # Remote branches
git branch -a                      # All branches

# Deleting branches
git branch -d feature/old          # Delete merged branch
git branch -D feature/abandoned    # Force delete unmerged branch

# Renaming branches
git branch -m old-name new-name

# Tracking remote branches
git branch -u origin/feature/new-feature
git push --set-upstream origin feature/new-feature

Stashing Changes

# Save uncommitted changes temporarily
git stash                         # Stash changes
git stash save "Work in progress" # Stash with message

# List stashes
git stash list

# Apply stashed changes
git stash apply                   # Apply latest stash
git stash apply stash@{1}         # Apply specific stash

# Create branch from stash
git stash branch new-branch

# Clear stashes
git stash drop stash@{0}          # Delete specific stash
git stash clear                   # Delete all stashes

Merging and Rebasing

Merge Strategies

# Fast-forward merge (linear history)
git checkout main
git merge feature/simple

# Three-way merge (merge commit)
git merge --no-ff feature/complex

# Squash merge (single commit)
git merge --squash feature/multiple-commits
git commit -m "Complete feature implementation"

# Resolving merge conflicts
# When conflict occurs:
# 1. Edit conflicted files
# 2. Mark as resolved: git add filename.txt
# 3. Complete merge: git commit

Rebasing

# Rebase feature branch onto main
git checkout feature/new-feature
git rebase main

# Interactive rebase (rewrite history)
git rebase -i HEAD~3              # Rebase last 3 commits

# Interactive rebase commands:
# pick - use commit
# reword - use commit, but edit commit message
# edit - use commit, but stop for amending
# squash - use commit, but meld into previous commit
# fixup - like squash, but discard commit message
# drop - remove commit

# Rebase with conflict resolution
git rebase main
# Resolve conflicts, then:
git add .
git rebase --continue
# Or abort: git rebase --abort

Remote Repository Management

Working with Remotes

# Adding remote repositories
git remote add origin https://github.com/user/repo.git
git remote add upstream https://github.com/original/repo.git

# Viewing remotes
git remote -v

# Fetching changes
git fetch origin                  # Download changes without merging
git fetch --all                   # Fetch from all remotes

# Pulling changes
git pull origin main             # Fetch and merge
git pull --rebase origin main    # Fetch and rebase

# Pushing changes
git push origin main             # Push to main branch
git push origin feature/new      # Push feature branch
git push -u origin feature/new   # Push and set upstream

# Force push (use with caution)
git push --force-with-lease origin main

Collaboration Patterns

# Forking workflow (open source)
# 1. Fork repository on GitHub
# 2. Clone your fork
git clone https://github.com/your-username/repo.git
# 3. Add upstream remote
git remote add upstream https://github.com/original/repo.git
# 4. Sync with upstream
git fetch upstream
git merge upstream/main

# Shared repository workflow (team)
# 1. Clone shared repository
git clone https://github.com/team/repo.git
# 2. Create feature branch
git checkout -b feature/your-feature
# 3. Push and create PR
git push -u origin feature/your-feature

Advanced Git Operations

Undoing Changes

# Undo unstaged changes
git checkout -- filename.txt      # Restore file from last commit
git restore filename.txt          # Newer way (Git 2.23+)

# Undo staged changes
git reset HEAD filename.txt       # Unstage file
git restore --staged filename.txt # Newer way

# Amend last commit
git commit --amend               # Edit last commit message
git commit --amend --no-edit     # Add changes to last commit

# Reset to previous commit
git reset --soft HEAD~1          # Keep changes staged
git reset --mixed HEAD~1         # Keep changes unstaged (default)
git reset --hard HEAD~1          # Discard all changes

# Revert a commit (safe for shared history)
git revert commit-hash           # Create new commit that undoes changes

Git History Manipulation

# Interactive rebase for history editing
git rebase -i HEAD~5

# Changing multiple commit messages
# In rebase interactive mode, change 'pick' to 'reword'

# Squashing commits
# In rebase interactive mode, change 'pick' to 'squash' or 'fixup'

# Reordering commits
# In rebase interactive mode, reorder the lines

# Splitting commits
# In rebase interactive mode, change 'pick' to 'edit'
# Then: git reset HEAD~1, make multiple commits, git rebase --continue

Git Hooks

Common Hooks

# Pre-commit hook (.git/hooks/pre-commit)
#!/bin/bash
# Run tests before commit
npm test
if [ $? -ne 0 ]; then
    echo "Tests failed! Commit aborted."
    exit 1
fi

# Pre-push hook (.git/hooks/pre-push)
#!/bin/bash
# Check if main branch is protected
current_branch=$(git symbolic-ref --short HEAD)
if [ "$current_branch" = "main" ]; then
    echo "Direct pushes to main are not allowed. Use PR instead."
    exit 1
fi

# Commit-msg hook
#!/bin/bash
# Validate commit message format
MSG=$(cat $1)
if ! echo "$MSG" | grep -qE "^(feat|fix|docs|style|refactor|test|chore): "; then
    echo "Invalid commit message format!"
    echo "Use: feat|fix|docs|style|refactor|test|chore: description"
    exit 1
fi

Client-Side Hooks

# pre-commit: Run before commit message
# prepare-commit-msg: Run before commit message editor
# commit-msg: Run after commit message is created
# post-commit: Run after commit is completed
# pre-rebase: Run before rebase
# post-merge: Run after successful merge
# pre-push: Run before push to remote

Git in CI/CD Pipelines

Git Commands in Automation

# GitHub Actions example
name: CI Pipeline
on: [push, pull_request]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0  # Fetch all history
    
    - name: Get changed files
      id: changed-files
      uses: tj-actions/changed-files@v35
      
    - name: Run tests for changed files
      run: |
        if [[ "${{ steps.changed-files.outputs.all_changed_files }}" ]]; then
          echo "Changed files: ${{ steps.changed-files.outputs.all_changed_files }}"
          # Run specific tests based on changed files
        fi

# GitLab CI example
stages:
  - test
  - deploy

test:
  stage: test
  script:
    - git diff --name-only $CI_COMMIT_BEFORE_SHA $CI_COMMIT_SHA
    - npm test

deploy:
  stage: deploy
  script:
    - git checkout main
    - git pull origin main
    - ./deploy.sh

Git Best Practices

Commit Message Conventions

# Conventional Commits specification
<type>[optional scope]: <description>

[optional body]

[optional footer(s)]

# Types:
# feat:     New feature
# fix:      Bug fix
# docs:     Documentation only changes
# style:    Changes that do not affect meaning (white-space, formatting)
# refactor: Code change that neither fixes bug nor adds feature
# test:     Adding missing tests or correcting existing tests
# chore:    Changes to build process or auxiliary tools

# Examples:
feat(auth): add JWT token authentication
fix(api): resolve null pointer in user endpoint
docs: update installation guide
style: format code with prettier
refactor: extract database connection logic
test: add unit tests for user service
chore: update dependencies

Repository Management

# .gitignore patterns
# Dependencies
node_modules/
vendor/
*.gem

# Build outputs
dist/
build/
*.jar
*.war

# Environment files
.env
.env.local
.env.production

# IDE files
.vscode/
.idea/
*.swp
*.swo

# OS files
.DS_Store
Thumbs.db

# Logs
*.log
logs/

# Temporary files
*.tmp
*.temp

Advanced Git Features

Bisect for Bug Hunting

# Find the commit that introduced a bug
git bisect start
git bisect bad                 # Current commit is bad
git bisect good v1.0.0         # This commit was good

# Git will checkout middle commit, you test it:
git bisect good                # If this commit is good
git bisect bad                 # If this commit is bad

# Continue until bug is found
git bisect reset               # Return to original state

Worktrees

# Multiple working directories from same repository
git worktree add ../feature-branch feature/new-feature
cd ../feature-branch
# Work on feature independently

# List worktrees
git worktree list

# Remove worktree
git worktree remove ../feature-branch

Submodules

# Add submodule
git submodule add https://github.com/user/library.git libs/library

# Clone repository with submodules
git clone --recurse-submodules https://github.com/user/repo.git

# Update submodules
git submodule update --init --recursive

# Working with submodules
cd libs/library
git checkout main
git pull origin main
cd ../..
git add libs/library
git commit -m "Update submodule to latest version"

Git Security

Security Best Practices

# Signed commits
git config --global user.signingkey YOUR_GPG_KEY_ID
git commit -S -m "Signed commit"

# Verified commits on GitHub
# Requires GPG key setup in GitHub settings

# Branch protection rules
# In repository settings, protect main branch:
# - Require pull request reviews
# - Require status checks to pass
# - Include administrators
# - Restrict who can push

# Secret scanning
# Use pre-commit hooks or GitHub secret scanning
# to prevent committing secrets

Troubleshooting Common Issues

Common Problems and Solutions

# Recovering lost commits
git reflog                    # Show reference log
git checkout commit-hash      # Checkout lost commit
git branch recovery-branch    # Create branch at recovered commit

# Large file issues
git filter-branch --tree-filter 'rm -f large-file.zip' HEAD
# Or use BFG Repo-Cleaner
bfg --delete-files large-file.zip

# Permission issues
git config --global --unset credential.helper
git config --global credential.helper 'cache --timeout=3600'

# Merge conflicts
git status                    # See conflicted files
# Edit files to resolve conflicts
git add .                     # Mark as resolved
git commit                    # Complete merge

Git with Different Workflows

Feature Branch Workflow

# Complete feature development cycle
git checkout -b feature/user-dashboard
# ... develop feature ...
git add .
git commit -m "feat: add user dashboard component"
git push -u origin feature/user-dashboard
# Create Pull Request on GitHub/GitLab
# After review and approval:
git checkout main
git pull origin main
git merge --no-ff feature/user-dashboard
git push origin main
git branch -d feature/user-dashboard
git push origin --delete feature/user-dashboard

Release Process

# Creating releases with semantic versioning
git checkout -b release/v1.2.0
# Update version numbers, changelog
git commit -m "chore: release v1.2.0"
git tag v1.2.0
git push origin release/v1.2.0
git push origin v1.2.0

# Merge to main
git checkout main
git merge --no-ff release/v1.2.0
git branch -d release/v1.2.0

Conclusion

Git is an essential tool for modern software development that enables efficient collaboration, version control, and code management. Mastering Git not only improves individual productivity but also enhances team collaboration and code quality.

Key Takeaways:

  • Understand Git's distributed architecture and core concepts
  • Master branching strategies that fit your team's workflow
  • Use Git hooks to automate quality checks and enforce standards
  • Follow commit message conventions for better history readability
  • Implement proper security practices and branch protection
  • Leverage Git in CI/CD pipelines for automated testing and deployment

By adopting Git best practices and continuously learning advanced features, development teams can work more efficiently, maintain cleaner codebases, and deliver higher quality software.

© 2025 DevOps Blog

Comments

Popular posts from this blog

Real-world Terraform scenarios to test and improve your Infrastructure as Code skills

Azure Kubernetes Service (AKS) Complete Guide

Automate Your DevOps Documentation: `iac-to-docs` Lands on PyPI with AI Power