Git Reset and .gitignore Fundamentals: Managing Changes and Ignored Files for Beginners

Master git reset commands and .gitignore file patterns to control what Git tracks. Learn the difference between git reset and git reset --hard, create effective .gitignore files, and manage your repository's staging area with practical examples.

21 min read

Git's power lies not just in tracking your code changes, but also in giving you precise control over what gets tracked and how to manage those changes. Two essential skills every developer needs are understanding how to reset changes with git reset and controlling what Git ignores with .gitignore files.

💡

🎯 What You'll Learn: In this comprehensive Git tutorial, you'll master:

  • Understanding Git's staging area and working directory
  • The difference between git reset and git reset --hard
  • How to unstage files without losing changes
  • How to discard changes completely with reset --hard
  • Creating and using .gitignore files effectively
  • Common .gitignore patterns for different file types
  • Managing directories and file extensions with .gitignore
  • Best practices for repository cleanliness

🏗️ Understanding Git's Three Areas

Before diving into reset commands, let's understand how Git organizes your files:

The Three Key Areas

  1. Working Directory: Your actual files that you edit
  2. Staging Area: Files prepared for the next commit
  3. Repository: Committed snapshots of your project
AreaPurposeCommands That Affect It
Working DirectoryFiles you're currently editinggit reset --hard, file edits
Staging AreaFiles ready for next commitgit add, git reset
RepositoryPermanent project historygit commit

🔄 Understanding Git Status Output

Let's start by understanding what git status tells us. This command shows the current state of our working directory and staging area.

git status

Sample Output:

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   second

no changes added to commit (use "git add" and/or "git commit -a")

Understanding the Output:

  • "On branch master": Shows which branch you're currently on
  • "Changes not staged for commit": Files that are modified but not yet added to staging area
  • "modified: second": The file second has been changed since the last commit
  • "no changes added to commit": Nothing is currently staged for commit

Git Status: This is your most important command for understanding what Git sees. Always run git status before making any changes to understand your current state.

📝 Making Changes and Staging Files

Let's see how changes move through Git's three areas:

nano first.txt

Add some content:

hello

working

new changes
git status

Output:

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   first.txt
	modified:   second

no changes added to commit (use "git add" and/or "git commit -a")

What This Shows:

  • Both first.txt and second have been modified
  • Changes exist in working directory but not in staging area
  • Git suggests using git add to stage changes or git restore to discard them

Now let's stage the changes:

git add .
git status

Output:

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   first.txt
	modified:   second

What Changed:

  • Files moved from "Changes not staged" to "Changes to be committed"
  • Both files are now in the staging area
  • Git suggests using git restore --staged to unstage files

🔄 Git Reset: Unstaging Changes

The basic git reset command moves files from the staging area back to the working directory without deleting your changes.

git reset

Output:

Unstaged changes after reset:
M	first.txt
M	second
git status

Output:

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   first.txt
	modified:   second

no changes added to commit (use "git add" and/or "git commit -a")

Git Reset Behavior: The basic git reset command only affects the staging area. Your working directory changes remain intact. This is safe - you won't lose any work.

Before git resetAfter git reset
Files in staging area (ready to commit)Files back in working directory (not staged)
Your file changes are preservedYour file changes are still preserved

⚠️ Git Reset --Hard: Discarding Changes Completely

The git reset --hard command is more powerful and dangerous - it discards changes in both the staging area AND the working directory.

Let's stage our changes again first:

git add .
git status

Output:

On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   first.txt
	modified:   second

Now let's use the hard reset:

git reset --hard

Output:

HEAD is now at 4d0a85e update first.txt
git status

Output:

On branch master
nothing to commit, working tree clean

Let's verify our changes are gone:

cat first.txt

Output:

hello

working

The "new changes" line we added is gone! Let's check the other file:

cat second

Output: (Empty file - no content)

⚠️

⚠️ Warning: git reset --hard permanently deletes changes that aren't committed. Use this command carefully! Always make sure you really want to discard your work before using it.

🔄 Demonstrating the Difference

Let's clearly demonstrate the difference between git reset and git reset --hard:

Test 1: Regular Git Reset (Safe)

nano second

Add content:

hello
git status

Output:

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   second

no changes added to commit (use "git add" and/or "git commit -a")
git reset

Output:

Unstaged changes after reset:
M	second

Since nothing was staged, the reset had no effect:

git status

Output:

On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
	modified:   second

no changes added to commit (use "git add" and/or "git commit -a")

Test 2: Hard Reset (Destructive)

git reset --hard

Output:

HEAD is now at 4d0a85e update first.txt
cat second

Output: (Empty file - our "hello" content is gone)

CommandStaging AreaWorking DirectorySafety
git resetClearedUnchanged✅ Safe
git reset --hardClearedReset to last commit⚠️ Destructive

📁 Introduction to .gitignore

The .gitignore file tells Git which files and directories to ignore. This is crucial for keeping your repository clean by excluding:

  • Temporary files
  • Build artifacts
  • Environment-specific files
  • Sensitive information
  • IDE configuration files

Let's start with a practical example:

git status

Output:

On branch master
nothing to commit, working tree clean
touch third.txt
nano third.txt

Content:

this is a new file
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	third.txt

nothing added to commit but untracked files present (use "git add" to track)

Understanding "Untracked files":

  • Git sees third.txt but isn't tracking it yet
  • The file exists in your working directory but Git doesn't know about it
  • You need to git add it to start tracking it

🚫 Creating Your First .gitignore File

touch .gitignore
ls -al

Output:

total 8
drwxr-xr-x. 3 centos9 centos9  84 Sep 23 12:47 .
drwxr-xr-x. 3 centos9 centos9  23 Sep 22 16:44 ..
-rw-r--r--. 1 centos9 centos9  15 Sep 23 12:41 first.txt
drwxr-xr-x. 8 centos9 centos9 183 Sep 23 12:46 .git
-rw-r--r--. 1 centos9 centos9   0 Sep 23 12:47 .gitignore
-rw-r--r--. 1 centos9 centos9   0 Sep 23 12:39 second
-rw-r--r--. 1 centos9 centos9  19 Sep 23 12:46 third.txt

Notice the .gitignore file:

  • It starts with a dot, making it a hidden file
  • Use ls -al to see hidden files (the -a flag shows all files)
  • The .git directory is also hidden
nano .gitignore

Content of .gitignore:

third.txt
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

What happened:

  • third.txt is no longer shown as untracked
  • Git is now ignoring third.txt completely
  • Only .gitignore itself is shown as untracked
  • The .gitignore file is not ignored by default

Gitignore Effect: Once a file is listed in .gitignore, Git acts as if it doesn't exist. The file is still there physically, but Git won't track it or show it in status.

🎯 Gitignore Patterns: Wildcard Matching

Ignoring File Extensions

Instead of ignoring individual files, you can ignore entire file types using patterns:

touch fourth.txt
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	fourth.txt

nothing added to commit but untracked files present (use "git add" to track)
nano .gitignore

New content:

*.txt

Understanding the * wildcard:

  • * matches any characters
  • *.txt means "any file ending with .txt"
  • This will ignore third.txt, fourth.txt, and any future .txt files
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

Result:

  • Both third.txt and fourth.txt are now ignored
  • Only .gitignore is still shown as untracked

Testing with Different File Types

touch test1.xlsx
touch test2.xlsx
ls -al

Output:

total 12
drwxr-xr-x. 3 centos9 centos9 138 Sep 23 13:01 .
drwxr-xr-x. 3 centos9 centos9  23 Sep 22 16:44 ..
-rw-r--r--. 1 centos9 centos9  15 Sep 23 12:41 first.txt
-rw-r--r--. 1 centos9 centos9   0 Sep 23 12:49 fourth.txt
drwxr-xr-x. 8 centos9 centos9 183 Sep 23 13:00 .git
-rw-r--r--. 1 centos9 centos9   6 Sep 23 12:50 .gitignore
-rw-r--r--. 1 centos9 centos9   0 Sep 23 12:39 second
-rw-r--r--. 1 centos9 centos9   0 Sep 23 13:01 test1.xlsx
-rw-r--r--. 1 centos9 centos9   0 Sep 23 13:01 test2.xlsx
-rw-r--r--. 1 centos9 centos9  19 Sep 23 12:46 third.txt
nano .gitignore

Updated content:

*.txt

*.xlsx
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

What we learned:

  • You can have multiple patterns in .gitignore
  • Each pattern goes on its own line
  • Empty lines are allowed for organization
  • Both .txt and .xlsx files are now ignored

Testing Pattern Removal

Let's see what happens when we remove a pattern:

nano .gitignore

Content after removing Excel pattern:

*.txt
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	test1.xlsx
	test2.xlsx

nothing added to commit but untracked files present (use "git add" to track)

Result:

  • .txt files are still ignored
  • .xlsx files are now visible to Git again
  • This shows that .gitignore changes take effect immediately
nano .gitignore

Final content:

*.txt

*.xlsx

📂 Ignoring Directories

You can also ignore entire directories and their contents:

mkdir build
cd build/
touch hello.txt
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	../.gitignore

nothing added to commit but untracked files present (use "git add" to track)

Understanding the output:

  • Git shows ../.gitignore (the parent directory's .gitignore file)
  • The hello.txt file isn't shown because *.txt is ignored
  • But the build directory itself would be tracked if it had non-ignored files
cd ..
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore

nothing added to commit but untracked files present (use "git add" to track)

Now let's test with a specific file ignored instead of the pattern:

nano .gitignore

Content:

third.txt

*.xlsx
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	build/
	fourth.txt

nothing added to commit but untracked files present (use "git add" to track)

What changed:

  • third.txt is still ignored (specific file)
  • fourth.txt is now visible (*.txt pattern removed)
  • build/ directory is visible because it contains a .txt file that's not ignored by the specific pattern

Let's check what's in the build directory from Git's perspective:

cd build/
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	../.gitignore
	./
	../fourth.txt

nothing added to commit but untracked files present (use "git add" to track)

Understanding the paths:

  • ../.gitignore: The .gitignore file in parent directory
  • ./: The current directory (build/)
  • ../fourth.txt: The fourth.txt file in parent directory

Adding Directory to .gitignore

cd ..
nano .gitignore

Content:

third.txt

*.xlsx

build
git status

Output:

On branch master
Untracked files:
  (use "git add <file>..." to include in what will be committed)
	.gitignore
	fourth.txt

nothing added to commit but untracked files present (use "git add" to track)

Result:

  • build/ directory is no longer shown
  • Git ignores the entire directory and everything inside it
  • fourth.txt is still visible because it's not covered by our ignore patterns

Directory Ignoring: When you add a directory name to .gitignore, Git ignores the entire directory and all its contents, regardless of what files are inside.

🎯 Common .gitignore Patterns

PatternWhat It IgnoresExample
filename.txtSpecific fileconfig.local.json
*.txtAll files with .txt extensionnotes.txt, readme.txt
buildDirectory named "build"build/ and all contents
build/Only directories named "build"build/ but not build.txt
/logslogs directory at root only./logs but not src/logs
**/logslogs directory anywherelogs, src/logs, app/logs
logs/**Everything inside logs directoryAll files and subdirs in logs/

🛠️ Real-World .gitignore Examples

Node.js Project

# Dependencies
node_modules/
npm-debug.log*

# Environment variables
.env
.env.local

# Build output
dist/
build/

# IDE files
.vscode/
.idea/

# OS files
.DS_Store
Thumbs.db

Python Project

# Byte-compiled / optimized files
__pycache__/
*.py[cod]
*$py.class

# Virtual environments
venv/
env/
.venv/

# IDE
.vscode/
.idea/

# Build
build/
dist/
*.egg-info/

General Development

# Logs
logs/
*.log

# Temporary files
*.tmp
*.temp
.cache/

# Backups
*.bak
*.backup

# IDE and editor files
.vscode/
.idea/
*.swp
*.swo

# OS generated files
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db

⚠️ Important .gitignore Rules

1. .gitignore Doesn't Affect Already Tracked Files

⚠️

⚠️ Important: If a file is already being tracked by Git, adding it to .gitignore won't stop tracking it. You need to untrack it first with git rm --cached filename.

2. .gitignore Should Be Committed

git add .gitignore
git commit -m "Add .gitignore file"

The .gitignore file should be tracked so that all team members use the same ignore rules.

3. Global .gitignore

You can create a global .gitignore file for patterns you want to ignore across all your projects:

git config --global core.excludesfile ~/.gitignore_global

🎯 Best Practices

PracticeWhyExample
Add .gitignore earlyPrevents accidentally committing unwanted filesCreate .gitignore with first commit
Use commentsMakes .gitignore file easier to understand# Node.js dependencies
Group related patternsOrganizes the file logicallyGroup IDE files together
Never ignore .gitignoreTeam needs to share ignore rulesAlways commit .gitignore file

🚨 Common Mistakes to Avoid

1. Using git reset --hard Without Thinking

git reset --hard  # This deletes your changes permanently!

Better approach:

git status        # Check what you have first
git stash        # Save changes temporarily
# or
git add .        # Stage changes
git commit -m "WIP: work in progress"  # Save changes

2. Ignoring Files That Are Already Tracked

echo "config.json" >> .gitignore

Correct approach:

git rm --cached config.json    # Remove from tracking
echo "config.json" >> .gitignore  # Then ignore
git commit -m "Remove config.json from tracking"

3. Not Testing .gitignore Patterns

git status  # Check if files are properly ignored

🎯 Key Takeaways

✅ Remember These Points

  1. git reset: Safely moves files from staging area to working directory
  2. git reset --hard: Permanently discards changes in both staging and working directory
  3. .gitignore: Controls which files Git ignores completely
  4. Patterns: Use * for wildcards, directory names to ignore folders
  5. Safety: Always check git status before using reset commands

📋 Git Reset and .gitignore Command Cheat Sheet

CommandPurposeSafety
git statusCheck current state of files✅ Always safe
git add .Stage all changes for commit✅ Safe
git resetUnstage files (keep changes)✅ Safe
git reset --hardDiscard all changes permanently⚠️ Destructive
touch .gitignoreCreate .gitignore file✅ Safe
nano .gitignoreEdit .gitignore file✅ Safe
ls -alList all files (including hidden)✅ Safe

Common .gitignore Patterns Cheat Sheet

PatternIgnores
filename.txtSpecific file
*.txtAll .txt files
buildbuild directory
*.logAll log files
node_modules/Node.js dependencies
.envEnvironment variables

🎉 Congratulations! You've mastered Git reset commands and .gitignore files. You now know how to safely manage your staging area, discard changes when needed, and keep your repository clean by ignoring unwanted files. These skills are essential for professional Git workflow management.

Owais

Written by Owais

I'm an AIOps Engineer with a passion for AI, Operating Systems, Cloud, and Security—sharing insights that matter in today's tech world.

I completed the UK's Eduqual Level 6 Diploma in AIOps from Al Nafi International College, a globally recognized program that's changing careers worldwide. This diploma is:

  • ✅ Available online in 17+ languages
  • ✅ Includes free student visa guidance for Master's programs in Computer Science fields across the UK, USA, Canada, and more
  • ✅ Comes with job placement support and a 90-day success plan once you land a role
  • ✅ Offers a 1-year internship experience letter while you study—all with no hidden costs

It's not just a diploma—it's a career accelerator.

👉 Start your journey today with a 7-day free trial

Related Articles

Continue exploring with these handpicked articles that complement what you just read

More Reading

One more article you might find interesting