You are not logged in.
Pages: 1
Is there a way to make an alias in a shell that works only within a certain directory?
I'm using zsh and I want to alias git commands ('add' to 'git add', 'commit' to 'git commit', etc.), but only when in a git directory. Is this possible? Has anyone done it before?
p.s.: I do realise commands like rm will be messed up, but I'm fine typing \rm when I need an actual rm inside a git directory. That's actually the precise reason I want the alias to only work inside git directories.
Thanks for your time.
Last edited by lilac-dust (2017-06-06 05:06:49)
Offline
It sounds like an odd goal to me, but you could use a conditional in a function (but not an alias):
function rm() { [[ -d .git ]] && git rm $@ || /usr/bin/rm $@; }You could also use a PROMPT_COMMAND or similar, to check the current working directory and set/unset aliases.
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
You might be interested in Smart CD
You would have to set it up for each git directory but it allows you to run commands on entering / leaving a directory.
It also has a very helpful command for aliases. It will set up the alias when you enter and remove it when you leave.
Offline
It sounds like an odd goal to me, but you could use a conditional in a function (but not an alias):
function rm() { [[ -d .git ]] && git rm $@ || /usr/bin/rm $@; }You could also use a PROMPT_COMMAND or similar, to check the current working directory and set/unset aliases.
Using && || will execute "/usr/bin/rm $@" if the "git rm $@" command returns an error exit status. It's better to be more wordy and use the normal "if-then-else" structure so that nothing unexpected can happen:
rm() {
if [[ -d .git ]]; then
git rm "$@"
else
/usr/bin/rm "$@"
fi
}Here's what I mean about && and || instead of if-then-else:
First, this here works like expected:
$ true && echo then || echo else
then
$ false && echo then || echo else
elseBut here's how it behaves if the "then" part returns an error, where it executes the "else" part as well:
$ true && { echo then; false; } || echo else
then
elseOffline
Ropid, that was intentional. Really, I was thinking about getting rid of the initial conditional and redirecting error output of the git command.b If the git command fails, one would want the "normal" command. The logic is "use git rm if possible, otherwise use regular rm".
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
edit 2
Here's the improved solution using the suggestion from below. It's so obvious now that I feel stupid, but in my defense I was focused on the "[[ -d .git ]]" idea above ![]()
Bikeshedding is fun ![]()
function rm()
{
if [[ $(git rev-parse --is-inside-work-tree 2>/dev/null) = true ]]
then
echo git rm "$@"
else
echo /usr/bin/rm "$@"
fi
}/edit 2
The .git directory may be in a parent directory. This will check further up the directory path hierarchy.
#!/bin/bash
function is_git()
{
local dpath_="$PWD/"
[[ $dpath_ == // ]] && dpath_=/
while [[ $dpath_ != // ]]
do
if [[ -d $dpath_.git ]]
then
return 0
fi
dpath_="${dpath_%/*/}/"
done
return 1
}
if is_git
then
git rm "$@"
else
/usr/bin/rm "$@"
fiedit 1
As a single "rm" function:
function rm()
{
local dpath_="$PWD/"
local is_git_=false
[[ $dpath_ == // ]] && dpath_=/
while [[ $dpath_ != // ]]
do
if [[ -d $dpath_.git ]]
then
is_git_=true
break
fi
dpath_="${dpath_%/*/}/"
done
if $is_git_
then
echo git rm "$@"
else
echo /usr/bin/rm "$@"
fi
}Last edited by Xyne (2017-06-05 10:57:05)
My Arch Linux Stuff • Forum Etiquette • Community Ethos - Arch is not for everyone
Offline
or just
function is_git() { git branch >/dev/null 2>&1; }"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
I'd suggest using
[[ $(git rev-parse --is-inside-work-tree 2>/dev/null) = true ]]actually, since unlike branch, rev-parse is a low-level command meant to be useful -- and used -- for scripting. Specifically, this lets you tell the difference between being in a bare git repo, or the .git directory of a git repo, and actually being in what you meant to ask about.
rev-parse lets you learn all kinds of useful things; it is also what the official bash-completion script for git uses for things like this, see the __git_find_repo_path function.
Managing AUR repos The Right Way -- aurpublish (now a standalone tool)
Offline
Thanks everyone
I'll try Xyne's edited solution for now and report back in case anything goes wrong, but for now this seems solved.
Also Smart CD sounds really interesting, but it might take a while before I look into it.
Once again, thank you for the ideas!
Offline
Pages: 1