Every developer uses Git. It does not matter if you write Python, JavaScript, Rust, or Kotlin. Git tracks your code changes, lets you go back to any previous version, and helps you work with other developers.
In this tutorial, you will install Git, create your first repository, and make your first commit. By the end, you will understand how Git tracks changes.
What Is Git?
Git is a version control system. It saves snapshots of your project over time. Each snapshot is called a commit.
Think of it like this: every time you save a document, you can only go back to the last save. Git lets you go back to any save you ever made.
Git is:
- Free and open source
- Fast — it works locally on your computer
- Distributed — every developer has a full copy of the project history
Installing Git
macOS
git --version
If Git is not installed, macOS will ask you to install the Command Line Tools. Click “Install” and wait.
You can also install it with Homebrew:
brew install git
Linux (Ubuntu/Debian)
sudo apt update
sudo apt install git
Windows
Download the installer from git-scm.com. Run it and keep the default options. After installation, open “Git Bash” from the Start menu.
Verify Installation
git --version
git version 2.47.1
If you see a version number, Git is ready.
Configuring Git
Before you use Git, tell it who you are. This information appears in every commit you make.
git config --global user.name "Alex"
git config --global user.email "alex@example.com"
Set the default branch name to main:
git config --global init.defaultBranch main
Check your settings:
git config --list
user.name=Alex
user.email=alex@example.com
init.defaultbranch=main
The --global flag means these settings apply to all repositories on your computer. You can override them per project by running the same commands without --global inside a project folder.
Creating Your First Repository
A repository (or “repo”) is a folder that Git tracks. Let’s create one.
mkdir my-project
cd my-project
git init
Initialized empty Git repository in /home/alex/my-project/.git/
Git creates a hidden .git folder inside your project. This folder contains all the history and configuration. Do not delete it.
The Git Workflow
Git has three areas where your files can be:
Working Directory → Staging Area → Repository
(edit) (git add) (git commit)
- Working Directory — the files you see and edit
- Staging Area — files you marked as “ready to commit”
- Repository — the saved snapshots (commits)
This might seem complicated at first. Why not just save directly? The staging area lets you choose which changes to include in a commit. You might have changed 5 files but only want to commit 2 of them.
Your First Commit
Let’s create a file and commit it.
echo "Hello, Git!" > hello.txt
Check what Git sees:
git status
On branch main
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
hello.txt
nothing added to commit but untracked files present (use "git add" to track)
Git sees the file but is not tracking it yet. The file is untracked.
Stage the File
git add hello.txt
Check the status again:
git status
On branch main
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: hello.txt
The file is now in the staging area. It is ready to commit.
Commit the File
git commit -m "Add hello.txt"
[main (root-commit) a1b2c3d] Add hello.txt
1 file changed, 1 insertion(+)
create mode 100644 hello.txt
The -m flag lets you write a commit message inline. Every commit needs a message that explains what you changed.
Stage All Files
If you want to stage all changed files at once:
git add .
The . means “everything in the current directory.” This is useful but be careful — it stages everything, including files you might not want to commit.
Checking Status with git status
You already used git status. Here is what each section means:
# After editing hello.txt and creating notes.txt
git status
On branch main
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes)
modified: hello.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
notes.txt
no changes added to commit (use "git add" and/or "git commit -a")
- Modified — a tracked file that changed but is not staged yet
- Untracked — a new file that Git does not know about
- Staged — a file in the staging area, ready to commit
Run git status often. It tells you exactly where things stand.
Viewing History with git log
git log
commit a1b2c3d4e5f6g7h8i9j0 (HEAD -> main)
Author: Alex <alex@example.com>
Date: Mon May 25 09:00:00 2026 +0000
Add hello.txt
Each commit has:
- A hash (the long string of letters and numbers) — a unique ID for this commit
- The author — who made the commit
- The date — when the commit was made
- The message — what the commit is about
For a shorter view:
git log --oneline
a1b2c3d Add hello.txt
This shows just the short hash and the message. Much easier to scan when you have many commits.
Seeing Changes with git diff
Let’s edit our file and see what changed.
echo "This is my first Git project." >> hello.txt
Now see the difference:
git diff
diff --git a/hello.txt b/hello.txt
index 8d0e412..b5a7e43 100644
--- a/hello.txt
+++ b/hello.txt
@@ -1 +1,2 @@
Hello, Git!
+This is my first Git project.
Lines starting with + are added. Lines starting with - are removed. This shows you exactly what changed before you commit.
To see changes that are already staged:
git diff --staged
This is useful when you staged some files and want to review them before committing.
Ignoring Files with .gitignore
Some files should not be in Git. Log files, compiled code, API keys, and IDE settings do not belong in your repository.
Create a .gitignore file in the root of your project:
cat > .gitignore << 'EOF'
# Compiled files
*.class
*.o
build/
# IDE files
.idea/
.vscode/
# OS files
.DS_Store
Thumbs.db
# Environment files
.env
.env.local
# Dependencies
node_modules/
EOF
Each line is a pattern. Git will ignore any file or folder that matches.
Common patterns:
*.log— ignore all files ending in.logbuild/— ignore the entirebuildfolder.env— ignore a specific file!important.log— do NOT ignore this file (exception)
Add and commit the .gitignore file:
git add .gitignore
git commit -m "Add .gitignore"
Always create .gitignore early in your project. If you add a file to Git and then add it to .gitignore later, Git will keep tracking it. You would need to remove it from tracking first with git rm --cached <file>.
Removing and Moving Files
Git has its own commands for removing and renaming files.
Remove a File
git rm old-file.txt
git commit -m "Remove old-file.txt"
This removes the file from both your working directory and Git’s tracking. If you only want to stop tracking the file but keep it on disk:
git rm --cached secret.txt
This is useful when you forgot to add a file to .gitignore and already committed it.
Rename or Move a File
git mv old-name.txt new-name.txt
git commit -m "Rename old-name to new-name"
This is the same as renaming the file manually and running git add on both the old and new names. But git mv does it in one step.
Multiple Commits — Building History
Let’s make a few more commits to see how history builds up:
echo "Project started on May 2026" >> hello.txt
git add hello.txt
git commit -m "Add project start date"
echo "## My Notes" > notes.txt
echo "- Learn Git basics" >> notes.txt
echo "- Practice daily" >> notes.txt
git add notes.txt
git commit -m "Add learning notes"
echo "- Read documentation" >> notes.txt
git add notes.txt
git commit -m "Add documentation reminder to notes"
Now check the history:
git log --oneline
f7g8h9i Add documentation reminder to notes
e6f7g8h Add learning notes
d5e6f7g Add project start date
c4d5e6f Add .gitignore
b3c4d5e Add hello.txt
Each line is a snapshot. You can see exactly what changed and when. This is the power of Git — a complete history of your project.
Putting It All Together
Here is a typical workflow:
# Create or edit files
echo "My notes" > notes.txt
# Check what changed
git status
# See the actual changes
git diff
# Stage the files you want to commit
git add notes.txt
# Commit with a clear message
git commit -m "Add notes file"
# Check the history
git log --oneline
b2c3d4e Add notes file
a1b2c3d Add hello.txt
Each commit is a snapshot. You can always go back to any of them.
Good Commit Messages
Write commit messages that explain what you changed and why:
# Good
git commit -m "Add user login validation"
git commit -m "Fix crash when email is empty"
git commit -m "Remove unused database helper"
# Bad
git commit -m "update"
git commit -m "fix"
git commit -m "asdfgh"
A good commit message helps you (and your team) understand what happened when you read the history months later.
Some teams follow conventions like starting with a verb in the present tense:
git commit -m "Add search feature" # not "Added search feature"
git commit -m "Fix memory leak" # not "Fixed memory leak"
git commit -m "Update dependencies" # not "Updated dependencies"
This is not a strict rule, but being consistent helps everyone on the team.
Checking What Will Be Committed
Before committing, it is a good habit to review your staged changes:
git diff --staged
This shows exactly what will go into the next commit. If you see something unexpected, unstage it:
git restore --staged <file>
Another useful command is git status -s for a compact view:
git status -s
M hello.txt
A notes.txt
?? temp.txt
M— modified and stagedA— new file, staged??— untracked
Common Mistakes
Forgetting to stage files — Running
git commitwithoutgit addfirst does nothing. Git only commits what is in the staging area. Usegit statusto check before committing.Committing sensitive files — API keys, passwords, and
.envfiles should never be in Git. Create.gitignoreat the start of every project. If you already committed a secret, changing.gitignoredoes not remove it from history.Writing vague commit messages — Messages like “fix” or “update” are useless when you read the history later. Take 5 seconds to write something meaningful like “Fix login crash on empty email.”
What’s Next?
In the next tutorial, we will learn about branches — how to work on multiple features at the same time without breaking your main code.
Git Tutorial #2: Branching — Work on Multiple Things at Once
For a quick reference of all Git commands, check the Git Commands Cheat Sheet.
This is part 1 of the DevTools Tutorial series.