Skip to content

Instantly share code, notes, and snippets.

@Cryptophobia
Last active February 21, 2017 23:13
Show Gist options
  • Save Cryptophobia/75a3b184c06bcc6de82c7b9f955b743b to your computer and use it in GitHub Desktop.
Save Cryptophobia/75a3b184c06bcc6de82c7b9f955b743b to your computer and use it in GitHub Desktop.
git info command
#!/bin/sh
#
# git-info - shows information about a Git repository a la `svn info'
#
# How to use:
# $ git info
# $ git info ~/src/somewhere/somefile
# $ git info some/relative/file_or_directory
# $ git info ~/repos/something.git
#
# Copyright (c) 2009, 2012, 2013 Akinori MUSHA
#
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
PAGINATE=t
COLOR=
main () {
local path file first=t opt OPTIND=1 ret
while getopts 'p-:' opt; do
case "$opt" in
p)
PAGINATE=t
;;
-)
case "$OPTARG" in
paginate)
PAGINATE=t
;;
no-pager)
PAGINATE=
;;
color)
COLOR=always
;;
color\=*)
COLOR="${OPTARG#color=}"
;;
*)
die "Illegal option --$OPTARG"
;;
esac
;;
*)
echo "Usage: $0 [-p|--paginate|--no-pager|--color[=<when>]] [path]" >&2
die
;;
esac
done
shift $(($OPTIND - 1))
initialize_colors
case "$#" in
1)
;;
0)
if [ -n "$GIT_DIR" ]; then
set -- "$GIT_DIR"
else
set -- .
fi
;;
*)
die "Too many arguments"
;;
esac
git_info "$1"
}
initialize_colors () {
if [ -z "$COLOR" ]; then
if git config --get-colorbool color.info; then
COLOR=always
else
COLOR=never
fi
fi
case "$COLOR" in
always|never)
COLOR_BRANCH=$COLOR
;;
auto)
if git config --get-colorbool color.branch; then
COLOR_BRANCH=always
else
COLOR_BRANCH=never
fi
;;
*)
die "option \`color' expects \"always\", \"auto\", or \"never\""
;;
esac
if [ "$COLOR" = always ]; then
REMOTE_COLOR="$(get_color color.info.remote color.branch.remote red)"
LOCAL_COLOR="$(get_color color.info.local color.branch.local green)"
PATH_COLOR="$(get_color color.info.path '' 'bold')"
REPOSITORY_COLOR="$(get_color color.info.repository '' 'bold')"
ID_COLOR="$(get_color color.info.id '' 'yellow')"
RESET_COLOR="$(git config --get-color '' '')"
else
REMOTE_COLOR=
LOCAL_COLOR=
PATH_COLOR=
REPOSITORY_COLOR=
ID_COLOR=
RESET_COLOR=
fi
}
get_color () {
local key1="$1" key2="$2" fb="$3"
local color="$(git config --get-color "$key1" '')"
case "$color" in
''|'')
git config --get-color "$key2" "$fb"
;;
*)
printf '%s' "$color"
;;
esac
}
git_info () {
local path="$1" dir relpath root git_dir
if [ -d "$path" ]; then
dir="$(cd -P "$path" && pwd)" || die "$path: Cannot cd to the directory"
case "$path" in
*.git)
git_dir="$dir"
;;
esac
elif [ -f "$path" ]; then
dir="$(dirname "$path")"
dir="$(cd -P "$dir" && pwd)" || die "$dir: Cannot cd to the directory"
relpath="$(basename "$path")"
else
die "$path: No such file or directory"
fi
if [ -n "$git_dir" ]; then
dir=
relpath=
elif case "$dir" in ?*.git) [ -d "$dir/objects" -a -d "$dir/refs" ] ;; *) false ;; esac; then
git_dir="$dir"
relpath=
else
root="$(
cd "$dir" || exit 1
while [ ! -d .git ]; do
[ "$(pwd)" = / ] && exit 1
cd ..
done
pwd
)" || die "Not a git repository."
git_dir="$root/.git"
if [ "$dir" = "$root" ]; then
relpath=.
elif [ -n "$relpath" ]; then
relpath="${dir#"$root/"}/$relpath"
else
relpath="${dir#"$root/"}"
fi
fi
set -- "$git_dir"
if [ -n "$relpath" ]; then
set -- "$@" "$relpath"
fi
if [ -n "$PAGINATE" ]; then
do_git_info "$@" | git-pager
else
do_git_info "$@"
fi
}
do_git_info () {
local git_dir="$1" relpath="$2" root line field color reset
shift
echo "Repository Path: $PATH_COLOR$git_dir$RESET_COLOR"
if [ $# -gt 0 ]; then
root="$(dirname "$git_dir")"
if [ "$relpath" = . ]; then
echo "Path: $PATH_COLOR$root$RESET_COLOR"
else
echo "Path: $PATH_COLOR$root/$relpath$RESET_COLOR"
fi
fi
maketemp
GIT_DIR="$git_dir" git remote -v > "$TEMPFILE"
if [ -s "$TEMPFILE" ]; then
echo "Remote Repositories:"
sed -e "s/^\([^ ]\{1,\}\)\([ ]\{1,\}\)\([^ ]\{1,\}\)/$REMOTE_COLOR\1$RESET_COLOR\2$REPOSITORY_COLOR\3$RESET_COLOR/" \
-e 's/^/ /' \
"$TEMPFILE"
fi
GIT_DIR="$git_dir" git branch -r --color=$COLOR_BRANCH > "$TEMPFILE"
if [ -s "$TEMPFILE" ]; then
echo "Remote Branches:"
sed -e "s/\([ ]\{1,\}->[ ]\{1,\}\)\([^ ]\{1,\}\)/\1$REMOTE_COLOR\2$RESET_COLOR/" \
-e 's/^ */ /' "$TEMPFILE"
fi
GIT_DIR="$git_dir" git branch --color=$COLOR_BRANCH > "$TEMPFILE"
if [ -s "$TEMPFILE" ]; then
echo "Local Branches:"
sed 's/^/ /' "$TEMPFILE"
fi
echo "Repository Configuration:"
sed -e "s/^\(\[remote \"\)\([^\"]\{1,\}\)\(\"\]\)$/\1$REMOTE_COLOR\2$RESET_COLOR\3/" \
-e "s/^\([ ]*remote[ ]*=[ ]*\"\{0,1\}\)\([^\" ]\{1,\}\)\(\"\{0,1\}[ ]*\)$/\1$REMOTE_COLOR\2$RESET_COLOR\3/" \
-e "s/^\(\[branch \"\)\([^\"]\{1,\}\)\(\"\]\)$/\1$LOCAL_COLOR\2$RESET_COLOR\3/" \
-e "s/^\([ ]*url[ ]*=[ ]*\"\{0,1\}\)\([^\" ]\{1,\}\)\(\"\{0,1\}[ ]*\)$/\1$REPOSITORY_COLOR\2$RESET_COLOR\3/" \
-e 's/^/ /' \
"$git_dir"/config
(cd "$root" && GIT_DIR="$git_dir" git log --max-count=1 "$@") | {
while read -r field line; do
color=
reset=
case "$field" in
commit)
field='Commit ID:'
color="$ID_COLOR"
reset="$RESET_COLOR"
;;
*:)
;;
'')
break
;;
esac
echo "Last Changed $field $color$line$reset"
done
cat > "$TEMPFILE"
}
echo "Last Changed Log:"
sed 's/^ / /' "$TEMPFILE"
finalize
}
die () {
[ "$#" -gt 0 ] && echo "$0: $@" >&2
finalize
exit 1
}
TEMPFILE=
maketemp () {
if [ -z "$TEMPFILE" ]; then
TEMPFILE="$(mktemp /tmp/git-info.XXXXXX)" || die
trap "finalize; exit 130" 1 2 3 15
fi
}
finalize () {
if [ -n "$TEMPFILE" ]; then
rm -f "$TEMPFILE"
fi
}
main "$@"
@Cryptophobia
Copy link
Author

Cryptophobia commented Feb 21, 2017

alias gi='. /Users/$USER/git-info.sh'

Above is for MacOS, below is a nice alternative for Linux:

Make an alias for the git-info script

alias "gi"='. /home/$USER/git-info.sh'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment