123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400 |
- # This shell scriplet is meant to be included by other shell scripts
- # to set up some variables pointing at the normal git directories and
- # a few helper shell functions.
- # Having this variable in your environment would break scripts because
- # you would cause "cd" to be taken to unexpected places. If you
- # like CDPATH, define it for your interactive shell sessions without
- # exporting it.
- # But we protect ourselves from such a user mistake nevertheless.
- unset CDPATH
- # Similarly for IFS, but some shells (e.g. FreeBSD 7.2) are buggy and
- # do not equate an unset IFS with IFS with the default, so here is
- # an explicit SP HT LF.
- IFS='
- '
- 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@@
- # Source git-sh-i18n for gettext support.
- . "$(git --exec-path)/git-sh-i18n"
- die () {
- die_with_status 1 "$@"
- }
- die_with_status () {
- status=$1
- shift
- printf >&2 '%s\n' "$*"
- exit "$status"
- }
- GIT_QUIET=
- say () {
- if test -z "$GIT_QUIET"
- then
- printf '%s\n' "$*"
- fi
- }
- if test -n "$OPTIONS_SPEC"; then
- usage() {
- "$0" -h
- exit 1
- }
- parseopt_extra=
- [ -n "$OPTIONS_KEEPDASHDASH" ] &&
- parseopt_extra="--keep-dashdash"
- [ -n "$OPTIONS_STUCKLONG" ] &&
- parseopt_extra="$parseopt_extra --stuck-long"
- eval "$(
- echo "$OPTIONS_SPEC" |
- git rev-parse --parseopt $parseopt_extra -- "$@" ||
- echo exit $?
- )"
- else
- dashless=$(basename -- "$0" | sed -e 's/-/ /')
- usage() {
- die "$(eval_gettext "usage: \$dashless \$USAGE")"
- }
- if [ -z "$LONG_USAGE" ]
- then
- LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE")"
- else
- LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE
- $LONG_USAGE")"
- fi
- case "$1" in
- -h)
- echo "$LONG_USAGE"
- case "$0" in *git-legacy-stash) exit 129;; esac
- exit
- esac
- fi
- # Set the name of the end-user facing command in the reflog when the
- # script may update refs. When GIT_REFLOG_ACTION is already set, this
- # will not overwrite it, so that a scripted Porcelain (e.g. "git
- # rebase") can set it to its own name (e.g. "rebase") and then call
- # another scripted Porcelain (e.g. "git am") and a call to this
- # function in the latter will keep the name of the end-user facing
- # program (e.g. "rebase") in GIT_REFLOG_ACTION, ensuring whatever it
- # does will be record as actions done as part of the end-user facing
- # operation (e.g. "rebase").
- #
- # NOTE NOTE NOTE: consequently, after assigning a specific message to
- # GIT_REFLOG_ACTION when calling a "git" command to record a custom
- # reflog message, do not leave that custom value in GIT_REFLOG_ACTION,
- # after you are done. Other callers of "git" commands that rely on
- # writing the default "program name" in reflog expect the variable to
- # contain the value set by this function.
- #
- # To use a custom reflog message, do either one of these three:
- #
- # (a) use a single-shot export form:
- # GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz" \
- # git command-that-updates-a-ref
- #
- # (b) save the original away and restore:
- # SAVED_ACTION=$GIT_REFLOG_ACTION
- # GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz"
- # git command-that-updates-a-ref
- # GIT_REFLOG_ACITON=$SAVED_ACTION
- #
- # (c) assign the variable in a subshell:
- # (
- # GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz"
- # git command-that-updates-a-ref
- # )
- set_reflog_action() {
- if [ -z "${GIT_REFLOG_ACTION:+set}" ]
- then
- GIT_REFLOG_ACTION="$*"
- export GIT_REFLOG_ACTION
- fi
- }
- git_editor() {
- 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
- for vardef in @@PAGER_ENV@@
- do
- var=${vardef%%=*}
- eval ": \"\${$vardef}\" && export $var"
- done
- eval "$GIT_PAGER" '"$@"'
- }
- sane_grep () {
- GREP_OPTIONS= LC_ALL=C grep @@SANE_TEXT_GREP@@ "$@"
- }
- sane_egrep () {
- GREP_OPTIONS= LC_ALL=C egrep @@SANE_TEXT_GREP@@ "$@"
- }
- is_bare_repository () {
- git rev-parse --is-bare-repository
- }
- cd_to_toplevel () {
- cdup=$(git rev-parse --show-toplevel) &&
- cd "$cdup" || {
- gettextln "Cannot chdir to \$cdup, the toplevel of the working tree" >&2
- exit 1
- }
- }
- require_work_tree_exists () {
- if test "z$(git rev-parse --is-bare-repository)" != zfalse
- then
- program_name=$0
- die "$(eval_gettext "fatal: \$program_name cannot be used without a working tree.")"
- fi
- }
- require_work_tree () {
- test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" = true || {
- program_name=$0
- die "$(eval_gettext "fatal: \$program_name 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
- action=$1
- case "$action" in
- rebase)
- gettextln "Cannot rebase: You have unstaged changes." >&2
- ;;
- "rewrite branches")
- gettextln "Cannot rewrite branches: You have unstaged changes." >&2
- ;;
- "pull with rebase")
- gettextln "Cannot pull with rebase: You have unstaged changes." >&2
- ;;
- *)
- eval_gettextln "Cannot \$action: You have unstaged changes." >&2
- ;;
- esac
- err=1
- fi
- if ! git diff-index --cached --quiet --ignore-submodules HEAD --
- then
- if test $err = 0
- then
- action=$1
- case "$action" in
- rebase)
- gettextln "Cannot rebase: Your index contains uncommitted changes." >&2
- ;;
- "pull with rebase")
- gettextln "Cannot pull with rebase: Your index contains uncommitted changes." >&2
- ;;
- *)
- eval_gettextln "Cannot \$action: Your index contains uncommitted changes." >&2
- ;;
- esac
- else
- gettextln "Additionally, your index contains uncommitted changes." >&2
- fi
- err=1
- fi
- if test $err = 1
- then
- test -n "$2" && echo "$2" >&2
- exit 1
- fi
- }
- # Generate a sed script to parse identities from a commit.
- #
- # Reads the commit from stdin, which should be in raw format (e.g., from
- # cat-file or "--pretty=raw").
- #
- # The first argument specifies the ident line to parse (e.g., "author"), and
- # the second specifies the environment variable to put it in (e.g., "AUTHOR"
- # for "GIT_AUTHOR_*"). Multiple pairs can be given to parse author and
- # committer.
- pick_ident_script () {
- while test $# -gt 0
- do
- lid=$1; shift
- uid=$1; shift
- printf '%s' "
- /^$lid /{
- s/'/'\\\\''/g
- h
- s/^$lid "'\([^<]*\) <[^>]*> .*$/\1/'"
- s/.*/GIT_${uid}_NAME='&'/p
- g
- s/^$lid "'[^<]* <\([^>]*\)> .*$/\1/'"
- s/.*/GIT_${uid}_EMAIL='&'/p
- g
- s/^$lid "'[^<]* <[^>]*> \(.*\)$/@\1/'"
- s/.*/GIT_${uid}_DATE='&'/p
- }
- "
- done
- echo '/^$/q'
- }
- # Create a pick-script as above and feed it to sed. Stdout is suitable for
- # feeding to eval.
- parse_ident_from_commit () {
- LANG=C LC_ALL=C sed -ne "$(pick_ident_script "$@")"
- }
- # Parse the author from a commit given as an argument. Stdout is suitable for
- # feeding to eval to set the usual GIT_* ident variables.
- get_author_ident_from_commit () {
- encoding=$(git config i18n.commitencoding || echo UTF-8)
- git show -s --pretty=raw --encoding="$encoding" "$1" -- |
- parse_ident_from_commit author AUTHOR
- }
- # 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)
- }
- # Generate a virtual base file for a two-file merge. Uses git apply to
- # remove lines from $1 that are not in $2, leaving only common lines.
- create_virtual_base() {
- sz0=$(wc -c <"$1")
- @@DIFF@@ -u -La/"$1" -Lb/"$1" "$1" "$2" | git apply --no-add
- sz1=$(wc -c <"$1")
- # If we do not have enough common material, it is not
- # worth trying two-file merge using common subsections.
- expr $sz0 \< $sz1 \* 2 >/dev/null || : >"$1"
- }
- # 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.
- git_dir_init () {
- GIT_DIR=$(git rev-parse --git-dir) || exit
- if [ -z "$SUBDIRECTORY_OK" ]
- then
- test -z "$(git rev-parse --show-cdup)" || {
- exit=$?
- gettextln "You need to run this command from the toplevel of the working tree." >&2
- exit $exit
- }
- fi
- test -n "$GIT_DIR" && GIT_DIR=$(cd "$GIT_DIR" && pwd) || {
- gettextln "Unable to determine absolute path of git directory" >&2
- exit 1
- }
- : "${GIT_OBJECT_DIRECTORY="$(git rev-parse --git-path objects)"}"
- }
- if test -z "$NONGIT_OK"
- then
- git_dir_init
- fi
- peel_committish () {
- case "$1" in
- :/*)
- peeltmp=$(git rev-parse --verify "$1") &&
- git rev-parse --verify "${peeltmp}^0"
- ;;
- *)
- git rev-parse --verify "${1}^0"
- ;;
- esac
- }
|