1# This shell scriplet is meant to be included by other shell scripts 2# to set up some variables pointing at the normal git directories and 3# a few helper shell functions. 4 5# Source git-sh-i18n for gettext support. 6. git-sh-i18n 7 8# Having this variable in your environment would break scripts because 9# you would cause "cd" to be taken to unexpected places. If you 10# like CDPATH, define it for your interactive shell sessions without 11# exporting it. 12# But we protect ourselves from such a user mistake nevertheless. 13unset CDPATH 14 15# Similarly for IFS, but some shells (e.g. FreeBSD 7.2) are buggy and 16# do not equate an unset IFS with IFS with the default, so here is 17# an explicit SP HT LF. 18IFS=' 19' 20 21git_broken_path_fix () { 22case":$PATH:"in 23*:$1:*) : ok ;; 24*) 25 PATH=$( 26 SANE_TOOL_PATH="$1" 27 IFS=: path= sep= 28set x $PATH 29shift 30for elem 31do 32case"$SANE_TOOL_PATH:$elem"in 33(?*:/bin | ?*:/usr/bin) 34 path="$path$sep$SANE_TOOL_PATH" 35 sep=: 36 SANE_TOOL_PATH= 37esac 38 path="$path$sep$elem" 39 sep=: 40done 41echo"$path" 42) 43;; 44esac 45} 46 47# @@BROKEN_PATH_FIX@@ 48 49die () { 50 die_with_status 1"$@" 51} 52 53die_with_status () { 54 status=$1 55shift 56printf>&2'%s\n'"$*" 57exit"$status" 58} 59 60GIT_QUIET= 61 62say () { 63iftest -z"$GIT_QUIET" 64then 65printf'%s\n'"$*" 66fi 67} 68 69iftest -n"$OPTIONS_SPEC";then 70 usage() { 71"$0"-h 72exit1 73} 74 75 parseopt_extra= 76[-n"$OPTIONS_KEEPDASHDASH"] && 77 parseopt_extra="--keep-dashdash" 78[-n"$OPTIONS_STUCKLONG"] && 79 parseopt_extra="$parseopt_extra--stuck-long" 80 81eval"$( 82 echo "$OPTIONS_SPEC" | 83 git rev-parse --parseopt$parseopt_extra-- "$@" || 84 echo exit $? 85 )" 86else 87 dashless=$(basename -- "$0" | sed -e 's/-/ /') 88 usage() { 89 die "$(eval_gettext "usage: \$dashless \$USAGE")" 90} 91 92if[-z"$LONG_USAGE"] 93then 94 LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE")" 95else 96 LONG_USAGE="$(eval_gettext "usage: \$dashless \$USAGE 97 98$LONG_USAGE")" 99fi 100 101case"$1"in 102-h) 103echo"$LONG_USAGE" 104exit 105esac 106fi 107 108# Set the name of the end-user facing command in the reflog when the 109# script may update refs. When GIT_REFLOG_ACTION is already set, this 110# will not overwrite it, so that a scripted Porcelain (e.g. "git 111# rebase") can set it to its own name (e.g. "rebase") and then call 112# another scripted Porcelain (e.g. "git am") and a call to this 113# function in the latter will keep the name of the end-user facing 114# program (e.g. "rebase") in GIT_REFLOG_ACTION, ensuring whatever it 115# does will be record as actions done as part of the end-user facing 116# operation (e.g. "rebase"). 117# 118# NOTE NOTE NOTE: consequently, after assigning a specific message to 119# GIT_REFLOG_ACTION when calling a "git" command to record a custom 120# reflog message, do not leave that custom value in GIT_REFLOG_ACTION, 121# after you are done. Other callers of "git" commands that rely on 122# writing the default "program name" in reflog expect the variable to 123# contain the value set by this function. 124# 125# To use a custom reflog message, do either one of these three: 126# 127# (a) use a single-shot export form: 128# GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz" \ 129# git command-that-updates-a-ref 130# 131# (b) save the original away and restore: 132# SAVED_ACTION=$GIT_REFLOG_ACTION 133# GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz" 134# git command-that-updates-a-ref 135# GIT_REFLOG_ACITON=$SAVED_ACTION 136# 137# (c) assign the variable in a subshell: 138# ( 139# GIT_REFLOG_ACTION="$GIT_REFLOG_ACTION: preparing frotz" 140# git command-that-updates-a-ref 141# ) 142set_reflog_action() { 143if[-z"${GIT_REFLOG_ACTION:+set}"] 144then 145 GIT_REFLOG_ACTION="$*" 146export GIT_REFLOG_ACTION 147fi 148} 149 150git_editor() { 151iftest -z"${GIT_EDITOR:+set}" 152then 153 GIT_EDITOR="$(git var GIT_EDITOR)"||return $? 154fi 155 156eval"$GIT_EDITOR"'"$@"' 157} 158 159git_pager() { 160iftest -t1 161then 162 GIT_PAGER=$(git var GIT_PAGER) 163else 164 GIT_PAGER=cat 165fi 166:"${LESS=-FRX}" 167:"${LV=-c}" 168export LESS LV 169 170eval"$GIT_PAGER"'"$@"' 171} 172 173sane_grep () { 174 GREP_OPTIONS= LC_ALL=C grep @@SANE_TEXT_GREP@@ "$@" 175} 176 177sane_egrep () { 178 GREP_OPTIONS= LC_ALL=C egrep @@SANE_TEXT_GREP@@ "$@" 179} 180 181is_bare_repository () { 182 git rev-parse --is-bare-repository 183} 184 185cd_to_toplevel () { 186 cdup=$(git rev-parse --show-toplevel)&& 187cd"$cdup"|| { 188 gettextln "Cannot chdir to \$cdup, the toplevel of the working tree">&2 189exit1 190} 191} 192 193require_work_tree_exists () { 194iftest"z$(git rev-parse --is-bare-repository)"!= zfalse 195then 196 program_name=$0 197 die "$(gettext "fatal: \$program_name cannot be used without a working tree.")" 198fi 199} 200 201require_work_tree () { 202test"$(git rev-parse --is-inside-work-tree 2>/dev/null)"= true || { 203 program_name=$0 204 die "$(gettext "fatal: \$program_name cannot be used without a working tree.")" 205} 206} 207 208require_clean_work_tree () { 209 git rev-parse --verify HEAD >/dev/null ||exit1 210 git update-index -q --ignore-submodules --refresh 211 err=0 212 213if! git diff-files --quiet --ignore-submodules 214then 215 action=$1 216case"$action"in 217 rebase) 218 gettextln "Cannot rebase: You have unstaged changes.">&2 219;; 220"rewrite branches") 221 gettextln "Cannot rewrite branches: You have unstaged changes.">&2 222;; 223"pull with rebase") 224 gettextln "Cannot pull with rebase: You have unstaged changes.">&2 225;; 226*) 227 eval_gettextln "Cannot \$action: You have unstaged changes.">&2 228;; 229esac 230 err=1 231fi 232 233if! git diff-index --cached --quiet --ignore-submodules HEAD -- 234then 235iftest$err=0 236then 237 action=$1 238case"$action"in 239 rebase) 240 gettextln "Cannot rebase: Your index contains uncommitted changes.">&2 241;; 242"pull with rebase") 243 gettextln "Cannot pull with rebase: Your index contains uncommitted changes.">&2 244;; 245*) 246 eval_gettextln "Cannot \$action: Your index contains uncommitted changes.">&2 247;; 248esac 249else 250 gettextln "Additionally, your index contains uncommitted changes.">&2 251fi 252 err=1 253fi 254 255iftest$err=1 256then 257test -n"$2"&&echo"$2">&2 258exit1 259fi 260} 261 262# Generate a sed script to parse identities from a commit. 263# 264# Reads the commit from stdin, which should be in raw format (e.g., from 265# cat-file or "--pretty=raw"). 266# 267# The first argument specifies the ident line to parse (e.g., "author"), and 268# the second specifies the environment variable to put it in (e.g., "AUTHOR" 269# for "GIT_AUTHOR_*"). Multiple pairs can be given to parse author and 270# committer. 271pick_ident_script () { 272whiletest$#-gt0 273do 274 lid=$1;shift 275 uid=$1;shift 276printf'%s'" 277 /^$lid/{ 278 s/'/'\\\\''/g 279 h 280 s/^$lid"'\([^<]*\) <[^>]*> .*$/\1/'" 281 s/.*/GIT_${uid}_NAME='&'/p 282 283 g 284 s/^$lid"'[^<]* <\([^>]*\)> .*$/\1/'" 285 s/.*/GIT_${uid}_EMAIL='&'/p 286 287 g 288 s/^$lid"'[^<]* <[^>]*> \(.*\)$/@\1/'" 289 s/.*/GIT_${uid}_DATE='&'/p 290 } 291 " 292done 293echo'/^$/q' 294} 295 296# Create a pick-script as above and feed it to sed. Stdout is suitable for 297# feeding to eval. 298parse_ident_from_commit () { 299 LANG=C LC_ALL=C sed-ne"$(pick_ident_script "$@")" 300} 301 302# Parse the author from a commit given as an argument. Stdout is suitable for 303# feeding to eval to set the usual GIT_* ident variables. 304get_author_ident_from_commit () { 305 encoding=$(git config i18n.commitencoding || echo UTF-8) 306 git show -s --pretty=raw --encoding="$encoding""$1"--| 307 parse_ident_from_commit author AUTHOR 308} 309 310# Clear repo-local GIT_* environment variables. Useful when switching to 311# another repository (e.g. when entering a submodule). See also the env 312# list in git_connect() 313clear_local_git_env() { 314unset$(git rev-parse --local-env-vars) 315} 316 317# Generate a virtual base file for a two-file merge. Uses git apply to 318# remove lines from $1 that are not in $2, leaving only common lines. 319create_virtual_base() { 320 sz0=$(wc -c <"$1") 321 @@DIFF@@ -u -La/"$1"-Lb/"$1""$1""$2"| git apply --no-add 322 sz1=$(wc -c <"$1") 323 324# If we do not have enough common material, it is not 325# worth trying two-file merge using common subsections. 326expr$sz0 \<$sz1 \*2>/dev/null || : >"$1" 327} 328 329 330# Platform specific tweaks to work around some commands 331case$(uname -s)in 332*MINGW*) 333# Windows has its own (incompatible) sort and find 334sort() { 335/usr/bin/sort"$@" 336} 337find() { 338/usr/bin/find"$@" 339} 340# git sees Windows-style pwd 341pwd() { 342builtin pwd -W 343} 344 is_absolute_path () { 345case"$1"in 346[/\\]* | [A-Za-z]:*) 347return0;; 348esac 349return1 350} 351;; 352*) 353 is_absolute_path () { 354case"$1"in 355/*) 356return0;; 357esac 358return1 359} 360esac 361 362# Make sure we are in a valid repository of a vintage we understand, 363# if we require to be in a git repository. 364git_dir_init () { 365 GIT_DIR=$(git rev-parse --git-dir)||exit 366if[-z"$SUBDIRECTORY_OK"] 367then 368test -z"$(git rev-parse --show-cdup)"|| { 369exit=$? 370 gettextln "You need to run this command from the toplevel of the working tree.">&2 371exit$exit 372} 373fi 374test -n"$GIT_DIR"&& GIT_DIR=$(cd "$GIT_DIR" && pwd)|| { 375 gettextln "Unable to determine absolute path of git directory">&2 376exit1 377} 378:"${GIT_OBJECT_DIRECTORY="$(git rev-parse --git-path objects)"}" 379} 380 381iftest -z"$NONGIT_OK" 382then 383 git_dir_init 384fi 385 386peel_committish () { 387case"$1"in 388:/*) 389 peeltmp=$(git rev-parse --verify "$1")&& 390 git rev-parse --verify"${peeltmp}^0" 391;; 392*) 393 git rev-parse --verify"${1}^0" 394;; 395esac 396}