Skip to content

Instantly share code, notes, and snippets.

@xkr47
Last active September 25, 2020 06:32
Show Gist options
  • Save xkr47/92d35df76891efdcb142e75ee496c48c to your computer and use it in GitHub Desktop.
Save xkr47/92d35df76891efdcb142e75ee496c48c to your computer and use it in GitHub Desktop.
"git alias" command for adding/removing/editing git aliases conveniently
#!/bin/bash
set -eo pipefail
usage () {
cat <<'EOF'
usage:
git alias [<options>]
git alias [<options>] name
git alias [<options>] name newvalue
git alias [<options>] -e|--edit name
git alias [<options>] -d|--unset name
options:
--system|--global|--local|--file <filename>
When getting, the values are read from the system, global and repository local configuration files by default, and options --system, --global, --local and --file <filename> can be used to tell the command to read from only that location (see the section called “FILES” in "git config --help").
When setting, the new value is written to the repository local configuration file by default, and options --system, --global, --file <filename> can be used to tell the command to write to that location (you can say --local but that is the default).
When editing, the alias is read in the same way as "when getting" above, and the edited version is written back to the *same* repository as it was read from.
When deleting, the alias is located in the same way as "when getting" above, and only the first match is deleted. Thus if you have overridden an alias "foo" in your local config, and you run "git alias -d foo" it will only remove the one from the local config and not from system nor global.
EOF
exit 1
}
detect-origin () {
case "$1" in
file:.git/config)
echo --local
;;
file:$HOME/.gitconfig)
echo --global
;;
file:/etc/gitconfig)
echo --system
;;
*)
echo "Unparseable origin '$1'" >&2
exit 3
;;
esac
}
while [ $# -gt 0 ]; do
case "$1" in
-h)
usage
;;
--system|--global|--local)
origin="$1"
shift
;;
-e|--edit)
shift
OP=edit
[ $# = 1 ] || usage
alias="$1"
;;
-d|--unset)
shift
OP=del
[ $# = 1 ] || usage
alias="$1"
;;
-*)
echo "Unsupported parameter: $1" >&2
usage
;;
*)
break
;;
esac
done
if [ ! "$OP" ]; then
case $# in
0)
OP=list
;;
1)
OP=get
alias="$1"
;;
2)
OP=set
alias="$1"
value="$2"
;;
*)
usage
;;
esac
fi
name="alias.$alias"
case "$OP" in
list)
git config $origin --list | perl -ne 'print if s/^alias\.//;'
;;
get)
git config $origin --get "$name"
;;
set)
git config $origin "$name" "$value"
;;
edit)
file="$(mktemp "/tmp/git-alias-$alias-XXXXXXXX.sh")"
git config $origin --show-origin --null --get "$name" | perl -e '<>=~m!(.*)\0(.*)\0! or die "lol"; print STDERR $1; print $2' > "$file" 2> "${file}.origin" || err=${PIPESTATUS[0]}
case $err in
1)
echo No ${origin#--} alias "'$alias'" >&2
exit 1
;;
"")
:
;;
*)
echo "Error $err"
exit $err
;;
esac
origin="$(detect-origin "$(cat "${file}.origin")")"
echo "Editing alias '$name' in ${origin#--}.."
"$(git var GIT_EDITOR)" "$file"
git config $origin "$name" "$(cat "$file")"
echo "Updated alias '$name' in ${origin#--}"
rm "$file" "${file}.origin"
;;
del)
file="$(mktemp "/tmp/git-alias-$alias-XXXXXXXX.sh")"
git config $origin --show-origin --null --get "$name" | perl -e '<>=~m!(.*)\0(.*)\0! or die "lol"; print STDERR $1; print $2' > "$file" 2> "${file}.origin" || err=${PIPESTATUS[0]}
case $err in
1)
echo No ${origin#--} alias "'$alias'" >&2
exit 1
;;
"")
:
;;
*)
echo "Error $err"
exit $err
;;
esac
origin="$(detect-origin "$(cat "${file}.origin")")"
rm "$file" "${file}.origin"
git config $origin --unset "$name"
echo "Deleted alias '$name' from ${origin#--}"
;;
*)
echo "Internal error '$OP'" "$@" >&2
exit 2
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment