During development, code can be lost or accidentally overwritten. Git provides a distributed version control system that tracks changes, enables branching for team collaboration, and allows reverting to previous states. This guide covers essential Git commands and workfolws for individual and team use.
- Initial Setup
Git uses command-line syntax similar to Linux. On Windows, right-click and select "Open Git Bash here" to launch the terminal. Before working with Git, configure your identity.
git config --global user.name "YourName"
git config --global user.email "your.email@example.com"
Configuration levels: --local (current repository only), --global (all repositories), --system (all users, rarely used). Once set, you can store credentials to avoid repeated prompts:
git config --global credential.helper store
Verify your configuration:
git config --global --list
- Creating a Repository
A repository (repo) is a directory where Git tracks every file change, allowing you to revisit any revision.
Method A: git init
Initialize a local project:
mkdir my-project
cd my-project
git init
ls -a # see hidden files including .git
cd .git && ls -al # explore git internals
cd ..
rm -rf .git # remove git tracking, revert to normal directory
git init my-repo # creates repo in subdirectory 'my-repo'
Method B: git clone
Clone an existing remote repository:
git clone https://github.com/user/repo.git
ls -ltr # list contents, show branches
- Work Areas and File States
Git locally manages three areas: working directory (your files), staging area (temporary holding for next commit), and local repository (committed history). File states are: untracked, unmodified, modified, and staged.
- Adding and Committing
Check the repository status first:
git status
Create a new file and track it:
echo "Initial content" > readme.md
git status # shows readme.md as untracked
git add readme.md # stage the file
git status # now shows changes to be committed
git rm --cached readme.md # unstage without deleting
git add . # stage all changes in current directory
Commit staged changes:
git commit -m "First commit: added readme"
git status # clean working tree
git log # view commit history
- Undoing Changes
Use git reset to move HEAD to a previous commit, with three modes:
--soft: keep both working directory and staging area changes.--hard: discard all changes in working directory and staging area.--mixed(default): keep working directory changes but discard staging area.
Example: create three files with three separate commits, then test each reset mode.
mkdir demo && cd demo
git init
echo "version1" > f1.txt
git add f1.txt && git commit -m "c1"
echo "version2" > f2.txt
git add f2.txt && git commit -m "c2"
echo "version3" > f3.txt
git add f3.txt && git commit -m "c3"
git log --oneline # note commit hashes
Backup the repo for each test:
cp -r demo demo-soft
cp -r demo demo-hard
cp -r demo demo-mixed
Test --soft:
cd demo-soft
git reset --soft HEAD~ # go back one commit
ls # all files still present
git ls-files # staged still has f3.txt
git status # f3.txt is staged as new file
If you need to recover after a reset, use git reflog to see all HEAD movements and restore with git reset --hard <hash>.
- Comparing Differences
git diff compares various areas:
git diff # working directory vs staging
git diff HEAD # working+staging vs last commit
git diff --cached # staging vs last commit (same as --staged)
git diff <commit1> <commit2> # between two commits
git diff branch1 branch2 # between two branch tips
- Deleting Files
Two ways to remove a file from Git tracking:
Manual removal + stage:
rm data.txt
git status # shows deleted file (not staged)
git add . # stage the deletion
git commit -m "remove data.txt"
Using git rm (removes from both working directory and staging):
git rm -f config.yml
git status
git commit -m "remove config.yml"
- Ignoring Files with .gitignore
Create a .gitignore file to exclude logs, credentials, build artifacts, etc.
echo "some log" > debug.log
echo "another" > app.log
echo "debug.log" > .gitignore # ignore only debug.log
git status # app.log still untracked
git add . && git commit -m "add gitignore"
To ignore all .log files:
echo "*.log" >> .gitignore
echo "new entry" > system.log
git status # only .gitignore change visible
git commit -am "ignore all .log files"
Common patterns: *.class, *.o, .env, *.zip, *.pem, node_modules/, .DS_Store.
- Remote Repositories
Popular hosting services: GitHub, GitLab, Bitbucket, Gitee. Below we use GitHub (requires account).
Link a Local Repository to Remote
Option 1: No local repo yet
echo "# my-project" >> README.md
git init
git add README.md
git commit -m "first commit"
git branch -M main
git remote add origin git@github.com:username/repo.git
git push -u origin main
Option 2: Existing local repo
git remote add origin git@github.com:username/repo.git
git branch -M main
git push -u origin main
Option 3: Import from another repo
Choose connection method: HTTPS (requires user/password) or SSH (requires key setup). SSH is recommended.
Configuring SSH Keys
cd ~/.ssh
ssh-keygen -t rsa -b 4096 # create key pair; press Enter for default file
ls -ltr # id_rsa (private) and id_rsa.pub (public)
cat id_rsa.pub # copy the public key
On GitHub: Settings → SSH and GPG keys → New SSH key → paste key → Add.
If you used a custom filename (e.g., mykey), create a config file:
touch ~/.ssh/config
echo "Host github.com" >> ~/.ssh/config
echo " HostName github.com" >> ~/.ssh/config
echo " PreferredAuthentications publickey" >> ~/.ssh/config
echo " IdentityFile ~/.ssh/mykey" >> ~/.ssh/config
Clone using SSH:
git clone git@github.com:username/repo.git
cd repo
echo "new file" > test.txt
git add . && git commit -m "add test.txt"
git push # push to remote
git pull # pull changes from remote
- Branching and Merging
Branches allow independent development lines.
git branch # list branches
git branch feature # create branch 'feature'
git checkout feature # switch to 'feature' (older)
git switch feature # switch (recommended)
git merge feature # merge 'feature' into current branch
git log --graph --oneline --decorate --all # visual branch history
git branch -d feature # delete branch (if merged)
git branch -D feature # force delete (even unmerged)
Hadnling Merge Conflicts
git branch dev
git switch dev
echo "dev content" > shared.txt
git commit -am "commit on dev"
git switch main
echo "main content" > shared.txt
git commit -am "commit on main"
git merge dev # conflict: both modified shared.txt
To resolve: edit the conflicted file, remove conflict markers, then:
git add shared.txt
git commit -am "merge conflict resolved"
Abort merge if needed: git merge --abort.
Branch Integration with Rebase
Alternate to merge: git rebase creates a linear history.
git branch -d dev # delete old branch
git checkout -b dev # create and switch
# make some commits on dev
git rebase main # rebase dev onto main (rewrites history)
Create an alias for quick graph viewing:
alias graph="git log --oneline --graph --decorate --all"