diff options
Diffstat (limited to 'git-sh-setup.sh')
-rw-r--r--[-rwxr-xr-x] | git-sh-setup.sh | 190 |
1 files changed, 159 insertions, 31 deletions
diff --git a/git-sh-setup.sh b/git-sh-setup.sh index a44b1c74a3..770a86e2b7 100755..100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -11,9 +11,52 @@ # exporting it. unset CDPATH -die() { - echo >&2 "$@" - exit 1 +git_broken_path_fix () { + case ":$PATH:" in + *:$1:*) : ok ;; + *) + PATH=$( + SANE_TOOL_PATH="$1" + IFS=: path= sep= + set x $PATH + shift + for elem + do + case "$SANE_TOOL_PATH:$elem" in + (?*:/bin | ?*:/usr/bin) + path="$path$sep$SANE_TOOL_PATH" + sep=: + SANE_TOOL_PATH= + esac + path="$path$sep$elem" + sep=: + done + echo "$path" + ) + ;; + esac +} + +# @@BROKEN_PATH_FIX@@ + +die () { + die_with_status 1 "$@" +} + +die_with_status () { + status=$1 + shift + echo >&2 "$*" + exit "$status" +} + +GIT_QUIET= + +say () { + if test -z "$GIT_QUIET" + then + printf '%s\n' "$*" + fi } if test -n "$OPTIONS_SPEC"; then @@ -32,21 +75,22 @@ if test -n "$OPTIONS_SPEC"; then echo exit $? )" else + dashless=$(basename "$0" | sed -e 's/-/ /') usage() { - die "Usage: $0 $USAGE" + die "Usage: $dashless $USAGE" } if [ -z "$LONG_USAGE" ] then - LONG_USAGE="Usage: $0 $USAGE" + LONG_USAGE="Usage: $dashless $USAGE" else - LONG_USAGE="Usage: $0 $USAGE + LONG_USAGE="Usage: $dashless $USAGE $LONG_USAGE" fi case "$1" in - -h|--h|--he|--hel|--help) + -h) echo "$LONG_USAGE" exit esac @@ -61,19 +105,33 @@ set_reflog_action() { } git_editor() { - : "${GIT_EDITOR:=$(git config core.editor)}" - : "${GIT_EDITOR:=${VISUAL:-${EDITOR}}}" - case "$GIT_EDITOR,$TERM" in - ,dumb) - echo >&2 "No editor specified in GIT_EDITOR, core.editor, VISUAL," - echo >&2 "or EDITOR. Tried to fall back to vi but terminal is dumb." - echo >&2 "Please set one of these variables to an appropriate" - echo >&2 "editor or run $0 with options that will not cause an" - echo >&2 "editor to be invoked (e.g., -m or -F for git-commit)." - exit 1 - ;; - esac - eval "${GIT_EDITOR:=vi}" '"$@"' + if test -z "${GIT_EDITOR:+set}" + then + GIT_EDITOR="$(git var GIT_EDITOR)" || return $? + fi + + eval "$GIT_EDITOR" '"$@"' +} + +git_pager() { + if test -t 1 + then + GIT_PAGER=$(git var GIT_PAGER) + else + GIT_PAGER=cat + fi + : ${LESS=-FRSX} + export LESS + + eval "$GIT_PAGER" '"$@"' +} + +sane_grep () { + GREP_OPTIONS= LC_ALL=C grep "$@" +} + +sane_egrep () { + GREP_OPTIONS= LC_ALL=C egrep "$@" } is_bare_repository () { @@ -81,38 +139,68 @@ is_bare_repository () { } cd_to_toplevel () { - cdup=$(git rev-parse --show-cdup) - if test ! -z "$cdup" + cdup=$(git rev-parse --show-toplevel) && + cd "$cdup" || { + echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" + exit 1 + } +} + +require_work_tree_exists () { + if test "z$(git rev-parse --is-bare-repository)" != zfalse then - cd "$cdup" || { - echo >&2 "Cannot chdir to $cdup, the toplevel of the working tree" - exit 1 - } + die "fatal: $0 cannot be used without a working tree." fi } require_work_tree () { - test $(git rev-parse --is-inside-work-tree) = true || + test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || die "fatal: $0 cannot be used without a working tree." } +require_clean_work_tree () { + git rev-parse --verify HEAD >/dev/null || exit 1 + git update-index -q --ignore-submodules --refresh + err=0 + + if ! git diff-files --quiet --ignore-submodules + then + echo >&2 "Cannot $1: You have unstaged changes." + err=1 + fi + + if ! git diff-index --cached --quiet --ignore-submodules HEAD -- + then + if [ $err = 0 ] + then + echo >&2 "Cannot $1: Your index contains uncommitted changes." + else + echo >&2 "Additionally, your index contains uncommitted changes." + fi + err=1 + fi + + if [ $err = 1 ] + then + test -n "$2" && echo >&2 "$2" + exit 1 + fi +} + get_author_ident_from_commit () { pick_author_script=' /^author /{ s/'\''/'\''\\'\'\''/g h s/^author \([^<]*\) <[^>]*> .*$/\1/ - s/'\''/'\''\'\'\''/g s/.*/GIT_AUTHOR_NAME='\''&'\''/p g s/^author [^<]* <\([^>]*\)> .*$/\1/ - s/'\''/'\''\'\'\''/g s/.*/GIT_AUTHOR_EMAIL='\''&'\''/p g - s/^author [^<]* <[^>]*> \(.*\)$/\1/ - s/'\''/'\''\'\'\''/g + s/^author [^<]* <[^>]*> \(.*\)$/@\1/ s/.*/GIT_AUTHOR_DATE='\''&'\''/p q @@ -123,6 +211,46 @@ get_author_ident_from_commit () { LANG=C LC_ALL=C sed -ne "$pick_author_script" } +# Clear repo-local GIT_* environment variables. Useful when switching to +# another repository (e.g. when entering a submodule). See also the env +# list in git_connect() +clear_local_git_env() { + unset $(git rev-parse --local-env-vars) +} + + +# Platform specific tweaks to work around some commands +case $(uname -s) in +*MINGW*) + # Windows has its own (incompatible) sort and find + sort () { + /usr/bin/sort "$@" + } + find () { + /usr/bin/find "$@" + } + # git sees Windows-style pwd + pwd () { + builtin pwd -W + } + is_absolute_path () { + case "$1" in + [/\\]* | [A-Za-z]:*) + return 0 ;; + esac + return 1 + } + ;; +*) + is_absolute_path () { + case "$1" in + /*) + return 0 ;; + esac + return 1 + } +esac + # Make sure we are in a valid repository of a vintage we understand, # if we require to be in a git repository. if test -z "$NONGIT_OK" |