I am using zsh
and in my config I am adding another alias :
alias recursively_git_pull_all_repo="for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done"
However this alias seems to get executed every time I open a new terminal (or at least it slows down starting up a new terminal considerably).
How can I add this alias without it being launched every time I open a new terminal ?
To set up a simple alias, edit the ~/. zshrc file using your text editor and add an alias at the bottom. It is good to keep all your aliases in a single section of the file to avoid confusion and ease of edit. alias ginit="git init ."
Otherwise, try cat ~/.zshrc | grep alias to see all aliases set in your .zshrc to make sure there are no other aliases being set. Thanks for contributing an answer to Unix & Linux Stack Exchange!
ZSH aliases are configured in the .zshrc file located in the user’s home directory. They are loaded on shell startup, but you can force-reload them by sourcing the .zshrc file.
ZSH has four main types of aliases. Simple aliases are a short form of a long command. To set up a simple alias, edit the ~/.zshrc file using your text editor and add an alias at the bottom. It is good to keep all your aliases in a single section of the file to avoid confusion and ease of edit.
The next file is.zshrc that contains the shell configurations and commands. It is sourced in interactive shells and contains aliases, key bindings, variables, and functions. The final file is.zlogout, which gets read when the shell session closes. You can use it to set up commands executed when the shell exits.
TL;DR (or should it be TL;WR - "too long, won't read"?)
alias recursively_git_pull_all_repo='for dir in **/.git(/:h); git -C $dir pull'
You are at least partially correct in that a part of this command is run when the alias is declared. This has two effects:
You are declaring the alias in double quotes, which allows for parameter expansion. That means that the parts $(find . -name ".git")
and ${dir%/*}
will be expanded and substituted at the time the alias is declared taking the values they produce at the time.
For $(find . -name ".git")
this means that .
is most likely $HOME
and the construct is replaced by a newline separated list of all .git
directories (and other file-like objects) in your home directory.
${dir%/*}
will probably be substituted with an empty string as dir
is most likely not set. Remember: the alias itself is not executed at that time, so dir
will not be set by the for
loop.
This means that:
alias recursively_git_pull_all_repo="for dir in $(find . -name ".git"); do cd ${dir%/*}; git pull ; cd -; done"
will effectively be saved as something like
alias recursively_git_pull_all_repo="for dir in docs/repo1/.git
docs/repo2/.git
otherdocs/repo/.git
whatever/.git; do
cd ; git pull ; cd -; done"
This will - fortunately - fail with an zsh: command not found: docs/repo2/.git
error because of the newline after the first repository. If it did not, it would change into your home directory repeatedly (cd
without parameter) and try to do git pull
.
The quick solution would be to just use single quotes, when declaring the alias, that way the command and parameter will substituted when the alias is run, not when it is declared.
But there are still some other problems with that:
git pull
will be run from the current directory instead. This can actually happen if the execute flag is not set on a directory in the path.find
will also list non-directories named .git
Instead I would suggest to use what zsh
has to offer:
alias recursively_git_pull_all_repo='for dir in **/.git(/:h); git -C $dir pull'
find
to get a list of the directories. The **
glob will be recursively expanded to all directories. So **/.git
will be expanded to all paths with .git
as last element.**/.git(/)
the qualifier /
means: "only directories".:
followed by the modifier - in this case h
, which removes the last path component (like the program dirname
, or ${dir%/*}
from your example).git
; you can tell git
where to work with git -C <path>
for
, meaning no do ...; done
.Fun fact: If you use d
instead of dir
, another short form of for
and the option GLOB_STAR_SHORT
is enabled (requires zsh >= 5.2), you can use:
for d (**.git(/:h))git -C $d pull
which is only 4 characters longer than your alias name. Yes, I know about completion. But there is also history searching 😉.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With