Essential Git Commands Reference
Introduction to Git and Version Control
Git is a distributed version control system that enables developers to track changes in their codebase, collaborate with team members, and maintain a complete history of project evolution. Understanding Git commands and workflows is essential for modern software development, whether working on personal projects or contributing to large-scale collaborative efforts.
This guide provides a comprehensive reference for Git commands, from basic initialization to advanced workflows, with practical examples and best practices for integrating with GitHub.
Understanding the Git Workflow
Before diving into specific commands, it's important to understand Git's three-stage architecture:
- Working Directory: Where you modify files and create new content
- Staging Area (Index): Where you prepare changes for commit
- Repository: Where committed changes are permanently stored
This architecture allows for precise control over what changes are recorded in your project history.
Directory and File Management Fundamentals
Creating and Organizing Project Directories
Create a new directory:
mkdir myNewDirectory
This command creates a new folder in your current location. For nested directories, use the -p flag:
mkdir -p projects/web-development/frontend
This creates the entire directory structure in one command, even if parent directories don't exist.
Create multiple directories simultaneously:
mkdir src tests docs config
Navigating the File System
List directory contents:
ls -l
This displays files and directories with detailed information including permissions, ownership, size, and modification date.
List all files including hidden ones:
ls -la
The -a flag reveals hidden files (those starting with a dot), which is crucial for seeing Git configuration files like .git and .gitignore.
Display the current directory path:
pwd
This prints the absolute path of your current working directory, helping you maintain awareness of your location in the file system.
Navigate to a directory:
cd myNewDirectory
Navigate to parent directory:
cd ..
Navigate to home directory:
cd ~
Navigate to previous directory:
cd -
Git Repository Initialization
Creating a New Git Repository
Initialize Git in the current directory:
git init
This command creates a .git subdirectory containing all necessary repository metadata and object database. The directory becomes a Git repository, ready to track changes.
Initialize with a specific branch name:
git init -b main
This initializes the repository with "main" as the default branch name, following modern naming conventions.
Initialize a bare repository (for servers):
git init --bare
Bare repositories contain only Git data without a working directory, typically used for central repositories on servers.
Verifying Repository Status
Check repository status:
git status
This displays the current state of your working directory and staging area, showing:
- Modified files not yet staged
- Files staged for commit
- Untracked files
- Current branch information
View status in short format:
git status -s
This provides a condensed view using status codes (M for modified, A for added, ?? for untracked).
File Creation and Editing
Creating Files from the Command Line
Create a file with content using echo:
echo "Enter Your Text Here" > filename.txt
This creates a new file with the specified content. If the file exists, it will be overwritten.
Append content to an existing file:
echo "Additional content" >> filename.txt
The >> operator appends content without overwriting existing data.
Create an empty file:
touch newfile.js
The touch command creates an empty file or updates the timestamp of an existing file.
Create multiple files at once:
touch index.html style.css script.js
Editing Files with Nano
Open a file in Nano editor:
nano filename.txt
Nano is a user-friendly terminal text editor with on-screen command hints.
Nano keyboard shortcuts:
Ctrl + O: Save (write out) the fileCtrl + X: Exit NanoCtrl + K: Cut the current lineCtrl + U: Paste the cut textCtrl + W: Search for textCtrl + \: Search and replaceCtrl + G: Display help
Save and exit workflow:
- Press
Ctrl + Xto exit - Press
Yto confirm saving changes - Press
Enterto confirm the filename
Alternative Text Editors
Using Vim:
vim filename.txt
Vim is a powerful modal editor. Basic commands:
- Press
ito enter insert mode - Press
Escto return to normal mode - Type
:wto save - Type
:qto quit - Type
:wqto save and quit
Using VS Code from terminal:
code filename.txt
This opens the file in Visual Studio Code (if installed and configured).
Staging Files for Commit
Adding Files to the Staging Area
Stage all files in the current directory:
git add .
This stages all new, modified, and deleted files in the current directory and subdirectories.
Stage all files in the repository:
git add -A
The -A flag stages all changes throughout the entire repository, regardless of your current directory.
Stage specific files:
git add filename1.txt filename2.js
Stage files by pattern:
git add *.js
This stages all JavaScript files in the current directory.
Stage files interactively:
git add -p
This allows you to review and stage changes in chunks, providing fine-grained control over what gets committed.
Stage only modified and deleted files (not new files):
git add -u
Managing Empty Directories
Git doesn't track empty directories. To preserve directory structure:
Create a .gitkeep file:
touch .gitkeep
Place this file in empty directories you want to track. The .gitkeep convention signals that the directory should be preserved in the repository.
Alternative approach using .gitignore:
echo "*" > .gitignore
echo "!.gitignore" >> .gitignore
This creates a .gitignore that ignores all files except itself, preserving the directory.
Committing Changes
Creating Commits
Commit staged changes with a message:
git commit -m "Initial commit"
Commit messages should be clear, concise, and descriptive of the changes made.
Commit with a detailed message:
git commit
This opens your default text editor for writing a multi-line commit message. The first line should be a brief summary (50 characters or less), followed by a blank line and detailed description.
Stage and commit in one command:
git commit -am "Update feature implementation"
The -a flag automatically stages all modified and deleted tracked files before committing. Note: This doesn't include new untracked files.
Amend the previous commit:
git commit --amend -m "Corrected commit message"
This replaces the last commit with a new one, useful for fixing commit messages or adding forgotten changes.
Commit Message Best Practices
Conventional commit format:
type(scope): subject
body
footer
Common types:
feat: New featurefix: Bug fixdocs: Documentation changesstyle: Code style changes (formatting, semicolons, etc.)refactor: Code refactoringtest: Adding or updating testschore: Maintenance tasks
Example:
git commit -m "feat(auth): implement JWT token authentication
- Add JWT token generation
- Implement token verification middleware
- Add refresh token functionality
Closes #123"
Branch Management
Working with Branches
View all branches:
git branch
The current branch is marked with an asterisk.
View all branches including remote:
git branch -a
Create a new branch:
git branch feature-name
Switch to a branch:
git checkout feature-name
Create and switch to a new branch:
git checkout -b feature-name
Rename the current branch:
git branch -m new-branch-name
Rename a specific branch:
git branch -m old-name new-name
Delete a branch:
git branch -d branch-name
Force delete a branch (even if not merged):
git branch -D branch-name
Rename master to main:
git branch -m master main
This updates your local branch name to follow modern naming conventions.
Remote Repository Management
Configuring Remote Repositories
View configured remotes:
git remote -v
This displays all remote repositories with their URLs for fetching and pushing.
Add a remote repository:
git remote add origin https://github.com/username/repository-name.git
The name "origin" is conventional for the primary remote repository.
Remove a remote:
git remote remove origin
Rename a remote:
git remote rename old-name new-name
Change remote URL:
git remote set-url origin https://github.com/username/new-repository.git
Add multiple remotes:
git remote add upstream https://github.com/original-owner/repository.git
This is useful for contributing to forked repositories.
Pushing Changes to GitHub
Uploading Local Commits
Push to remote repository:
git push origin main
This uploads commits from your local "main" branch to the "main" branch on the "origin" remote.
Push and set upstream tracking:
git push -u origin main
The -u flag sets the upstream tracking relationship, allowing you to use git push without specifying the remote and branch in future commands.
Push all branches:
git push --all origin
Push tags:
git push --tags
Force push (use with caution):
git push --force origin main
Force pushing overwrites remote history and should only be used when you're certain it won't affect collaborators.
Safer force push:
git push --force-with-lease origin main
This prevents overwriting work if the remote has been updated since your last fetch.
Pulling and Fetching Changes
Synchronizing with Remote Repositories
Fetch changes from remote:
git fetch origin
This downloads remote changes without merging them into your local branches.
Pull changes and merge:
git pull origin main
This fetches and merges changes from the remote "main" branch into your current branch.
Pull with rebase:
git pull --rebase origin main
This applies your local commits on top of the fetched commits, creating a linear history.
Fetch all remotes:
git fetch --all
Viewing History and Changes
Examining Repository History
View commit history:
git log
View condensed history:
git log --oneline
View history with graph:
git log --graph --oneline --all
View history for a specific file:
git log filename.txt
View changes in commits:
git log -p
View last N commits:
git log -n 5
Inspecting Changes
View unstaged changes:
git diff
View staged changes:
git diff --staged
View changes between branches:
git diff branch1..branch2
View changes for a specific file:
git diff filename.txt
Practical Example: Complete Workflow
Setting Up a New Project and Pushing to GitHub
Step 1: Create and navigate to project directory
mkdir my-awesome-project
cd my-awesome-project
Step 2: Initialize Git repository
git init -b main
Step 3: Create project files
touch README.md
echo "# My Awesome Project" > README.md
echo "This is a sample project demonstrating Git workflow." >> README.md
Step 4: Create a .gitignore file
nano .gitignore
Add common ignore patterns:
node_modules/
.env
*.log
.DS_Store
Step 5: Stage all files
git add -A
Step 6: Create initial commit
git commit -m "Initial commit: Add README and .gitignore"
Step 7: Connect to GitHub repository
git remote add origin https://github.com/username/my-awesome-project.git
Step 8: Push to GitHub
git push -u origin main
Advanced Example: C Program Development Workflow
Creating, Compiling, and Version Controlling a C Program
Step 1: Create project structure
mkdir c-project
cd c-project
git init -b main
mkdir src build
Step 2: Create C source file using echo
echo '#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}' > src/hello.c
Step 3: Alternative - Create using Nano
nano src/hello.c
Add the following code:
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}
Save and exit (Ctrl + X, Y, Enter).
Step 4: Create .gitignore for C projects
echo '# Compiled files
*.o
*.exe
*.out
a.out
# Build directory
build/
# Editor files
*.swp
*~' > .gitignore
Step 5: Compile the program
gcc src/hello.c -o build/hello
Step 6: Run the compiled program
./build/hello
Expected output:
Hello, World!
Step 7: Stage and commit source code
git add src/hello.c .gitignore
git commit -m "feat: implement hello world program"
Step 8: Push to GitHub
git remote add origin https://github.com/username/c-project.git
git push -u origin main
Common Git Scenarios and Solutions
Undoing Changes
Discard changes in working directory:
git checkout -- filename.txt
Unstage a file:
git reset HEAD filename.txt
Undo last commit (keep changes):
git reset --soft HEAD~1
Undo last commit (discard changes):
git reset --hard HEAD~1
Revert a commit (create new commit):
git revert commit-hash
Handling Merge Conflicts
When pulling or merging creates conflicts:
- Identify conflicted files:
git status
- Open and resolve conflicts in each file
- Stage resolved files:
git add resolved-file.txt
- Complete the merge:
git commit -m "Resolve merge conflicts"
Stashing Changes
Save work in progress:
git stash
View stashed changes:
git stash list
Apply most recent stash:
git stash apply
Apply and remove stash:
git stash pop
Apply specific stash:
git stash apply stash@{2}
Git Configuration
Setting Up User Information
Configure username:
git config --global user.name "Your Name"
Configure email:
git config --global user.email "your.email@example.com"
View configuration:
git config --list
Configure default editor:
git config --global core.editor "nano"
Configure default branch name:
git config --global init.defaultBranch main
Best Practices and Tips
Commit Guidelines
- Commit frequently: Make small, logical commits rather than large, monolithic ones
- Write clear messages: Describe what and why, not how
- Test before committing: Ensure code works before creating a commit
- Use branches: Keep main branch stable, develop features in separate branches
- Review before pushing: Check
git statusandgit diffbefore pushing
Repository Organization
- Use .gitignore: Exclude build artifacts, dependencies, and sensitive files
- Include README: Document project purpose, setup, and usage
- Add LICENSE: Specify how others can use your code
- Structure directories: Organize code logically (src, tests, docs, etc.)
Collaboration Workflow
- Pull before push: Always fetch latest changes before pushing
- Use pull requests: Review code before merging to main branch
- Communicate: Document changes and discuss major modifications
- Follow conventions: Adhere to team's branching and commit message standards
Troubleshooting Common Issues
Authentication Problems
If you encounter authentication errors when pushing:
Use personal access token (recommended):
- Generate token on GitHub (Settings → Developer settings → Personal access tokens)
- Use token as password when prompted
Configure credential helper:
git config --global credential.helper cache
Large File Issues
For files larger than GitHub's limits:
Use Git LFS (Large File Storage):
git lfs install
git lfs track "*.psd"
git add .gitattributes
Accidental Commits
Remove file from Git but keep locally:
git rm --cached filename.txt
Remove directory from Git:
git rm -r --cached directory/
Conclusion
Mastering Git commands and workflows is essential for efficient software development. This guide covers fundamental operations, from basic file management to advanced version control scenarios. Regular practice with these commands will build muscle memory and improve your development workflow.
Remember that Git is a powerful tool with many features beyond what's covered here. As you become comfortable with these basics, explore advanced topics like rebasing, cherry-picking, bisecting, and submodules to further enhance your version control capabilities.
For additional resources and detailed documentation, visit the official Git documentation at git-scm.com.
Quick Reference Summary:
- Initialize:
git init - Stage:
git add . - Commit:
git commit -m "message" - Connect remote:
git remote add origin URL - Push:
git push -u origin main - Pull:
git pull origin main - Status:
git status - History:
git log
This guide is maintained and updated regularly to reflect current Git best practices and GitHub workflows.