The Curious Case of Double Dashes
Bare -- in bash commands
Why do we sometimes use bare double dashes in commands like git checkout -- file.txt
? Isn’t git checkout file.txt
just as good?
Bare double dashes signify the end of options. Anything after --
is a parameter. For example in git, you can checkout a file named master
:
git checkout master # Checkout the master branch
git checkout -- master # Checkout the file named master
In proper documentation, we see git checkout -- file.txt
when git checkout file.txt
would work, too. --
safeguards against checking out branches when files have the same name as branches.
POSIX.1–2017 standard
12.2 Utility Syntax Guidelines
Guideline 10:
The first
--
argument that is not an option-argument should be accepted as a delimiter indicating the end of options. Any following arguments should be treated as operands, even if they begin with the ‘-’ character.
Use case: rm
When you need to delete an oddly named filed like -file.txt
, rm
treats -f
as an option. Use bare double dashes to delete the file. This works for many bash commands that work with files like cat
, mv
, or touch
.
rm -file.txt # rm: illegal option -- l
rm -- -file.txt
Use case: grep
You can use double dashes in grep
when the search term starts with a dash:
grep -- -v *
This searches for the string ‘-v’ rather than interpreting it as the option for inverse matches.
Use case: npm scripts
Double dashes are incredibly useful for npm
scripts. Anything after the double dashes is not an option of npm
, but a parameter for the script that npm
executes.
If we want to fix linter errors, we do not need to look up which linter is specified in package.json
. As long as the linter understands --fix
, we simply run
npm run lint -- --fix
What can you do with --
?
I hope this shed some light on why we sometimes have bare double dashes in our commands. Where do you use --
? I would love to hear your tips in the comment section.