What is Git?#
Git is a distributed version control system. It tracks every change you make to your files, lets you revert mistakes, work on multiple features simultaneously, and collaborate with others without overwriting each other’s work.
Every project you work on — code, configuration, documentation — benefits from version control. Git is the standard tool for this.
Core Concepts#
| Concept | Meaning |
|---|---|
| Repository (repo) | A project directory tracked by Git |
| Commit | A saved snapshot of your changes |
| Staging area (index) | Where you prepare changes before committing |
| Branch | An independent line of development |
| Remote | A copy of the repo on another server (GitHub, GitLab) |
| Working directory | The files you see and edit |
The basic flow:
Edit files → Stage changes → Commit → Push to remoteCreating a Repository#
Start a new project#
mkdir my-project
cd my-project
git initThis creates a hidden .git/ directory that stores all version history. Your project is now a Git repository.
Clone an existing project#
git clone https://github.com/user/project.git
cd projectThis downloads the full repo — all files, all history, all branches.
# Clone with a custom directory name
git clone https://github.com/user/project.git my-local-name
# Clone via SSH (if you have SSH keys configured)
git clone git@github.com:user/project.gitChecking Status#
git statusThis is the command you’ll run most often. It shows:
- Which branch you’re on
- Which files are modified
- Which files are staged
- Which files are untracked (new, not yet tracked by Git)
On branch main
Changes not staged for commit:
modified: src/app.js
Untracked files:
src/utils.js
no changes added to commitShort status#
git status -s M src/app.js
?? src/utils.js| Symbol | Meaning |
|---|---|
M | Modified |
A | Added (staged) |
?? | Untracked |
D | Deleted |
Staging Changes#
The staging area lets you choose exactly which changes go into the next commit. You don’t have to commit everything at once.
Add specific files#
git add src/app.js
git add src/utils.jsAdd all changes#
git add .Add interactively (choose hunks)#
git add -pThis shows each change and asks whether to stage it — useful when you’ve made multiple unrelated changes in one file.
Unstage a file#
git restore --staged src/app.jsThe file is still modified, just no longer staged.
Committing#
A commit is a permanent snapshot with a message describing what changed.
git commit -m "Add user authentication module"Multi-line commit message#
git commit -m "Add user authentication module
- Implement JWT token generation
- Add login and logout endpoints
- Include password hashing with bcrypt"Open your editor for the message#
git commitThis opens your configured editor ($EDITOR or core.editor). Write the message, save, and close.
Stage and commit in one step#
git commit -am "Fix typo in README"The -a flag stages all modified tracked files. It won’t add new untracked files — you still need git add for those.
Viewing History#
Log#
# Full log
git log
# Compact one-line format
git log --oneline
# With graph showing branches
git log --oneline --graph
# Last 5 commits
git log -5
# Show what changed in each commit
git log -p
# Commits affecting a specific file
git log -- src/app.jsDiff — what changed?#
# Changes not yet staged
git diff
# Changes that are staged
git diff --staged
# Difference between two commits
git diff abc123 def456
# Changes in a specific file
git diff src/app.jsWorking with Remotes#
A remote is a copy of your repo hosted elsewhere — GitHub, GitLab, a company server.
View remotes#
git remote -vorigin git@github.com:user/project.git (fetch)
origin git@github.com:user/project.git (push)origin is the conventional name for the primary remote (set automatically when you clone).
Add a remote#
git remote add origin git@github.com:user/project.gitPush — send your commits to the remote#
# First push (set upstream tracking)
git push -u origin main
# Subsequent pushes
git pushThe -u flag links your local branch to the remote branch so future pushes/pulls just need git push/git pull.
Pull — get changes from the remote#
git pullThis fetches new commits from the remote and merges them into your current branch. It’s equivalent to:
git fetch
git merge origin/mainFetch — download without merging#
git fetchDownloads new commits and branches from the remote but doesn’t change your working files. Useful to see what’s new before deciding to merge.
The .gitignore File#
Tell Git which files to ignore — build output, dependencies, secrets, editor files.
# .gitignore
node_modules/
dist/
*.log
.env
.DS_Store
*.pyc
__pycache__/# Create it
echo "node_modules/" > .gitignore
echo "dist/" >> .gitignore
git add .gitignore
git commit -m "Add .gitignore"Check if a file is ignored#
git check-ignore -v filenameCommon Workflows#
Start a new project and push to GitHub#
mkdir my-project && cd my-project
git init
echo "# My Project" > README.md
git add .
git commit -m "Initial commit"
git remote add origin git@github.com:user/my-project.git
git push -u origin mainMake changes and push#
# Edit files...
git status # See what changed
git add . # Stage everything
git commit -m "Add feature X"
git push # Send to remotePull changes before starting work#
git pull # Get latest from remote
# Now start your work...Undo changes to a file (discard edits)#
# Discard unstaged changes (revert to last commit)
git restore src/app.js
# Discard all unstaged changes
git restore .Remove a file from Git#
# Remove from Git and filesystem
git rm old-file.txt
git commit -m "Remove old-file.txt"
# Remove from Git but keep the file locally
git rm --cached secrets.env
git commit -m "Stop tracking secrets.env"Understanding the Three States#
Every file in a Git repo is in one of three states:
Working Directory → Staging Area → Repository
(edit) (add) (commit)| State | Meaning | Command to move forward |
|---|---|---|
| Modified | Changed but not staged | git add |
| Staged | Marked for next commit | git commit |
| Committed | Safely stored in history | git push (to share) |
# See all three states at once
git statusQuick Reference#
| Task | Command |
|---|---|
| Create a repo | git init |
| Clone a repo | git clone URL |
| Check status | git status |
| Stage files | git add FILE or git add . |
| Commit | git commit -m "message" |
| View log | git log --oneline |
| View changes | git diff |
| Push to remote | git push |
| Pull from remote | git pull |
| Discard changes | git restore FILE |
| Unstage a file | git restore --staged FILE |
Best Practices#
- Commit often — small, focused commits are easier to understand and revert than large ones
- Write meaningful messages — “Fix login timeout by increasing session duration” beats “fix bug”
- Use
.gitignorefrom the start — don’t commitnode_modules/, build output, or secrets - Pull before you push — avoids merge conflicts on shared branches
- Don’t commit secrets — API keys, passwords,
.envfiles should never enter Git history (once committed, they’re in history forever) - Use
git statusconstantly — it’s your dashboard for understanding the repo state - Stage intentionally — use
git add fileinstead ofgit add .when you have unrelated changes you want in separate commits


