├── LICENSE.txt ├── README.md └── git-info /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009, 2022 Akinori MUSHA 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions 7 | are met: 8 | 1. Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 | ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 | OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 | HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 | OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 | SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | git-info 2 | ======== 3 | 4 | Synopsis 5 | -------- 6 | 7 | * git-info - shows information about a Git repository a la `svn info' 8 | 9 | How to set up 10 | ------------- 11 | 12 | Just place these scripts in one of the directories in your `PATH`, and 13 | you are done. 14 | 15 | How to use 16 | ---------- 17 | 18 | git info 19 | git info ~/src/somewhere/somefile 20 | git info some/relative/file_or_directory 21 | git info ~/repos/something.git 22 | 23 | Sample output 24 | ------------- 25 | 26 | % git info 27 | Repository Path: /home/knu/src/github/git-info/.git 28 | Path: /home/knu/src/github/git-info 29 | Remote Repositories: 30 | origin git@github.com:knu/git-info.git (fetch) 31 | origin git@github.com:knu/git-info.git (push) 32 | Remote Branches: 33 | origin/HEAD -> origin/master 34 | origin/master 35 | Local Branches: 36 | * master 37 | Repository Configuration: 38 | [core] 39 | repositoryformatversion = 0 40 | filemode = true 41 | bare = false 42 | logallrefupdates = true 43 | [remote "origin"] 44 | fetch = +refs/heads/*:refs/remotes/origin/* 45 | url = git@github.com:knu/git-info.git 46 | [branch "master"] 47 | remote = origin 48 | merge = refs/heads/master 49 | Last Changed Commit ID: da32fa59f7fab84606ce3c144e636043e96d8063 50 | Last Changed Author: Akinori MUSHA 51 | Last Changed Date: Tue Jul 28 10:37:09 2009 +0900 52 | Last Changed Log: 53 | Take the directory as a physical path. 54 | 55 | Author 56 | ------ 57 | 58 | Copyright (c) 2009-2022 Akinori MUSHA. 59 | 60 | Licensed under the 2-clause BSD license. See `LICENSE.txt` for 61 | further details. 62 | -------------------------------------------------------------------------------- /git-info: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | # git-info - shows information about a Git repository a la `svn info' 4 | # 5 | # How to use: 6 | # $ git info 7 | # $ git info ~/src/somewhere/somefile 8 | # $ git info some/relative/file_or_directory 9 | # $ git info ~/repos/something.git 10 | # 11 | # Copyright (c) 2009-2022 Akinori MUSHA 12 | # 13 | # All rights reserved. 14 | # 15 | # Redistribution and use in source and binary forms, with or without 16 | # modification, are permitted provided that the following conditions 17 | # are met: 18 | # 1. Redistributions of source code must retain the above copyright 19 | # notice, this list of conditions and the following disclaimer. 20 | # 2. Redistributions in binary form must reproduce the above copyright 21 | # notice, this list of conditions and the following disclaimer in the 22 | # documentation and/or other materials provided with the distribution. 23 | # 24 | # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 25 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 26 | # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 27 | # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 28 | # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 | # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 | # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 | # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 | # SUCH DAMAGE. 35 | # 36 | 37 | COLOR= 38 | 39 | main () { 40 | local opt 41 | local OPTS_SPEC="\ 42 | $0 [] [] 43 | 44 | $0 shows information about a Git repository. 45 | -- 46 | h,help show the help 47 | color?when show colored output (always|never|auto) 48 | " 49 | eval "$(echo "$OPTS_SPEC" | git rev-parse --parseopt --stuck-long -- "$@" || echo exit $?)" 50 | 51 | while [ $# -gt 0 ]; do 52 | opt="$1" 53 | shift 54 | 55 | case "$opt" in 56 | --color) 57 | COLOR=always 58 | ;; 59 | --color\=*) 60 | COLOR="${opt#*=}" 61 | ;; 62 | --) 63 | break 64 | ;; 65 | *) 66 | die "Unexpected option: $opt" 67 | ;; 68 | esac 69 | done 70 | 71 | initialize_colors 72 | 73 | case "$#" in 74 | 1) 75 | ;; 76 | 0) 77 | if [ -n "$GIT_DIR" ]; then 78 | set -- "$GIT_DIR" 79 | else 80 | set -- . 81 | fi 82 | ;; 83 | *) 84 | die "Too many arguments" 85 | ;; 86 | esac 87 | 88 | git_info "$1" 89 | } 90 | 91 | initialize_colors () { 92 | if [ -z "$COLOR" ]; then 93 | if git config --get-colorbool color.info; then 94 | COLOR=always 95 | else 96 | COLOR=never 97 | fi 98 | fi 99 | 100 | case "$COLOR" in 101 | always|never) 102 | COLOR_BRANCH=$COLOR 103 | ;; 104 | auto) 105 | if git config --get-colorbool color.branch; then 106 | COLOR_BRANCH=always 107 | else 108 | COLOR_BRANCH=never 109 | fi 110 | ;; 111 | *) 112 | die "option \`color' expects \"always\", \"auto\", or \"never\"" 113 | ;; 114 | esac 115 | 116 | if [ "$COLOR" = always ]; then 117 | REMOTE_COLOR="$(get_color color.info.remote color.branch.remote red)" 118 | LOCAL_COLOR="$(get_color color.info.local color.branch.local green)" 119 | PATH_COLOR="$(get_color color.info.path '' 'bold')" 120 | REPOSITORY_COLOR="$(get_color color.info.repository '' 'bold')" 121 | ID_COLOR="$(get_color color.info.id '' 'yellow')" 122 | RESET_COLOR=$(printf "\033[m") 123 | else 124 | REMOTE_COLOR= 125 | LOCAL_COLOR= 126 | PATH_COLOR= 127 | REPOSITORY_COLOR= 128 | ID_COLOR= 129 | RESET_COLOR= 130 | fi 131 | } 132 | 133 | get_color () { 134 | local key1="$1" key2="$2" fb="$3" 135 | local color="$(git config --get-color "$key1" '')" 136 | case "$color" in 137 | ''|'') 138 | git config --get-color "$key2" "$fb" 139 | ;; 140 | *) 141 | printf '%s' "$color" 142 | ;; 143 | esac 144 | } 145 | 146 | git_info () { 147 | local path="$1" dir relpath root git_dir 148 | 149 | if [ -d "$path" ]; then 150 | dir="$(cd -P "$path" && pwd)" || die "$path: Cannot cd to the directory" 151 | case "$path" in 152 | *.git) 153 | git_dir="$dir" 154 | ;; 155 | esac 156 | elif [ -f "$path" ]; then 157 | dir="$(dirname "$path")" 158 | dir="$(cd -P "$dir" && pwd)" || die "$dir: Cannot cd to the directory" 159 | relpath="$(basename "$path")" 160 | else 161 | die "$path: No such file or directory" 162 | fi 163 | 164 | if [ -n "$git_dir" ]; then 165 | dir= 166 | relpath= 167 | elif case "$dir" in ?*.git) [ -d "$dir/objects" -a -d "$dir/refs" ] ;; *) false ;; esac; then 168 | git_dir="$dir" 169 | relpath= 170 | else 171 | root="$( 172 | cd "$dir" || exit 1 173 | while [ ! -e .git ]; do 174 | [ "$(pwd)" = / ] && exit 1 175 | cd .. 176 | done 177 | pwd 178 | )" || die "Not a git repository." 179 | git_dir="$root/.git" 180 | if [ "$dir" = "$root" ]; then 181 | relpath=. 182 | elif [ -n "$relpath" ]; then 183 | relpath="${dir#"$root/"}/$relpath" 184 | else 185 | relpath="${dir#"$root/"}" 186 | fi 187 | fi 188 | 189 | set -- "$git_dir" 190 | if [ -n "$relpath" ]; then 191 | set -- "$@" "$relpath" 192 | fi 193 | 194 | do_git_info "$@" 195 | } 196 | 197 | do_git_info () { 198 | local git_dir="$1" relpath="$2" root line field color reset 199 | 200 | shift 201 | 202 | echo "Repository Path: $PATH_COLOR$git_dir$RESET_COLOR" 203 | 204 | if [ $# -gt 0 ]; then 205 | root="$(dirname "$git_dir")" 206 | if [ "$relpath" = . ]; then 207 | echo "Path: $PATH_COLOR$root$RESET_COLOR" 208 | else 209 | echo "Path: $PATH_COLOR$root/$relpath$RESET_COLOR" 210 | fi 211 | fi 212 | 213 | maketemp 214 | 215 | GIT_DIR="$git_dir" git remote -v > "$TEMPFILE" 216 | if [ -s "$TEMPFILE" ]; then 217 | echo "Remote Repositories:" 218 | sed -e "s/^\([^ ]\{1,\}\)\([ ]\{1,\}\)\([^ ]\{1,\}\)/$REMOTE_COLOR\1$RESET_COLOR\2$REPOSITORY_COLOR\3$RESET_COLOR/" \ 219 | -e 's/^/ /' \ 220 | "$TEMPFILE" 221 | fi 222 | 223 | GIT_DIR="$git_dir" git branch -r --color=$COLOR_BRANCH > "$TEMPFILE" 224 | if [ -s "$TEMPFILE" ]; then 225 | echo "Remote Branches:" 226 | sed -e "s/\([ ]\{1,\}->[ ]\{1,\}\)\([^ ]\{1,\}\)/\1$REMOTE_COLOR\2$RESET_COLOR/" \ 227 | -e 's/^ */ /' "$TEMPFILE" 228 | fi 229 | 230 | GIT_DIR="$git_dir" git branch --color=$COLOR_BRANCH > "$TEMPFILE" 231 | if [ -s "$TEMPFILE" ]; then 232 | echo "Local Branches:" 233 | sed 's/^/ /' "$TEMPFILE" 234 | fi 235 | 236 | echo "Repository Configuration:" 237 | GIT_DIR="$git_dir" git config --local --list | sort | { 238 | prev_section= 239 | prev_subsection= 240 | while read line; do 241 | case "$line" in 242 | (*=*) 243 | lhs=$(expr "$line" : '\([^=]\{1,\}\)') 244 | rhs=$(expr "$line" : '[^=]\{1,\}=\(.*\)') 245 | case "$lhs" in 246 | (?*.?*.?*) 247 | section=$(expr "$lhs" : '\([^.]\{1,\}\)') 248 | subsection=$(expr "$lhs" : '[^.]\{1,\}\.\(.\{1,\}\)\.') 249 | key=$(expr "$lhs" : '[^.]\{1,\}\..\{1,\}\.\([^.]\{0,\}\)$') 250 | if [ "$section" != "$prev_section" -o "$subsection" != "$prev_subsection" ]; then 251 | prev_section=$section 252 | prev_subsection=$subsection 253 | case "$section" in 254 | (remote) 255 | subsection=$REMOTE_COLOR$subsection$RESET_COLOR 256 | ;; 257 | (branch) 258 | subsection=$LOCAL_COLOR$subsection$RESET_COLOR 259 | esac 260 | printf "\t[%s \"%s\"]\n" "$section" "$subsection" 261 | fi 262 | case "$section" in 263 | (remote) 264 | if [ "$key" = url ]; then 265 | rhs=$REPOSITORY_COLOR$rhs$RESET_COLOR 266 | fi 267 | ;; 268 | (branch) 269 | if [ "$key" = remote ]; then 270 | rhs=$REMOTE_COLOR$rhs$RESET_COLOR 271 | fi 272 | esac 273 | printf "\t\t%s = %s\n" "$key" "$rhs" 274 | ;; 275 | (?*.?*) 276 | section=$(expr "$lhs" : '\([^.]\{1,\}\)') 277 | key=$(expr "$lhs" : '[^.]\{1,\}\.\([^.]\{1,\}\)$') 278 | if [ "$section" != "$prev_section" -o -n "$prev_subsection" ]; then 279 | prev_section=$section 280 | prev_subsection= 281 | printf "\t[%s]\n" "$section" 282 | fi 283 | printf "\t\t$key = $rhs\n" 284 | ;; 285 | (*) 286 | esac 287 | esac 288 | done 289 | } 290 | 291 | (cd "$root" && GIT_DIR="$git_dir" git log --max-count=1 "$@") | { 292 | while read -r field line; do 293 | color= 294 | reset= 295 | case "$field" in 296 | commit) 297 | field='Commit ID:' 298 | color="$ID_COLOR" 299 | reset="$RESET_COLOR" 300 | ;; 301 | *:) 302 | ;; 303 | '') 304 | break 305 | ;; 306 | esac 307 | echo "Last Changed $field $color$line$reset" 308 | done 309 | cat > "$TEMPFILE" 310 | } 311 | echo "Last Changed Log:" 312 | sed 's/^ / /' "$TEMPFILE" 313 | 314 | finalize 315 | } 316 | 317 | die () { 318 | [ "$#" -gt 0 ] && echo "$0: $@" >&2 319 | finalize 320 | exit 1 321 | } 322 | 323 | TEMPFILE= 324 | 325 | maketemp () { 326 | if [ -z "$TEMPFILE" ]; then 327 | TEMPFILE="$(mktemp /tmp/git-info.XXXXXX)" || die 328 | trap "finalize; exit 130" 1 2 3 15 329 | fi 330 | } 331 | 332 | finalize () { 333 | if [ -n "$TEMPFILE" ]; then 334 | rm -f "$TEMPFILE" 335 | fi 336 | } 337 | 338 | main "$@" 339 | --------------------------------------------------------------------------------