📝 Git & GitHub

Common Git Mistakes Beginners Make: How to Avoid Them 🚨

0
Author
04e5cc8b-58ac-4bdc-bdee-661bbb
📅
Published
06.05.2026
⏱️
Reading time
6 min
👁️
Views
51
🌱
Level
Beginner

Working with Git for the first time? We’ve all been there! Let’s go through the top mistakes and how to avoid them.

Early Mistakes: Branches, Commits, Files and Security

1. Committing Directly to main/master

❌ Mistake:

Doing everything straight in main:

# Bad
git add .
git commit -m "fix"
git push origin main

✅ Right approach:

Create branches for each task:

# Good
git checkout -b feature/add-login
# ... make your changes ...
git add .
git commit -m "feat: add user login form"
git push origin feature/add-login
# Then open a Pull Request

Why it matters:
- main should stay stable
- Easier to revert changes
- You can work on multiple tasks in parallel
- Code review before merging

2. Bad Commit Messages

❌ Bad examples:

git commit -m "fix"
git commit -m "update"
git commit -m "asdfasdf"
git commit -m "commit"
git commit -m "done"

✅ Good examples:

git commit -m "fix: fix email validation error"
git commit -m "feat: add export to PDF button"
git commit -m "docs: update API documentation"
git commit -m "refactor: optimize database query"

The good message formula:

<type>: <what was done>

feat - new feature
fix - bug fix
docs - documentation
refactor - refactoring
test - tests
chore - routine tasks

3. Committing Everything Blindly

❌ Mistake:

git add .
git commit -m "changes"

The commit ends up containing:
- .env with passwords 😱
- node_modules/ (millions of files)
- .DS_Store (macOS junk)
- __pycache__/ (compiled Python)
- Personal notes

✅ Right approach:

Set up .gitignore first:

# .gitignore
.env
*.pyc
__pycache__/
node_modules/
.DS_Store
*.log
.vscode/
.idea/

Check before committing:

git status  # what will be added?
git diff    # what changed?
git add file1.py file2.py  # add selectively
git commit -m "feat: add auth module"

4. Pushing Secrets to the Repository

❌ DANGEROUS:

# settings.py
SECRET_KEY = "django-insecure-key-123456789"
DATABASE_PASSWORD = "mypassword123"
API_KEY = "sk_live_51234567890abcdef"

☠️ All of this becomes public if the repository is Public!

✅ Right approach:

Use environment variables:

# settings.py
import os
SECRET_KEY = os.getenv('SECRET_KEY')
DATABASE_PASSWORD = os.getenv('DB_PASSWORD')
API_KEY = os.getenv('API_KEY')

Create a .env file (DO NOT commit it!):

# .env
SECRET_KEY=django-insecure-key-123456789
DB_PASSWORD=mypassword123
API_KEY=sk_live_51234567890abcdef

Add to .gitignore:

echo ".env" >> .gitignore
git add .gitignore
git commit -m "chore: add .gitignore for .env"

Create a .env.example for the team:

# .env.example
SECRET_KEY=your-secret-key-here
DB_PASSWORD=your-database-password
API_KEY=your-api-key

Sync and Code Quality Mistakes

5. Not Pulling Before Pushing

❌ Mistake:

# You're working locally...
git commit -m "fix: bug"
git push origin main

# ❌ Error: Updates were rejected

A colleague already pushed changes!

✅ Right approach:

# Pull first
git pull origin main

# Resolve conflicts if any
# Then push
git push origin main

Even better — use rebase:

git pull --rebase origin main
git push origin main

6. Being Afraid of Conflicts

What this looks like:

git pull origin main
# <<< Auto-merging file.py
# <<< CONFLICT (content): Merge conflict in file.py

Don’t panic! Conflicts are normal.

How to resolve:

# file.py
<<<<<<< HEAD
def hello():
    print("Hello")  # Your version
=======
def hello():
    print("Hi")   # Version from origin
>>>>>>> origin/main

Steps:

  1. Open the file
  2. Remove the markers <<<<<<<, =======, >>>>>>>
  3. Choose the code you want (or merge both)
  4. Save the file
# Final version
def hello():
    print("Hello")  # Kept our version
  1. Commit:
git add file.py
git commit -m "fix: resolve conflict in file.py"
git push

7. Not Using Branches

❌ Bad:

Everyone works in main → constant conflicts.

✅ Git Flow (simplified):

# Main branches
main (or master)  - stable code
develop            - development

# Feature branches
feature/login      - new feature
feature/payment    - another feature

# Bugfix branches
bugfix/fix-email   - bug fix

Workflow:

# New feature
git checkout main
git pull origin main
git checkout -b feature/user-profile

# ... work ...

git add .
git commit -m "feat: add user profile"
git push origin feature/user-profile

# Create a Pull Request on GitHub
# After approval:
git checkout main
git pull origin main  # get updated main with your feature
git branch -d feature/user-profile  # delete local branch

8. Huge Commits

❌ Bad:

# 3 days of work, 500 files changed
git add .
git commit -m "done"

Impossible to:
- Understand what changed
- Revert a specific part
- Do a code review

✅ Good:

Make small commits:

# Day 1
git add auth/login.py
git commit -m "feat: add login form"

git add auth/validators.py
git commit -m "feat: email and password validators"

# Day 2
git add auth/views.py
git commit -m "feat: auth view"

git add auth/urls.py
git commit -m "feat: auth routes"

Rule: 1 commit = 1 logical change.

9. Committing Broken Code

❌ Bad:

# Code doesn't work, tests fail
git add .
git commit -m "wip"
git push

Now everyone has broken code!

✅ Right approach:

Before committing:

# Run tests
pytest

# Check code
python manage.py check

# Make sure it runs
python manage.py runserver

Only then:

git add .
git commit -m "feat: add feature X"
git push

If you need to save unfinished work:

git stash  # stash changes
git stash list  # view stash list
git stash pop  # restore changes

Ignoring Important Git Conventions

10. Ignoring .gitignore

❌ Mistake:

After git add . these end up committed:

  • 📦 node_modules/ (200 MB!)
  • 🗄️ Database db.sqlite3
  • 🖼️ Uploaded files media/
  • 📝 Logs debug.log

✅ .gitignore template for Python/Django:

# .gitignore

# Python
*.pyc
__pycache__/
*.py[cod]
*.so
*.egg
*.egg-info/
dist/
build/

# Django
*.log
db.sqlite3
media/
staticfiles/

# Environment
.env
.venv/
venv/
ENV/

# IDE
.vscode/
.idea/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Testing
.coverage
htmlcov/
.pytest_cache/

11. Not Using git status

❌ Blind commands:

git add .
git commit -m "update"
git push

✅ Check before every action:

git status  # what changed?

# You'll see:
# Changes not staged:
#   modified: file1.py
#   deleted: old_file.py
# Untracked files:
#   new_file.py

git diff file1.py  # what exactly changed?

git add file1.py new_file.py  # add consciously
git status  # check again

git commit -m "feat: update file1, add new_file"

12. Force Push to a Shared Branch

❌ DANGEROUS:

git push --force origin main

☠️ This rewrites history for everyone! May destroy a colleague’s work.

✅ Right approach:

Force push only to your own branches:

# Your personal feature branch
git push --force origin feature/my-work

For main/master use:

git push origin main  # without --force!

If you need force push, use the safe version:

git push --force-with-lease origin main
# Checks that history hasn't changed since your last pull

13. Deleting Branches Without Checking

❌ Mistake:

git branch -D feature/important
# Oops, there was unpushed code there! 😱

✅ Right approach:

Check before deleting:

# Are changes pushed?
git branch -vv  # shows remote tracking info

# Is the branch merged?
git branch --merged  # list of merged branches

# Safe delete (only if merged)
git branch -d feature/task  # -d refuses to delete unmerged branches

# Forced (use carefully!)
git branch -D feature/task  # -D deletes regardless

General Tips

Use a GUI if you’re nervous

  • GitHub Desktop - simple interface
  • GitKraken - powerful and beautiful
  • Sourcetree - free from Atlassian
  • VS Code - built-in Git

Learn to undo mistakes

# Undo last commit (changes stay)
git reset --soft HEAD~1

# Undo changes in a file
git checkout -- file.py

# Return to a specific commit
git revert <commit-hash>

# View history
git log --oneline --graph --all

Back up before experimenting

# Create a backup branch
git checkout -b backup/before-experiment

# Experiment in another branch
git checkout -b experiment

# If something broke, go back
git checkout backup/before-experiment

Pre-push Checklist

  • [ ] git status - checked what I’m adding
  • [ ] git diff - reviewed the changes
  • [ ] Tests pass
  • [ ] .env and secrets are not in the commit
  • [ ] Commit message is meaningful
  • [ ] git pull before git push
  • [ ] Working in the correct branch

Follow these rules and you’ll avoid 90% of Git problems! 🎯

Your reaction to the article

💬 Comments (0)

🔐 Sign in to leave a comment
🚪 Login
💭

No comments yet

Be the first to share your opinion about this article!

🔗 Similar

Similar articles

Continue learning with these materials

📝

Git Hosting Platforms: Full Comparison 🏆

GitHub, GitLab, Bitbucket — which one to choose? A complete comparison with up-to-date data.

📅 06.05.2026 👁️ 52
📝

What Is a Git Commit and Why Do You Need It? 📸

A commit is a saved snapshot of your project at a specific point in time...

📅 06.05.2026 👁️ 55
📝

Why Git won over every other version control syst…

Today Git is the de facto standard for version control in software development. But it...

📅 06.05.2026 👁️ 50

Did you like the article?

Subscribe to our updates and receive new articles first. Grow with PyLand!