Skip to main content

Git Basics: Init, Clone, Add, Commit, Push, Pull

·1187 words·6 mins
Linux Learning Lab
Author
Linux Learning Lab
Writing about code, tools, and workflows.
Table of Contents
git-essentials - This article is part of a series.
Part 1: This Article

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
#

ConceptMeaning
Repository (repo)A project directory tracked by Git
CommitA saved snapshot of your changes
Staging area (index)Where you prepare changes before committing
BranchAn independent line of development
RemoteA copy of the repo on another server (GitHub, GitLab)
Working directoryThe files you see and edit

The basic flow:

Edit files → Stage changes → Commit → Push to remote

Creating a Repository
#

Start a new project
#

mkdir my-project
cd my-project
git init

This 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 project

This 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.git

Checking Status
#

git status

This 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 commit

Short status
#

git status -s
 M src/app.js
?? src/utils.js
SymbolMeaning
MModified
AAdded (staged)
??Untracked
DDeleted

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.js

Add all changes
#

git add .

Add interactively (choose hunks)
#

git add -p

This 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.js

The 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 commit

This 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.js

Diff — 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.js

Working with Remotes
#

A remote is a copy of your repo hosted elsewhere — GitHub, GitLab, a company server.

View remotes
#

git remote -v
origin  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.git

Push — send your commits to the remote
#

# First push (set upstream tracking)
git push -u origin main

# Subsequent pushes
git push

The -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 pull

This fetches new commits from the remote and merges them into your current branch. It’s equivalent to:

git fetch
git merge origin/main

Fetch — download without merging
#

git fetch

Downloads 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 filename

Common 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 main

Make changes and push
#

# Edit files...
git status              # See what changed
git add .               # Stage everything
git commit -m "Add feature X"
git push                # Send to remote

Pull 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)
StateMeaningCommand to move forward
ModifiedChanged but not stagedgit add
StagedMarked for next commitgit commit
CommittedSafely stored in historygit push (to share)
# See all three states at once
git status

Quick Reference
#

TaskCommand
Create a repogit init
Clone a repogit clone URL
Check statusgit status
Stage filesgit add FILE or git add .
Commitgit commit -m "message"
View loggit log --oneline
View changesgit diff
Push to remotegit push
Pull from remotegit pull
Discard changesgit restore FILE
Unstage a filegit 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 .gitignore from the start — don’t commit node_modules/, build output, or secrets
  • Pull before you push — avoids merge conflicts on shared branches
  • Don’t commit secrets — API keys, passwords, .env files should never enter Git history (once committed, they’re in history forever)
  • Use git status constantly — it’s your dashboard for understanding the repo state
  • Stage intentionally — use git add file instead of git add . when you have unrelated changes you want in separate commits
git-essentials - This article is part of a series.
Part 1: This Article