
Getting Started with Git: Create Your First Repository
Git becomes easier when you stop treating it as a list of commands and start seeing it as a workflow. A file is created or changed in the working directory, selected through the staging area, and recorded as part of the repository history.
This guide turns that model into a complete practical exercise. You will create a small project, initialize a repository, inspect file states, prepare changes, create commits, ignore generated files, compare revisions, and verify that the repository is clean.
The goal is not to memorize commands. It is to understand what changes inside Git after every command you run.
What You Will Build
We will create a small command-line project called Task Notes. It will begin with a README file and a simple text-based task list.
The final project structure will look like this:
task-notes/
├── .gitignore
├── README.md
├── notes/
│ └── tasks.txt
└── src/
└── app.txtDuring the exercise, you will learn how to:
Create a new project directory.
Initialize a Git repository.
Inspect the hidden
.gitdirectory.Read the output of
git status.Understand untracked, tracked, modified, staged, and committed states.
Stage individual files and groups of files.
Create focused commits.
Use
git diffbefore committing.Ignore temporary and sensitive files.
Remove a file from Git tracking without deleting the local copy.
View a compact project history.
Confirm that the working tree is clean.
Prerequisites
Before continuing, verify that Git is installed and that your identity is configured:
git --version
git config --get user.name
git config --get user.emailThe name and email commands should return the identity you want written into new commits.
If either value is missing, configure it:
git config --global user.name "Jane Developer"
git config --global user.email "jane@example.com"Also confirm the default initial branch name:
git config --get init.defaultBranchIf no value appears, you can initialize the project explicitly with git init -b main, or configure the global default:
git config --global init.defaultBranch mainTwo Ways to Get a Git Repository
There are two main ways to begin working with a Git repository:
Initialize Git inside a new or existing local project.
Clone an existing repository from another location.
This guide focuses on the first method because it exposes the full workflow from an ordinary folder to the first commit.
Cloning will be covered later when remote repositories and collaboration are introduced.
Step 1: Create the Project Directory
macOS, Linux, or Git Bash
mkdir task-notes
cd task-notesPowerShell
New-Item -ItemType Directory task-notes
Set-Location task-notesAt this moment, task-notes is only a normal directory. Git is not tracking it.
Check the current location:
pwdIn PowerShell, Get-Location provides the same information:
Get-LocationMake sure you are inside the intended project directory before initializing Git. Running git init in the wrong directory can cause Git to track files you did not intend to include.
Step 2: Initialize the Repository
Run:
git init -b mainA successful result will indicate that an empty Git repository was initialized.
If your Git version or environment does not support the -b option, run:
git initThen verify the initial branch name:
git branch --show-currentBefore the first commit, some commands may describe the branch as unborn because the branch name exists conceptually but does not yet point to a commit.
What git init Actually Does
git init creates a hidden directory named .git inside the project. This directory contains the internal data Git needs to manage the repository.
It includes structures for:
Objects representing project content and commits.
References to branches and tags.
Repository-specific configuration.
The staging area, also called the index.
Logs and metadata used by Git operations.
The visible project files remain in the working directory. Git stores repository metadata separately inside .git.
Inspect the Hidden Directory
On macOS, Linux, or Git Bash:
ls -laOn PowerShell:
Get-ChildItem -ForceYou should see .git.
Do not manually edit or delete files inside .git unless you understand Git internals and have a recovery plan. Removing that directory removes the repository history and configuration from the working folder.
Can git init Be Run Again?
Running git init inside an existing repository normally reinitializes the repository without deleting its commit history. However, repeatedly running it is unnecessary and does not create a new nested repository unless you run it inside a separate subdirectory.
Step 3: Check the Initial Repository Status
Run:
git statusThe result should show that you are on the initial branch, no commits exist yet, and there is currently nothing to commit.
git status is one of the most important daily commands. It answers questions such as:
Which branch am I on?
Which files are untracked?
Which tracked files were modified?
Which changes are staged for the next commit?
Is the working tree clean?
Run it frequently. It is a safe inspection command and does not modify files or repository history.
Short Status Output
Git also provides a compact form:
git status --shortAt this stage it should produce no output because the directory contains no project files.
Step 4: Create the First Project File
macOS, Linux, or Git Bash
cat > README.md <<'EOF'
# Task Notes
A small project for practicing the basic Git workflow.
## Features
- Store task notes
- Organize project files
- Practice meaningful Git commits
EOFPowerShell
@"
# Task Notes
A small project for practicing the basic Git workflow.
## Features
- Store task notes
- Organize project files
- Practice meaningful Git commits
"@ | Set-Content README.mdNow run:
git statusGit should place README.md under Untracked files.
What Is an Untracked File?
An untracked file exists in the working directory but is not yet part of Git’s tracked history.
Git notices that the file exists, but it will not automatically include it in a commit.
This is an important safety feature. A project directory may contain temporary files, logs, generated output, credentials, or personal editor settings. Git requires you to deliberately choose which new files become tracked.
The compact status output represents an untracked file with two question marks:
git status --shortExpected output:
?? README.mdStep 5: Stage the README File
Run:
git add README.mdThen inspect the status again:
git statusThe file should now appear under Changes to be committed.
In short format:
A README.mdThe letter A means the file has been added to the staging area.
What git add Means
git add has two closely related roles:
It begins tracking a new file.
It updates the staged version of a tracked file.
The command does not create a commit. It prepares the exact content that the next commit will record.
A useful mental model is:
Working Directory
|
| git add README.md
v
Staging Area
|
| git commit
v
Repository HistoryThe Staging Area Is a Snapshot, Not a File List
Beginners often imagine the staging area as a list of filenames. More precisely, it contains the versions of files selected for the next commit.
This distinction matters. A file can be staged and then modified again. Git will keep the staged version for the next commit while the newer edit remains unstaged in the working directory.
You will see this behavior later in the exercise.
Step 6: Review the Staged Change
Run:
git diff --stagedYou may also see the equivalent form:
git diff --cachedThe output shows what the next commit will contain relative to the current commit. Because this repository has no previous commit, Git displays the entire new file as added content.
Use this command before important commits. It helps detect:
Accidental debug code.
Unrelated changes.
Credentials or private information.
Formatting noise.
Files that were staged by mistake.
git status tells you which paths are staged. git diff --staged shows the actual line-level content.
Step 7: Create the First Commit
Run:
git commit -m "Create project README"The -m option provides the commit message directly on the command line.
A successful commit creates the first recorded snapshot in the repository.
Check the status:
git statusExpected result:
On branch main
nothing to commit, working tree cleanThe exact wording may vary slightly by Git version, but the meaning is the same: the working directory and staging area match the latest commit.
What the First Commit Contains
The commit stores:
The staged version of
README.md.The author and committer identity.
The date and time.
The message
Create project README.A unique commit identifier.
A reference to the project snapshot.
The first commit has no parent commit because it begins the project history.
Step 8: View the Commit History
Run:
git logThe output shows the commit identifier, author, date, and message.
For a compact history:
git log --onelineExample:
7a93c2e Create project READMEYour identifier will be different.
Inspect the most recent commit and its changes:
git show --stat
git show --onelineThe first commit proves that Git is installed, configured, and able to record history correctly.
Step 9: Add Project Directories and Files
macOS, Linux, or Git Bash
mkdir -p notes src
cat > notes/tasks.txt <<'EOF'
[ ] Learn git status
[ ] Learn git add
[ ] Learn git commit
EOF
cat > src/app.txt <<'EOF'
Task Notes Application
Version: 0.1.0
EOFPowerShell
New-Item -ItemType Directory notes, src
@"
[ ] Learn git status
[ ] Learn git add
[ ] Learn git commit
"@ | Set-Content notes/tasks.txt
@"
Task Notes Application
Version: 0.1.0
"@ | Set-Content src/app.txtRun:
git status --shortDepending on how Git summarizes untracked directories, you may see:
?? notes/
?? src/Git tracks files, not empty directories. A directory appears in repository history only through tracked content inside it.
Staging One File, a Directory, or the Current Tree
You can stage a specific file:
git add notes/tasks.txtYou can stage all relevant changes inside a directory:
git add src/You can stage changes under the current directory:
git add .You can also stage updates across the repository with:
git add -AFor a beginner, the important difference is not memorizing every variation. It is avoiding blind staging.
After a broad command such as git add ., always review:
git status
git diff --stagedBroad staging is convenient, but it can include files you did not intend to commit.
Step 10: Create a Focused Second Commit
Stage only the task list:
git add notes/tasks.txtCheck status:
git status --shortYou should see the task file staged while the source directory remains untracked.
Review the staged content:
git diff --stagedCommit it:
git commit -m "Add initial learning tasks"Now stage and commit the application description separately:
git add src/app.txt
git commit -m "Add application version information"This creates two focused commits instead of one broad commit containing unrelated ideas.
View the history:
git log --onelineExample:
ca52d10 Add application version information
34e8c91 Add initial learning tasks
7a93c2e Create project READMEWhy Focused Commits Matter
A commit should represent one understandable unit of work.
Focused commits are easier to:
Review.
Explain.
Test.
Search in history.
Revert when a problem occurs.
Move between branches later.
A single commit named update project that changes documentation, application logic, formatting, and configuration provides little useful history.
A better history explains how the project evolved through deliberate steps.
Step 11: Modify an Existing Tracked File
Add a new section to README.md.
macOS, Linux, or Git Bash
cat >> README.md <<'EOF'
## Usage
Open `notes/tasks.txt` and update the task status.
EOFPowerShell
@"
## Usage
Open `notes/tasks.txt` and update the task status.
"@ | Add-Content README.mdRun:
git status --shortExpected result:
M README.mdThe position of the letter matters in short status output. Here, the change exists in the working directory but has not been staged.
Step 12: Inspect Unstaged Changes
Run:
git diffWithout additional options, git diff shows changes in the working directory that are not currently staged.
It compares:
Working Directory vs Staging AreaBy contrast:
git diff --stagedcompares:
Staging Area vs Latest CommitThis distinction is fundamental.
| Command | What It Shows |
|---|---|
git status | A summary of file states |
git diff | Unstaged line-level changes |
git diff --staged | Staged line-level changes for the next commit |
git log --oneline | A compact commit history |
git show | Details of a commit or another Git object |
Step 13: See Staged and Unstaged Versions of the Same File
Stage the current README:
git add README.mdNow add one more line without staging it.
macOS, Linux, or Git Bash
echo "" >> README.md
echo "This project is used for Git practice." >> README.mdPowerShell
"" | Add-Content README.md
"This project is used for Git practice." | Add-Content README.mdRun:
git status --shortYou should see:
MM README.mdThe first M means a modified version is staged. The second M means the working directory contains an additional unstaged modification.
Inspect each layer:
# Shows the additional unstaged line
git diff
# Shows the earlier staged README change
git diff --stagedThis demonstrates why the staging area is a snapshot. Running git add README.md captured the file as it existed at that moment. Later edits did not automatically update the staged version.
To include the latest working version in the commit, stage the file again:
git add README.mdNow:
git diffshould show no unstaged difference, while:
git diff --stagedshows the complete README update.
Commit it:
git commit -m "Document basic project usage"Step 14: Create a .gitignore File
Projects often generate files that should not enter version control, such as logs, temporary output, local environment files, dependency directories, and editor caches.
Create some files that should remain local.
macOS, Linux, or Git Bash
mkdir logs
echo "Temporary application output" > logs/app.log
echo "APP_SECRET=do-not-commit" > .env
echo "Temporary notes" > scratch.tmpPowerShell
New-Item -ItemType Directory logs
"Temporary application output" | Set-Content logs/app.log
"APP_SECRET=do-not-commit" | Set-Content .env
"Temporary notes" | Set-Content scratch.tmpCheck the status:
git status --shortGit should report the new untracked paths.
Create .gitignore.
macOS, Linux, or Git Bash
cat > .gitignore <<'EOF'
# Local environment secrets
.env
.env.*
# Application logs
logs/
*.log
# Temporary files
*.tmp
# Common operating-system files
.DS_Store
Thumbs.db
EOFPowerShell
@"
# Local environment secrets
.env
.env.*
# Application logs
logs/
*.log
# Temporary files
*.tmp
# Common operating-system files
.DS_Store
Thumbs.db
"@ | Set-Content .gitignoreRun:
git status --shortThe ignored files should disappear from normal status output. The .gitignore file itself remains visible because it should be committed as part of the project policy.
Stage and commit it:
git add .gitignore
git commit -m "Ignore local secrets, logs, and temporary files"How .gitignore Patterns Work
Common patterns include:
# Ignore one exact file
.env
# Ignore every .log file
*.log
# Ignore a directory and its contents
logs/
# Ignore temporary files anywhere
*.tmp
# Ignore a file only at the repository root
/config.local.php
# Ignore everything in build except one required file
build/*
!build/.gitkeepBlank lines are ignored, and lines beginning with # are comments unless the character is escaped.
A repository-level .gitignore should describe shared project rules. Personal editor and operating-system patterns can also be stored in a global ignore file configured for one developer.
.gitignore Does Not Affect Tracked Files
This is one of the most common beginner surprises.
If a file is already tracked, adding its name to .gitignore does not remove it from Git history or stop Git from noticing future changes.
Ignore rules apply to intentionally untracked files.
To stop tracking a file while keeping it in the working directory:
git rm --cached path/to/fileThen commit the removal from the repository index.
For a directory:
git rm -r --cached path/to/directoryUse these commands carefully and review the staged result before committing.
Debug an Ignore Rule
If you do not understand why Git is ignoring a file, use:
git check-ignore -v logs/app.logThe output identifies the ignore file and pattern responsible for the match.
To display ignored files in status output:
git status --ignored --shortThis is useful when a required file appears to be missing from the repository.
Step 15: Add Another Task and Commit It
Update notes/tasks.txt.
macOS, Linux, or Git Bash
cat > notes/tasks.txt <<'EOF'
[x] Learn git status
[x] Learn git add
[x] Learn git commit
[ ] Learn Git branches
EOFPowerShell
@"
[x] Learn git status
[x] Learn git add
[x] Learn git commit
[ ] Learn Git branches
"@ | Set-Content notes/tasks.txtReview the change:
git status
git diffStage it:
git add notes/tasks.txtReview exactly what is staged:
git diff --stagedCommit:
git commit -m "Update completed Git learning tasks"Step 16: Rename a Tracked File
Rename src/app.txt to src/version.txt.
Use Git’s move command:
git mv src/app.txt src/version.txtCheck the status:
git status --shortGit should report a staged rename, commonly represented by R.
Commit it:
git commit -m "Rename application information file"Does Git Store Renames Directly?
Git generally records snapshots and later detects renames by comparing content similarity. The git mv command is a convenient combination of a filesystem move and staging the related deletion and addition.
You could also rename the file with an operating-system command and then stage the changes. Git may still recognize the result as a rename.
Step 17: Delete a Tracked File
For demonstration, create and commit an obsolete file.
macOS, Linux, or Git Bash
echo "Obsolete draft" > old-notes.txt
git add old-notes.txt
git commit -m "Add temporary project draft"PowerShell
"Obsolete draft" | Set-Content old-notes.txt
git add old-notes.txt
git commit -m "Add temporary project draft"Now remove it through Git:
git rm old-notes.txtThis removes the working file and stages the deletion.
Review:
git status
git diff --stagedCommit:
git commit -m "Remove obsolete project draft"Deleting a tracked file with the operating-system command is also possible, but you must stage the deletion afterward.
Understanding the File Lifecycle
A file can move through several states:
New file
|
v
Untracked
|
| git add
v
Staged
|
| git commit
v
Tracked and committed
|
| edit the file
v
Tracked and modified
|
| git add
v
Staged again
|
| git commit
v
New committed versionA tracked file can also be deleted, renamed, or intentionally removed from the index.
| State | Meaning | Typical Next Action |
|---|---|---|
| Untracked | The file exists but Git is not tracking it | git add or add an ignore rule |
| Modified | A tracked file differs from its staged version | Review with git diff |
| Staged | The selected version is prepared for the next commit | Review and commit |
| Committed | The version is recorded in repository history | Continue development |
| Ignored | An untracked path matches an ignore rule | Usually leave it local |
Reading git status --short
The short format uses two status columns:
XY PATHX: Difference between the latest commit and the staging area.
Y: Difference between the staging area and the working directory.
Common examples:
?? file.txt Untracked file
A file.txt New file staged
M file.txt Tracked file modified but not staged
M file.txt Modified version staged
MM file.txt Staged change plus another unstaged change
D file.txt Deletion staged
R old -> new Rename stagedThe long status output is easier for beginners, while the short form becomes useful for fast daily inspection and scripts.
Useful Path-Specific Commands
Inspect only one file:
git status --short README.mdView unstaged changes for one file:
git diff -- README.mdView staged changes for one file:
git diff --staged -- README.mdStage one directory:
git add notes/The double dash separates command options from paths. It becomes especially useful when a filename resembles an option or when command syntax becomes more complex.
What git add . Can Accidentally Include
The command:
git add .is convenient, but it may stage:
Debug output.
Temporary files.
Generated builds.
Large assets.
Local configuration.
Credentials that were not ignored.
Unrelated edits from another task.
Use this safe sequence:
git status
git add .
git status
git diff --staged
git commit -m "Describe the logical change"Never assume that a broad staging command selected only the files you intended.
Do Not Commit Secrets
Before every first commit and before adding new configuration files, check for:
Passwords.
API keys.
Database connection strings.
Cloud credentials.
Private SSH keys.
Access tokens.
Real production environment files.
Adding .env to .gitignore helps prevent accidental tracking, but ignore rules are not a security system. Review staged content before committing.
If a real secret is committed, removing it in a later commit does not make the earlier value safe. Rotate or revoke the secret immediately, then clean history through an appropriate process.
Check the Final Repository
Run:
git status
git log --oneline --decorateThe status should report a clean working tree.
Inspect tracked files:
git ls-filesExpected tracked content:
.gitignore
README.md
notes/tasks.txt
src/version.txtThe ignored .env, logs/app.log, and scratch.tmp files should not appear.
Inspect ignored files separately:
git status --ignored --shortInspect the history as a graph:
git log --oneline --graph --decorate --allBecause no branches have diverged yet, the graph should appear as a straight sequence of commits.
Manual Run: What Changed After Every Command?
The following manual trace summarizes the internal state of the exercise.
1. Before git init
Working directory: Exists
.git directory: Does not exist
Repository history: Does not exist
Staging area: Does not exist2. After git init -b main
Working directory: Exists
.git directory: Created
Current branch: main
Commits: None
Staging area: Empty3. After Creating README.md
README.md: Untracked
Staging area: Empty
Commits: None4. After git add README.md
README.md: Tracked and staged
Staging area: Contains README.md snapshot
Commits: None5. After the First git commit
README.md: Tracked and committed
Latest commit: Create project README
Staging area: Matches latest commit
Working tree: Clean6. After Editing README.md
Committed version: Still preserved
Staged version: Still matches committed version
Working version: Modified
git diff: Shows the new edit7. After Staging and Editing Again
Committed version: Original committed content
Staged version: First new edit
Working version: First new edit plus second new edit
git diff --staged: Shows first edit
git diff: Shows second edit8. After Staging Again and Committing
Committed version: Contains both edits
Staging area: Matches latest commit
Working directory: Matches staging area
Working tree: CleanThis is the core Git model in action.
Common Beginner Mistakes
Running git init in the Wrong Directory
Always check the current path before initialization. A repository created too high in the filesystem may begin observing unrelated files.
Assuming git add Saves a Commit
git add prepares content. git commit records it in history.
Assuming git commit Includes Every Changed File
A normal commit records staged content. Unstaged and untracked changes remain outside the commit.
Using git add . Without Reviewing
Broad staging can include unrelated or sensitive files. Inspect both status and staged diff.
Creating One Large “Initial Commit” Without Inspection
Even a first commit should exclude generated files, dependencies, logs, secrets, and local configuration.
Adding a Tracked Secret to .gitignore
Ignore rules do not stop Git from tracking a file already in history.
Editing Files Inside .git
The .git directory is repository infrastructure. Treat it as internal unless you are deliberately studying Git internals.
Writing Meaningless Commit Messages
Messages such as changes, update, or fix do not explain the purpose of the snapshot.
Mixing Several Tasks in One Commit
Documentation, refactoring, bug fixes, and new features should usually be separated when they represent different logical changes.
Best Practices for Your First Repositories
Initialize Git at the project root.
Create
.gitignorebefore staging a large project.Run
git statusfrequently.Review unstaged work with
git diff.Review the next commit with
git diff --staged.Stage files intentionally.
Keep commits focused.
Use clear, action-oriented commit messages.
Never commit secrets.
End each completed task with a clean working tree when practical.
Command Reference from This Tutorial
| Command | Purpose |
|---|---|
git init -b main | Initialize a repository with the initial branch named main |
git status | Show detailed working tree and staging information |
git status --short | Show compact status codes |
git add file | Stage the current version of one file |
git add . | Stage relevant changes under the current directory |
git diff | Show unstaged changes |
git diff --staged | Show changes prepared for the next commit |
git commit -m "message" | Create a commit from staged content |
git log --oneline | Display compact commit history |
git show | Inspect the latest commit by default |
git check-ignore -v path | Explain which ignore rule matches a path |
git mv old new | Move or rename a file and stage the result |
git rm file | Remove a tracked file and stage the deletion |
git ls-files | List files currently tracked in the index |
Getting Started Checklist
Before moving to the deeper staging and commit article, confirm that you can:
Create a project directory.
Initialize a repository with
git init.Explain the purpose of the
.gitdirectory.Recognize an untracked file.
Stage a specific file.
Create a commit with a meaningful message.
Distinguish
git difffromgit diff --staged.Explain why a staged file can also have unstaged changes.
Create and test a
.gitignorefile.Recognize that tracked files are not affected by new ignore rules.
Read common short status codes.
Verify that the repository has a clean working tree.
Frequently Asked Questions
Can I Run git init Inside an Existing Project?
Yes. Git can be initialized inside an existing project directory. Create a suitable .gitignore and inspect all untracked files before staging the first commit.
Does git init Upload the Project?
No. It creates a local repository. Uploading or sharing commits requires a remote repository and a later push operation.
Does Git Track Empty Directories?
No. Git tracks file content. Projects sometimes place a file such as .gitkeep in an otherwise empty directory, but that filename has no special built-in meaning to Git.
What Is the Difference Between git add and git commit?
git add prepares selected file versions in the staging area. git commit records the staged snapshot in repository history.
Why Does git diff Show Nothing After git add?
Normal git diff shows unstaged changes. After staging, use git diff --staged to inspect the content prepared for the next commit.
Can I Commit Only One File?
Yes. Stage only that file, review the staged diff, and create the commit.
Should I Always Use git add .?
No. It is convenient when all current changes belong together, but specific paths or interactive staging provide better control when several tasks are mixed.
Why Is an Ignored File Still Tracked?
It was probably committed or staged before the ignore rule was added. Ignore patterns do not affect already tracked files.
What Does “Working Tree Clean” Mean?
It means Git sees no tracked modifications, staged differences, or reportable untracked files relative to the current commit and ignore rules.
Can I Delete the .git Directory?
Deleting it turns the working folder back into a normal directory and removes the local repository metadata and history. Do so only when that is explicitly your intention and any required history is safely stored elsewhere.
Conclusion
Your first Git repository demonstrates the complete basic workflow: initialize a project, create files, inspect their state, stage selected versions, review the staged content, and record focused commits.
The most important lesson is that Git manages multiple states at once. The working directory contains current edits, the staging area contains the proposed next snapshot, and the repository stores committed history. Commands such as git status, git diff, and git diff --staged reveal the differences between those states.
A disciplined workflow is simple: inspect, edit, inspect again, stage deliberately, review the staged diff, commit with a meaningful message, and verify the final status.
The next article will examine staging and commits in greater depth, including partial staging, unstaging, amending commits, commit-message structure, and strategies for creating a clean and useful history.
Official References and Further Reading

