I recently ran into an issue while working with Git. I had a bunch of Markdown files spread across multiple nested folders and wanted to stage them all at once. So I ran:
git add *.mdBut only the .md files in the current directory got added (to the staging area). The .md files in the nested directories didn’t get added.
The root casue: the * wildcard isn’t processed by Git, but by the shell. So the shell was only matching them in the current folder. What a revelation!
After a few minutes of worrying and searching, I figured out two different ways of solving this. Solution 1 uses Git to do the work while solution 2 uses bash.
Solution 1 (Git way)
The solution is to use:
git add '**/*.md'Let’s break down how git add '**/*.md' works:
git add- tells Git to stage files'**/*.md'- First, the quotes are important. They prevent your shell (like Bash or Zsh) from expanding the*s. Without the quotes, your shell would handle the wildcard expansion. Most shells don’t match files recursively by default. So, Git receives the literal string**/*.md.**/— the double asterisk means “search recursively through all directories.” It matches zero or more directory levels. 1So
**/*.mdmatches:notes.md(in the current directory)docs/guide.md(one folder deep)posts/tutorials/intro.md(multiple levels deep)
From official Git documentation: A leading “” followed by a slash means match in all directories. For example, “/foo” matches file or directory “foo” anywhere.
In short:
git add '**/*.md' tells Git itself (not the shell) to recursively find and stage all Markdown files under the current directory & nested ones.
Solution 2 (bash way)
If you’re using Bash with globstar enabled, you can do:
shopt -s globstar
git add **/*.mdBoth commands will add all .md files, even those nested in deep subfolders.
It was a small issue, but it served as a reminder for me of how easy it is to overlook the basics of how tools interact.
Lesson learned: always double-check how shell and Git are interpreting your command.
