Julien Danjou

Sep 4, 2025

4 min

read

Stop Abusing .gitignore

landmark photography of trees near rocky mountain under blue skies daytime
landmark photography of trees near rocky mountain under blue skies daytime

.gitignore is one of Git’s most abused features. Here’s what it’s actually for, why you shouldn’t commit your editor junk into it, and how to use a global ignore file instead.

There isn't a single month where I don't have to explain this. So let's do it once and for all: .gitignore is a great feature, but people keep using it wrong.

🤓 What's the Purpose of .gitignore?

The .gitignore file tells Git which files it should not track. It usually lives at the root of your repository, and it can list specific file paths or use wildcards.

Example:


In this case:

  • Any file named foo will be ignored.

  • Everything under the bar/ directory will be ignored.

That way, you don't accidentally git add files that don't belong in your repo.

Pretty neat.

😅 Where People Go Wrong

Here's what happens: your working directory gets messy. Build artifacts, editor backups, OS junk files…

So you add them to .gitignore:


Problem solved? Not really.

The repo is a shared space. Your editor isn't my editor. My OS isn't your OS. Nobody wants PRs that just add "ignore VSCode stuff" or "ignore my Vim backups.”

It clutters history, helps nobody, and frustrates maintainers.

🙄 So How Do I Ignore My Local Junk?

Git has you covered: a global ignore file.

By default: ~/.config/git/ignore

Here's mine:


This keeps Vim swaps, Emacs configs, and macOS clutter out of every repo I work on.

You can configure the file location with:

Now your junk stays out of everyone else's history.

✅ What Belongs in .gitignore?

The only things that should live in .gitignore are project-generated files:

  • Build artifacts

  • Compiled files

  • Cache directories

For example, in Python projects:

*.pyc
__pycache__

That way, the ignore file reflects the project’s needs, not every contributor’s local setup.

💡 Takeaway

  • .gitignore is for project artifacts.

  • Use a global ignore for your editor/OS noise.

  • Stop sending PRs that add your pet editor's folders — nobody cares. 😉

Follow these rules, and your repositories will stay cleaner, your teammates happier, and your commit history will be free of irrelevant junk.

Stay ahead in CI/CD

Blog posts, release news, and automation tips straight in your inbox

Stay ahead in CI/CD

Blog posts, release news, and automation tips straight in your inbox

Recommended blogposts

Dec 2, 2025

9 min

read

Lessons From a Noisy Monitor

Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

Dec 2, 2025

9 min

read

Lessons From a Noisy Monitor

Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

Dec 2, 2025

9 min

read

Lessons From a Noisy Monitor

Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

Dec 2, 2025

9 min

read

Lessons From a Noisy Monitor

Your database monitors keep firing even though nothing is wrong? We hit the same problem: noisy IOPS alerts caused by predictable jobs. This post explains how we replaced brittle thresholds with an SLO-based approach that restored signal, eliminated noise, and stopped the monitor from "crying wolf."

Julian Maurin

Nov 27, 2025

5 min

read

Monorepo CI for GitHub Actions: Run Exactly the Tests You Need, Nothing More

Run only the tests that matter in your monorepo. Mergify Monorepo CI detects which parts of your repo each pull request touches and triggers the right GitHub Actions jobs, then aggregates them into a single CI gate for branch protection or Merge Queue.

Julien Danjou

Nov 27, 2025

5 min

read

Monorepo CI for GitHub Actions: Run Exactly the Tests You Need, Nothing More

Run only the tests that matter in your monorepo. Mergify Monorepo CI detects which parts of your repo each pull request touches and triggers the right GitHub Actions jobs, then aggregates them into a single CI gate for branch protection or Merge Queue.

Julien Danjou

Nov 27, 2025

5 min

read

Monorepo CI for GitHub Actions: Run Exactly the Tests You Need, Nothing More

Run only the tests that matter in your monorepo. Mergify Monorepo CI detects which parts of your repo each pull request touches and triggers the right GitHub Actions jobs, then aggregates them into a single CI gate for branch protection or Merge Queue.

Julien Danjou

Nov 27, 2025

5 min

read

Monorepo CI for GitHub Actions: Run Exactly the Tests You Need, Nothing More

Run only the tests that matter in your monorepo. Mergify Monorepo CI detects which parts of your repo each pull request touches and triggers the right GitHub Actions jobs, then aggregates them into a single CI gate for branch protection or Merge Queue.

Julien Danjou

Nov 25, 2025

7 min

read

await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks

Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

Nov 25, 2025

7 min

read

await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks

Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

Nov 25, 2025

7 min

read

await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks

Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

Nov 25, 2025

7 min

read

await Is Not a Context Switch: Understanding Python's Coroutines vs Tasks

Python’s async model is misunderstood, especially by engineers coming from JS or C#. In Python, awaiting a coroutine doesn’t yield to the event loop. Only tasks create concurrency. This post explains why that distinction matters and how it affects locking, design, and correctness.

Mehdi Abaakouk

Curious where your CI is slowing you down?

Try CI Insights — observability for CI teams.

Curious where your CI is slowing you down?

Try CI Insights — observability for CI teams.

Curious where your CI is slowing you down?

Try CI Insights — observability for CI teams.

Curious where your CI is slowing you down?

Try CI Insights — observability for CI teams.