Note: This guide uses modern Git commands (
switch,restore). Older syntax (checkout) works but is less intuitive.
- First-Time Setup
- SSH Key Setup for GitHub
- Managing Your Code Like a Pro
- Additional Configuration
- Essential Viewing & Inspection Commands
- Undoing Changes (Critical Safety Net)
- Stashing (Temporary Storage)
- Handling Merge Conflicts
- Remote Management
- Tagging Releases
- Common Troubleshooting Scenarios
- Quick Reference Card
- Pro Tips
- gitignore Basics
Configure your identity—this information will be attached to every commit you make, so choose a name and email you're comfortable sharing publicly.
git config --global user.name "your-name"
git config --global user.email "your-email"
git config --global init.defaultBranch mainTo verify your current configuration:
git config --listBefore generating a new key, see if you already have one:
-
Open Git Bash.
-
Enter
ls -al ~/.sshto see if existing SSH keys are present. -
Look for an existing public key. GitHub accepts these filenames by default:
id_rsa.pubid_ecdsa.pubid_ed25519.pub
-
If you find one, you can use it—otherwise, generate a new key.
-
Open Git Bash.
-
Run the following, replacing the email with your GitHub email:
ssh-keygen -t ed25519 -C "your_email@example.com" -
When prompted for a file location, press Enter to accept the default.
-
When prompted, enter a secure passphrase (or press Enter for no passphrase):
> Enter passphrase (empty for no passphrase): [Type passphrase] > Enter same passphrase again: [Type passphrase again]
-
In an administrator PowerShell window, ensure the ssh-agent is running:
# start the ssh-agent in the background Get-Service -Name ssh-agent | Set-Service -StartupType Manual Start-Service ssh-agent
-
In a regular terminal (non-elevated), add your private key:
ssh-add c:/Users/YOU/.ssh/id_ed25519
-
Add the SSH public key to your account on GitHub.
-
Copy your public key to the clipboard: In a new admin elevated PowerShell window
$ cat ~/.ssh/id_ed25519.pub | clip # Copies the contents of the id_ed25519.pub file to your clipboard
-
On GitHub, go to Settings → SSH and GPG keys.
-
Click New SSH key.
-
Give it a descriptive Title (e.g., "Personal Laptop").
-
Select the key type (authentication or signing).
-
Paste your public key into the Key field.
-
Click Add SSH key.
After you've set up your SSH key and added it to GitHub, you can test your connection.
-
Open Git Bash.
-
Enter the following:
ssh -T git@github.com # Attempts to ssh to GitHub -
If prompted, verify the fingerprint matches GitHub's public key fingerprint, then type
yes. You should see:> Hi USERNAME! You've successfully authenticated, but GitHub does not > provide shell access.
-
Verify that the resulting message contains your username.
1. Create a Remote Repository
Go to GitHub.com, click the + icon (or the green New button), and select New repository. Give it a name, add a description, choose visibility, and click Create repository.
Then, navigate to your local project and open it in VS Code:
code .2. Initialize a Local Git Repository
git init3. Connect to Your Remote Repository
git remote add origin https://github.com/username/repository_name.git4. Pull the Latest Changes
git pull origin main5. Check Your Current Branch
git branch --show-current6. Stage Your Changes
# Stage everything
git add .
# Stage a specific file or folder
git add <file or folder name>Unstage changes when needed:
# Unstage everything
git reset
# Unstage a specific file
git reset <file name>7. Commit Your Work
git commit -m "Your commit message"8. Push to GitHub
git push -u origin mainWorking with branches:
# show current branch
git branch --show-current
# Create a new branch
git branch <branch-name>
# Switch to a branch
git switch <branch-name>
# Create and switch to a new branch (one step)
git switch -c <branch-name>
# Push the branch to GitHub
git push -u origin <branch-name>9. Your Daily Workflow
Once your remote is set up, these three commands cover most of your day-to-day work:
git add .
git commit -m "commit message"
git push10. Merge Your Work Into main
- Update your local
mainbranch:
git switch main
git pull origin main- Switch back to your working branch and merge in the latest
main(so you can resolve conflicts locally):
git switch <branch-name>
git merge mainFor a cleaner, linear history, consider rebasing instead:
git rebase main- Push your branch and create a pull request:
git push --set-upstream origin <branch-name>- After your PR is merged, clean up the branch locally:
git branch -d <branch-name>11. Clone a Repository
# HTTPS
git clone https://github.com/username/repository.git
# SSH (requires SSH key setup)
git clone git@github.com:username/repository.git
# GitHub CLI
gh repo clone username/repositoryThis is an excellent, well-structured Git reference. Here are some additions that would make it even more comprehensive and practical:
# Set up a global gitignore for OS-specific and editor files
git config --global core.excludesfile ~/.gitignore_global
# Common entries for ~/.gitignore_global:
# .DS_Store (macOS)
# Thumbs.db (Windows)
# *.log
# .vscode/
# .idea/# Shortcuts for common commands
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'
git config --global alias.tree 'log --graph --oneline --all'# See what's changed but not staged
git diff
# See what's staged but not committed
git diff --staged
# View commit history
git log --oneline --graph --all
# See who changed what in a file
git blame <filename>
# Show status in a compact format
git status -sb
# List all remote repositories
git remote -v# Discard changes to a file (irreversible!)
git checkout -- <filename>
# or with modern syntax
git restore <filename>
# Unstage a file but keep changes
git restore --staged <filename>
# Amend the last commit (add forgotten changes)
git add <forgotten-file>
git commit --amend -m "Updated message"
# Undo last commit but keep changes
git reset --soft HEAD~1
# Undo last commit and discard changes (dangerous!)
git reset --hard HEAD~1
# Revert a commit (safe for shared branches)
git revert <commit-hash># Save uncommitted work temporarily
git stash save "optional description"
# List stashes
git stash list
# Apply most recent stash and keep it
git stash apply
# Apply and remove most recent stash
git stash pop
# Create a branch from a stash
git stash branch <branch-name>
# Clear all stashes
git stash clear# When conflicts occur, see which files have issues
git status
# Use VS Code's merge editor
code --wait --merge <current-file> <base-file> <other-file> --track-focus
# After resolving conflicts
git add <resolved-file>
git commit -m "Merge resolved"
# Abort merge and start over
git merge --abort# Change remote URL
git remote set-url origin <new-url>
# Add another remote (e.g., for backup)
git remote add backup https://github.com/username/repo-backup.git
# Push to multiple remotes
git push origin main
git push backup main
# Fetch from remote without merging
git fetch origin
# See what would be pulled
git fetch --dry-run# Create lightweight tag
git tag v1.0.0
# Create annotated tag (recommended for releases)
git tag -a v1.0.0 -m "Release version 1.0.0"
# Push tags to remote
git push origin --tags
# Push a single tag
git push origin v1.0.0
# Delete local tag
git tag -d v1.0.0
# Delete remote tag
git push origin --delete v1.0.0# Create a branch to save work done in detached HEAD
git switch -c <new-branch-name># Warning: Only if no one else has pulled!
git reset --soft HEAD~1
git push --force origin <branch-name>git remote prune origin| What you want | Command |
|---|---|
| Save work quickly | git add . && git commit -m "wip" |
Undo git add . |
git reset |
| Fix last commit message | git commit --amend -m "new message" |
| See what you've changed today | git log --since="today" --author="your-name" |
| Show files changed in last commit | git diff HEAD~1 HEAD --name-only |
| Discard everything not committed | git reset --hard HEAD |
- Commit early, commit often - Small, focused commits are easier to debug and revert
- Write meaningful commit messages - Use imperative tense: "Fix bug" not "Fixed bug"
- Never force push to main/master - Use
--force-with-leaseinstead of--forceif you must - Pull before you push - Avoids unnecessary merge commits
- Use
.gitignorefrom day one - Prevents committing node_modules, .env files, build artifacts
A .gitignore file tells Git which files/folders to never track. Create it in your project root:
# Create .gitignore in current directory
touch .gitignore # macOS/Linux/Git Bash
# or
echo "" > .gitignore # Windows PowerShell# Dependencies
node_modules/
vendor/
.env
# Build outputs
dist/
build/
*.exe
*.dll
# IDE files
.vscode/
.idea/
*.swp
.DS_Store (macOS)
Thumbs.db (Windows)
# Logs
*.log
npm-debug.log*
# Environment files
.env
.env.local
.env.*.local
# API keys/secrets (never commit these!)
.secrets/
config/keys.json# Show all ignored files
git status --ignored
# Check if a specific file is ignored
git check-ignore -v <filename>