diff --git a/vcsh.in b/vcsh.in index aa44c978..377dd501 100755 --- a/vcsh.in +++ b/vcsh.in @@ -21,6 +21,10 @@ VCSH_SELF='@TRANSFORMED_PACKAGE_NAME@'; export VCSH_SELF # Ensure all files created are accessible only to the current user. umask 0077 +# Allow override of shell dependencies (including outside of $PATH) either by +# setting ENV vars at build time or run time. +alias git="${GIT:-@GIT@}" + fatal() { echo "$VCSH_SELF: fatal: $1" >&2 [ -z "$2" ] && exit 1 @@ -169,7 +173,7 @@ info() { clone() { hook pre-clone # Check if remote is reachable. Abort early if there's a typo, TLS certificate problem, etc - @GIT@ ls-remote "$GIT_REMOTE" 2> /dev/null || fatal "Can not reach '$GIT_REMOTE'" + git ls-remote "$GIT_REMOTE" 2> /dev/null || fatal "Can not reach '$GIT_REMOTE'" init # Test which, if any, given or detected branches can be pulled from. # In a future version, if we need the logic, we could do the following: @@ -179,7 +183,7 @@ clone() { # set VCSH_BRANCH if only one match # offer a list of all matching refs for the user to choose for VCSH_BRANCH_TEST in "$VCSH_BRANCH" master trunk development; do - if [ $(@GIT@ ls-remote "$GIT_REMOTE" "$VCSH_BRANCH_TEST" 2> /dev/null | @WC@ -l ) -lt 1 ]; then + if [ $(git ls-remote "$GIT_REMOTE" "$VCSH_BRANCH_TEST" 2> /dev/null | @WC@ -l ) -lt 1 ]; then info "remote branch '$VCSH_BRANCH_TEST' empty" else info "remote branch '$VCSH_BRANCH_TEST' found" @@ -194,21 +198,21 @@ clone() { VCSH_BRANCH=$VCSH_BRANCH_REMOTE # Set up remote - @GIT@ remote add origin "$GIT_REMOTE" - @GIT@ checkout -b "$VCSH_BRANCH" || return $? - @GIT@ config branch."$VCSH_BRANCH".remote origin - @GIT@ config branch."$VCSH_BRANCH".merge refs/heads/"$VCSH_BRANCH" - GIT_VERSION_MAJOR=$(@GIT@ --version | @SED@ -E -n 's/.* ([0-9]+)\..*/\1/p' ) + git remote add origin "$GIT_REMOTE" + git checkout -b "$VCSH_BRANCH" || return $? + git config branch."$VCSH_BRANCH".remote origin + git config branch."$VCSH_BRANCH".merge refs/heads/"$VCSH_BRANCH" + GIT_VERSION_MAJOR=$(git --version | @SED@ -E -n 's/.* ([0-9]+)\..*/\1/p' ) if [ 1 -lt "$GIT_VERSION_MAJOR" ];then - @GIT@ fetch origin "$VCSH_BRANCH" + git fetch origin "$VCSH_BRANCH" else - @GIT@ fetch origin + git fetch origin fi hook pre-merge - @GIT@ read-tree -n -mu origin/"$VCSH_BRANCH" \ + git read-tree -n -mu origin/"$VCSH_BRANCH" \ || fatal "will stop after fetching and not try to merge! Once this situation has been resolved, run 'vcsh $VCSH_REPO_NAME pull' to finish cloning." 17 # editorconfig-checker-disable-line - @GIT@ -c merge.ff=true merge origin/"$VCSH_BRANCH" + git -c merge.ff=true merge origin/"$VCSH_BRANCH" hook post-merge hook post-clone retire @@ -224,7 +228,7 @@ commit() { GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR use hook_repo pre-commit - @GIT@ commit --untracked-files=no --quiet "$@" + git commit --untracked-files=no --quiet "$@" hook_repo post-commit VCSH_COMMAND_RETURN_CODE=$? echo @@ -236,7 +240,7 @@ delete() { cd "$VCSH_BASE" || fatal "could not enter '$VCSH_BASE'" 11 use info "This operation WILL DESTROY DATA!" - files=$(@GIT@ ls-files) + files=$(git ls-files) echo "These files will be deleted: $files @@ -263,7 +267,7 @@ foreach() { # We default to prefixing `git` to all commands passed to foreach, but # allow running in general context with -g - command_prefix=@GIT@ + command_prefix=git # shellcheck disable=SC2220 while getopts gp flag; do case "$flag" in @@ -319,7 +323,7 @@ init() { [ ! -e "$GIT_DIR" ] || fatal "'$GIT_DIR' exists" 10 mkdir -p "$VCSH_BASE" || fatal "could not create '$VCSH_BASE'" 50 cd "$VCSH_BASE" || fatal "could not enter '$VCSH_BASE'" 11 - @GIT@ init --shared=false + git init --shared=false upgrade hook post-init } @@ -335,13 +339,13 @@ list_has_remote() { GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR # This command returns the tracking branch of the currently-checked-out local # branch, if any. See https://stackoverflow.com/a/9753364 - [ -n "$(@GIT@ for-each-ref "$(@GIT@ symbolic-ref -q HEAD)")" ] && echo "$VCSH_REPO_NAME" + [ -n "$(git for-each-ref "$(git symbolic-ref -q HEAD)")" ] && echo "$VCSH_REPO_NAME" done } get_files() { GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR - @GIT@ ls-files --full-name + git ls-files --full-name } list_tracked() { @@ -397,7 +401,7 @@ list_untracked() { list_untracked_helper() { export GIT_DIR="$VCSH_REPO_D/$VCSH_REPO_NAME.git" - @GIT@ ls-files --others $exclude_standard_opt $directory_opt | ( + git ls-files --others $exclude_standard_opt $directory_opt | ( while read -r line; do echo "$line" directory_component=${line%%/*} @@ -420,7 +424,7 @@ pull() { GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR use hook_repo pre-pull - @GIT@ pull + git pull hook_repo post-pull VCSH_COMMAND_RETURN_CODE=$? echo @@ -436,7 +440,7 @@ push() { GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR use hook_repo pre-push - @GIT@ push + git push hook_repo post-push VCSH_COMMAND_RETURN_CODE=$? echo @@ -494,13 +498,13 @@ status_helper() { use # Shellcheck isn't understanding a complex block. # shellcheck disable=SC1083 - remote_tracking_branch=$(@GIT@ rev-parse --abbrev-ref --symbolic-full-name @{u} 2> /dev/null) && { - commits_behind=$(@GIT@ log ..${remote_tracking_branch} --oneline | @WC@ -l) - commits_ahead=$(@GIT@ log ${remote_tracking_branch}.. --oneline | @WC@ -l) + remote_tracking_branch=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2> /dev/null) && { + commits_behind=$(git log ..${remote_tracking_branch} --oneline | @WC@ -l) + commits_ahead=$(git log ${remote_tracking_branch}.. --oneline | @WC@ -l) [ ${commits_behind} -ne 0 ] && echo "Behind $remote_tracking_branch by $commits_behind commits" [ ${commits_ahead} -ne 0 ] && echo "Ahead of $remote_tracking_branch by $commits_ahead commits" } - @GIT@ ${VCSH_GIT_OPTIONS} status --short --untracked-files='no' | @SED@ -E 's@([^ ] +)@\1~/@' + git ${VCSH_GIT_OPTIONS} status --short --untracked-files='no' | @SED@ -E 's@([^ ] +)@\1~/@' VCSH_COMMAND_RETURN_CODE=$? } @@ -509,20 +513,20 @@ upgrade() { # fake-bare repositories are not bare, actually. Set this to false # because otherwise Git complains "fatal: core.bare and core.worktree # do not make sense" - @GIT@ config core.bare false + git config core.bare false # core.worktree may be absolute or relative to $GIT_DIR, depending on # user preference if [ ! "x$VCSH_WORKTREE" = 'xabsolute' ]; then - @GIT@ config core.worktree "$(cd "$GIT_DIR" && GIT_WORK_TREE=$VCSH_BASE @GIT@ rev-parse --show-cdup)" + git config core.worktree "$(cd "$GIT_DIR" && GIT_WORK_TREE=$VCSH_BASE git rev-parse --show-cdup)" elif [ ! "x$VCSH_WORKTREE" = 'xrelative' ]; then - @GIT@ config core.worktree "$VCSH_BASE" + git config core.worktree "$VCSH_BASE" fi - [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && @GIT@ config core.excludesfile ".gitignore.d/$VCSH_REPO_NAME" - [ ! "x$VCSH_GITATTRIBUTES" = 'xnone' ] && @GIT@ config core.attributesfile ".gitattributes.d/$VCSH_REPO_NAME" - @GIT@ config vcsh.vcsh 'true' + [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && git config core.excludesfile ".gitignore.d/$VCSH_REPO_NAME" + [ ! "x$VCSH_GITATTRIBUTES" = 'xnone' ] && git config core.attributesfile ".gitattributes.d/$VCSH_REPO_NAME" + git config vcsh.vcsh 'true' use - [ -e "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" ] && @GIT@ add -f "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" - [ -e "$VCSH_BASE/.gitattributes.d/$VCSH_REPO_NAME" ] && @GIT@ add -f "$VCSH_BASE/.gitattributes.d/$VCSH_REPO_NAME" + [ -e "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" ] && git add -f "$VCSH_BASE/.gitignore.d/$VCSH_REPO_NAME" + [ -e "$VCSH_BASE/.gitattributes.d/$VCSH_REPO_NAME" ] && git add -f "$VCSH_BASE/.gitattributes.d/$VCSH_REPO_NAME" hook post-upgrade } @@ -558,12 +562,12 @@ write_gitignore() { # Works in all shells we care about. # shellcheck disable=SC2039,SC3043 local GIT_VERSION GIT_VERSION_MAJOR GIT_VERSION_MINOR - GIT_VERSION="$(@GIT@ --version)" + GIT_VERSION="$(git --version)" GIT_VERSION_MAJOR="$(echo "$GIT_VERSION" | @SED@ -E -n 's/.* ([0-9]+)\..*/\1/p')" GIT_VERSION_MINOR="$(echo "$GIT_VERSION" | @SED@ -E -n 's/.* ([0-9]+)\.([0-9]+)\..*/\2/p')" OLDIFS=$IFS IFS=$(printf '\n\t') - gitignores=$(for file in $(@GIT@ ls-files); do + gitignores=$(for file in $(git ls-files); do while true; do echo "$file"; new=${file%/*} [ x"$file" = x"$new" ] && break @@ -604,7 +608,7 @@ write_gitignore() { fatal "could not move '$tempfile' to '$GIT_IGNORE_PATH'" 53 } -debug "$(@GIT@ version)" +debug "$(git version)" if [ ! "x$VCSH_GITIGNORE" = 'xexact' ] && [ ! "x$VCSH_GITIGNORE" = 'xnone' ] && [ ! "x$VCSH_GITIGNORE" = 'xrecursive' ]; then fatal "'\$VCSH_GITIGNORE' must equal 'exact', 'none', or 'recursive'" 1 @@ -658,7 +662,7 @@ elif [ "$VCSH_COMMAND" = 'help' ]; then help && exit elif [ "$VCSH_COMMAND" = 'version' ]; then echo "$VCSH_SELF $VCSH_VERSION" - @GIT@ version + git version exit elif [ x"$VCSH_COMMAND" = x'which' ]; then [ -z "$2" ] && fatal "$VCSH_COMMAND: please specify a filename" 1 @@ -705,7 +709,7 @@ elif [ -n "$2" ]; then GIT_DIR=$VCSH_REPO_D/$VCSH_REPO_NAME.git; export GIT_DIR [ -d "$GIT_DIR" ] || { help; exit 1; } shift 1 - set -- "@GIT@" "$@" + set -- "git" "$@" elif [ -n "$VCSH_COMMAND" ]; then VCSH_COMMAND='enter'; export VCSH_COMMAND VCSH_REPO_NAME=$1; export VCSH_REPO_NAME