Git Usage Guide — From Basics to Real-World Workflows

Why Git Is Needed

When editing code, you need to be able to undo mistakes. Multiple people need to be able to modify the same code simultaneously. Git is a distributed version control system that solves both of these problems.

Key characteristics of Git:

  • Work independently locally — commit, branch, and browse history without a network connection
  • Branches are lightweight — creating a new branch is nearly instant (just creating a pointer)
  • Full change history — records who changed what, when, and why

Initial Setup

The first settings to configure after installing Git.

# Set user info (recorded in commits)
git config --global user.name "Alice"
git config --global user.email "alice@example.com"

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

# Verify settings
git config --list
# user.name=Alice
# user.email=alice@example.com
# init.defaultbranch=main

Core Concept: Three Areas

Git has three areas that files pass through.

AreaDescriptionAnalogy
Working DirectoryWhere you actually edit filesYour desk
Staging Area (Index)Where changes for the next commit are gatheredPacking area
Repository (.git)Where committed snapshots are storedWarehouse

Flow: Edit -> git add -> Staging -> git commit -> Repository

Essential Commands

Creating and Cloning Repositories

# Initialize a new repository
mkdir my-project && cd my-project
git init
# Initialized empty Git repository in /my-project/.git/

# Clone an existing remote repository
git clone https://github.com/user/repo.git
git clone https://github.com/user/repo.git my-folder   # Specify folder name

Checking Status and Tracking Changes

# Check current status (the most frequently used command)
git status
# On branch main
# Changes not staged for commit:
#   modified:   src/app.js
# Untracked files:
#   src/utils.js

# Compare changes
git diff                   # Working -> Staging comparison
git diff --staged          # Staging -> Last commit comparison

# View commit history
git log --oneline --graph
# * a1b2c3d (HEAD -> main) feat: add login feature
# * d4e5f6g fix: bug fix
# * g7h8i9j init: project initialization

Staging and Committing

# Stage specific files
git add src/app.js

# Stage all changed files (including new files)
git add .

# Commit (message should record "why" the change was made)
git commit -m "feat: add user login feature"

# Stage + commit in one step (tracked files only)
git commit -am "fix: fix password validation error"

Commit Message Conventions

Using a unified format within a team makes history easier to understand.

PrefixPurposeExample
featNew featurefeat: add social login
fixBug fixfix: resolve session expiry error
refactorRefactoring (no behavior change)refactor: extract auth module
docsDocumentation changesdocs: add API endpoint descriptions
testAdd/modify teststest: add login failure test cases
choreBuild, config changeschore: update ESLint rules
perfPerformance improvementperf: optimize query indexing

Using Branches

Branches are independent workspaces. Develop features while keeping the main branch safe.

# List branches
git branch
# * main
#   feature/login

# Create + switch to a branch
git checkout -b feature/login
# Or (Git 2.23+)
git switch -c feature/login

# Switch branches
git checkout main
git switch main

# Delete a branch (after merging)
git branch -d feature/login

Merging

# Merge a feature branch into main
git checkout main
git merge feature/login
# Auto-merges if there are no conflicts

# When conflicts occur
# 1. Manually edit conflicting files
# 2. Stage after resolving conflicts
git add src/auth.js
# 3. Create merge commit
git commit -m "merge: merge feature/login"

Rebase vs Merge

AspectMergeRebase
HistoryMerge commit remains (branch visible)Linear history (clean)
SafetyPreserves original historyCommit hashes change
When to useMerging into mainUpdating feature branch with main
RuleSafe on shared branchesNever rebase shared branches
# Bring latest changes from main into a feature branch
git checkout feature/login
git rebase main
# -> Feature commits are replayed on top of latest main

Remote Repositories

Commands for synchronizing with remote repositories like GitHub and GitLab.

# Register a remote repository
git remote add origin https://github.com/user/repo.git

# List remotes
git remote -v

# Push (local -> remote)
git push origin main
git push -u origin feature/login    # -u: set upstream (git push alone is enough after this)

# Pull (remote -> local, fetch + merge)
git pull origin main

# Fetch remote changes only (no merge)
git fetch origin

Undoing Mistakes

SituationCommandDescription
Unstagegit restore --staged file.jsUndo add (file content preserved)
Discard changesgit restore file.jsRestore to last commit state (caution: deletes changes)
Amend last commitgit commit --amendEdit message or add files (unpushed commits only)
Revert a specific commitgit revert a1b2c3dCreates a new reverting commit (safe)
Reset commit historygit reset --soft HEAD~1Undo commit, changes preserved in Staging
# Most common mistake: forgot to include a file in commit
git add forgotten-file.js
git commit --amend --no-edit    # Add file while keeping the message

# Dangerous commands — use with caution
git reset --hard HEAD~1    # Deletes commit + all changes (difficult to recover)

Real-World Collaboration Workflow

The most commonly used workflow based on GitHub Flow.

# 1. Get latest code from main
git checkout main
git pull origin main

# 2. Create a feature branch
git checkout -b feature/user-profile

# 3. Work + commit (repeat multiple times)
git add .
git commit -m "feat: implement profile edit UI"
git commit -m "feat: add profile image upload"

# 4. Push to remote
git push -u origin feature/user-profile

# 5. Create a Pull Request on GitHub
# -> Code review -> Approval -> Merge to main

# 6. Clean up locally
git checkout main
git pull origin main
git branch -d feature/user-profile

.gitignore Setup

Specify files to exclude from version control. Create a .gitignore file at the project root.

# Dependencies
node_modules/
vendor/
venv/

# Build artifacts
dist/
build/
*.pyc

# Environment variables / secrets
.env
.env.local
*.pem

# IDE settings
.vscode/
.idea/
*.swp

# OS files
.DS_Store
Thumbs.db

Summary

SituationCommand
Start a projectgit init or git clone
Save changesgit add . -> git commit -m "message"
Check statusgit status, git log --oneline
Branch workgit switch -c feature/xxx -> work -> git merge
Sync with remotegit pull -> work -> git push
Undo mistakesgit restore, git revert, git reset --soft

Git is a tool, not an end in itself. Do not try to memorize complex commands — just learn the basic flow in the table above and you can handle most situations. Look up the rest when you need it.

Was this article helpful?