This answer was mostly derived from Git Pathspecs and How to Use Them. I haven’t copied everything over, so look into the link to dig deeper
The
pathspecis the mechanism that git uses for limiting the scope of a git command to a subset of the repository. If you have used much git, you have likely used apathspecwhether you know it or not. For example, in the commandgit add README.md, thepathspecisREADME.md. However, it is capable of much more nuance and flexibility.So, why should you learn about
pathspecs? Since it is a part of many commands, these commands become much more powerful with an understanding ofpathspecs. Withgit add, you can add just the files within a single directory. Withgit diff, you can examine just the changes made to filenames with an extension of.scss. You can git grep all files except for those in the/distdirectory.
File or directory
git add . # add CWD (current working directory)
git add .. # add parent directory and its subdirectories
git add src/ # add src/ directory
git add README # add only README directory
Also note that the git add command takes [<pathspec>...]. The ... means possibility of multiple occurence. So you can do:
git add /content /images
and that would all changes under both directories.
if you ever do ls -a, it will list all files and ‘directory entries’, it will include . and .. for more see here
Wildcards
đź’ˇNote the single quotes
git log '*.js' # logs all .js files in CWD and subdirectories git log '.*' # logs all 'hidden' files and directories in CWD git log '*/.*' # logs all 'hidden' files and directories in subdirectories
An example using git add:
git add '*/*.swift' # stages all 'swift' files
top
The
topsignature tells git to match the pattern from the root of the git repository rather than the current working directory. You can also use the shorthand:/rather than:(top).git ls-files ':(top)*.js' git ls-files ':/*.js' # shorthand
icase
The
icasesignature tells git to not care about case when matching .. [e.g.] this could be useful for matchingjpgfiles, which sometimes use the uppercase extensionJPG.git ls-files ':(icase)*.jpg'
exclude
Lastly, there is the “exclude’” magic signature (shorthand of
:!or:^)… [e.g.] you can search through all of your.jsfiles while excluding the.spec.jstest files.git grep 'foo' -- '*.js' ':(exclude)*.spec.js' # search .js files excluding .spec.js git grep 'foo' -- '*.js' ':!*.spec.js' . # shorthand for the same
Other good use cases of pathspec
See the change made for a single file in a specific commit:
git show 78b0383148bdfeca4a85aa445949cfe1a131c4a6 config.yml
Search the commit messages for a certain string for a specific file. For more on that see here
git log -S "plus sign" -- Documentation/git-branch.txt
Restore files at certain path(s) to its previous commit. See here and here
git checkout c5f567 -- file1/to/restore file2/to/restore # identify the commit with the SHA1
git checkout origin/main -- src/main/java/HelloWorld.java # identify the commit with a branch