Cygwin下配置自定义函数git替代git默认命令,实现自动识别不同仓库使用不同的用户和密钥,并可自动检测识别是否需要代理做push或pull操作

以下代码在个人自用Cygwin平台上测试通过,MSYS Git Bash下也可以使用,但需要做一些调整,比如MSYS Git Bash默认没有nc这个命令,等等...

git函数部分写入.bashrc.bash_profile自动加载即可,使用时还是遵循原始git命令使用习惯即可,脚本代码会自动hook并运行内部功能以达到效果(自动切换用户,判断是国内还是国外仓库)
git add -v .
git commit
git push
git fetch
git pull
etc...:

## 以下示例代码已脱敏,去除了个人敏感信息,仅提供一个思路,若需要使用,需要你自行填充个人信息
## 覆盖默认git命令,判断是否使用特定密钥连接git服务器
## 在部分目录下如果source重载本文件时报错请参考:https://stackoverflow.com/questions/35335488/bash-source-syntax-error-near-unexpected-token-then
## 原因,git别名与git函数冲突导致git别名被提前展开,See:/v/bin/git-stevxxxx-dir.sh
[[ $(type -t git) == "alias" ]] && unalias git
git() {
	local SCRIPTPATH="/v/bin/aliaswinapp"
	# 20210915 备注:以下 print_color 操作会破坏git的文件名补全功能,原因未知!可能是 {TAB} 键错误地传递给了print_color处理,y也可能与git本身的实现有关(实际操作前不能有任何文本输出...)
	#print_color 33 "Notice:使用自定义 git 函数..."
	#print_color 33 "Notice:Function in $SCRIPTPATH"
	#print_color 33 "export GIT_FORCE_PROXY=[true | x.x.x.x:port] 可促使git强制使用代理..."
	if [[ ! $(echo "$*"|grep -E '\t') ]] #排除TAB按键的事件响应,以修复git的自动补全文件名功能 @20210915
	then
		print_color 33 "Notice:使用自定义 git 函数..."
		print_color 33 "Notice:Function in $SCRIPTPATH"
		print_color 33 "export GIT_FORCE_PROXY=[true | x.x.x.x:port] 可促使git强制使用代理..."
	fi
	#if [[ $(echo "$*"|tr '[:upper:]' '[:lower:]') =~ "commit" ]]
	if [[ "${*,,}" =~ ^commit(\ .*)?$ ]]
	then
		OLD_IFS=$IFS
		IFS=$(echo -e "\n")
		/usr/bin/git $@
		IFS=$OLD_IFS
		return 
	fi
	if [ $# -gt 1 ] && [[ "$1" == "-i" ]];then
		/v/bin/git.sh $@
		# 如果git当前动作是克隆仓库,则克隆后设置本地仓库对应用户名和邮箱为stevxxxx
		if [[ "$*" =~ " clone " ]] && [[ "$2" =~ "github_stevxxxx" ]];
		then
			# 假定最后一个参数包含本地仓库目录路径
		    local repoDir=$(basename "${@:$#}"|sed 's/.git$//i')
			#echo "仓库目录 $repoDir"
			if [ -d "$repoDir" ];
			then
				pushd "$repoDir" >/dev/null
				/usr/bin/git config --local user.name stevxxxx
				/usr/bin/git config --local user.email stevxxxx@gmail.com
				popd >/dev/null
			fi
		fi
		## 设置当前仓库的提交者的用户名和邮箱
	elif [ $# -eq 2 ] && [[ "$1" == "setperson" ]];then
		case "$2" in 
			"stevxxxx")
				/usr/bin/git config --local user.name stevxxxx
				/usr/bin/git config --local user.email stevxxxx@gmail.com
				echo -e "current repo username and email set to User: stevxxxx"
			;;
			"hexxxxx")
				/usr/bin/git config --local user.name userabc
				/usr/bin/git config --local user.email userabc@gmail.com
				echo -e "current repo username and email set to User: userabc"
			;;
			*)
			#:
			echo -e "Nothing to do..."
			;;
		esac
	else
		/v/bin/git2 $@
	fi
}


附:其他依赖的脚本代码:
/v/bin/git.sh:

#!/bin/bash
 
# The MIT License (MIT)
# Copyright (c) 2013 Alvin Abad
 
if [ $# -eq 0 ]; then
    echo "Git wrapper script that can specify an ssh-key file
Usage:
    git.sh -i ssh-key-file git-command
    "
    exit 1
fi
 
# remove temporary file on exit
trap 'rm -f /tmp/.git_ssh.$$' 0
 
if [ "$1" = "-i" ]; then
    SSH_KEY=$2; shift; shift
    echo "ssh -i $SSH_KEY \$@" > /tmp/.git_ssh.$$
    chmod +x /tmp/.git_ssh.$$
    export GIT_SSH=/tmp/.git_ssh.$$
fi
 
# in case the git command is repeated
[ "$1" = "git" ] && shift
 
# Run the git command
#git "$@"

# =========================================
	
## add by lonelyer@20210216
## 针对stevingking名下仓库,push/commit 之前检查用户名邮箱是否配置正确
[ -e /v/bin/git-stevxxxx-dir.sh ] && source /v/bin/git-stevxxxx-dir.sh
	
## modify by lonelyer@20210204
## 修改git外部执行进程为 /v/bin/git2,取代默认/usr/bin/git,以便于自动使用代理
/v/bin/git2 "$@"
#bash -x /v/bin/git2 "$@" # for debug git2

/v/bin/git2:

#!/bin/bash
## 自动检测是否需要代理环境,并应用
## 代理开启的情况下,使用代理环境变量执行后续git命令
PROXY_ARGS=""
SSH_PROXY=""
IS_GITHUB=0
GITBIN=/usr/bin/git
##是否含有github.com的国外网站域名,仅当克隆国外仓库时使用代理
if [[ $* =~ "github.com" || $* =~ "gitlab.com" || $* =~ "bitbucket.org" ]];then
IS_GITHUB=1
fi

## 判断pull或push的时候是否需要使用代理
if [ ${IS_GITHUB} -eq 0 ] && [[ ! $* =~ ( -h| --help)$ ]] && [[ "$*" =~ ^(.*[ ]+)?(push|pull)([ ]+.*)?$ ]] && [[ $($GITBIN remote -v 2>/dev/null|grep -iE '(github\.com|gitlab\.com|bitbucket\.org)' &>/dev/null&&echo -n "yes") ==  "yes" ]];then
#echo "仓库对了"
IS_GITHUB=1
fi

## ping 检测软路由,看自己是否在家
#ping -w 1 -W 1 -c 1 10.10.10.254 &>/dev/null
## 如果ping不通,且访问的是国外git网址,才进行代理测试
## $GIT_FORCE_PROXY:是否强制GIT使用代理,可以在当前Shell中export GIT_FORCE_PROXY=true表明git强制使用代理
if [ ! -z "$GIT_FORCE_PROXY" ] || ([ ${IS_GITHUB} -eq 1 ] && [[ $(ping -w 1 -W 1 -c 1 10.10.10.254 &>/dev/null||echo "false") == false ]]);
then  
	if [[ "$GIT_FORCE_PROXY" =~ ([0-9]{1,3}\.){3}[0-9]{1,3}:[0-9]{2,5} ]]; # $GIT_FORCE_PROXY 指定了代理地址的情况
	then
		_git_ProxyType="socks5://"
		[[ "$GIT_FORCE_PROXY" =~ ^http:// ]] && _git_ProxyType="http://"
		declare -a _git_Proxy
		_git_Proxy=($(echo "$GIT_FORCE_PROXY"|awk -F ':' '{gsub(/(http|socks5):\/\/|\/$/,"");printf $1" "$2;}'))
		nc -v -w 1 ${_git_Proxy[0]} ${_git_Proxy[1]} >/dev/null 2>&1
		if [ $? -ne 0 ];then
			echo -e "$GIT_FORCE_PROXY 代理端口测试失败,中断后续操作...!"
			exit 1
		fi
		echo -e "当前 Git 使用代理 ${_git_ProxyType}${_git_Proxy[0]}:${_git_Proxy[1]} ..."
		if [[ "${_git_ProxyType,,}" == "socks5://" ]];then
			# socks 代理识别:
			PROXY_ARGS="env HTTPS_PROXY=socks5://${_git_Proxy[0]}:${_git_Proxy[1]}/"
			SSH_PROXY="ProxyCommand nc -X 5 -x ${_git_Proxy[0]}:${_git_Proxy[1]} %h %p"
		else
			# http 代理识别:
			PROXY_ARGS="env HTTPS_PROXY=http://${_git_Proxy[0]}:${_git_Proxy[1]}/"
			SSH_PROXY="ProxyCommand connect-proxy -H ${_git_Proxy[0]}:${_git_Proxy[1]} %h %p"
		fi
	else
		#请注意nc命令端口号后面重定向符号前面的空格,必须
		nc -v -w 1 127.0.0.1 1080 >/dev/null 2>&1
		if [ $IS_GITHUB -eq 1 -a $? -eq 0 ];then 
			PROXY_ARGS="env HTTPS_PROXY=socks5://127.0.0.1:1080/"
			SSH_PROXY="ProxyCommand nc -X 5 -x 127.0.0.1:1080 %h %p"
		else
			nc -v -w 1 127.0.0.1 1082 >/dev/null 2>&1
			if [ $IS_GITHUB -eq 1 -a $? -eq 0 ];then
				PROXY_ARGS="env HTTPS_PROXY=socks5://127.0.0.1:1082/"
				#PROXY_ARGS="HTTPS_PROXY=socks5://127.0.0.1:1082/"
				SSH_PROXY="ProxyCommand nc -X 5 -x 127.0.0.1:1082 %h %p"
			fi
		fi
	fi
fi
#echo $PROXY_ARGS
#$PROXY_ARGS git $*
OLD_IFS=$IFS
IFS=$(echo -e "\n")
if [ ! -z "$SSH_PROXY" -a -f "$GIT_SSH" ];then
	sed -i "s/\$@/-o \"${SSH_PROXY}\" \$@/" $GIT_SSH
elif [ ! -z "$SSH_PROXY" ];then
	[ ! -z "$PROXY_ARGS" ] && PROXY_ARGS="${PROXY_ARGS} GIT_SSH_COMMAND=\"/usr/bin/ssh -o \\\"${SSH_PROXY}\\\"\""
	#[ ! -z "$PROXY_ARGS" ] && PROXY_ARGS="${PROXY_ARGS} GIT_SSH_COMMAND=\"/usr/bin/ssh -i ~/.ssh/github_stevxxxx -o \\\"${SSH_PROXY}\\\"\""
fi

# test echo git_ssh
#echo $GIT_SSH
#[ -f "$GIT_SSH" ] && cat $GIT_SSH

## echo test command
#echo $PROXY_ARGS $GITBIN $@
#$PROXY_ARGS $GITBIN $@
eval $PROXY_ARGS $GITBIN $@
IFS=$OLD_IFS

#####################################
### 另:Git设置代理的备用方法
:<<EOF
git config --global http.proxy http://127.0.0.1:1080
git config --global https.proxy https://127.0.0.1:1080

git config --global --unset http.proxy
git config --global --unset https.proxy
--------------------

git config --global http.proxy 'socks5://127.0.0.1:1080'
git config --global https.proxy 'socks5://127.0.0.1:1080'

--------------------
只对github.com
git config --global http.https://github.com.proxy socks5://127.0.0.1:1080

#取消代理
git config --global --unset http.https://github.com.proxy)

----------------
# 如果你的代理走的是sock5 用这个
export ALL_PROXY=socks5://127.0.0.1:1080
或者

# 如果你的代理走的是http 用这个
export ALL_PROXY=http://127.0.0.1:1080

----------------
参考1:https://gist.github.com/evantoli/f8c23a37eb3558ab8765
参考2:https://gist.github.com/laispace/666dd7b27e9116faece6
参考3:https://www.google.com/search?newwindow=1&sxsrf=ALeKk015KzJ8woZnlyvv3MFtJuEQzf_E1A%3A1612373340339&ei=XN0aYMSPFI-U0PEPquOF8A8&q=git+use+proxy&oq=git+use+proxy&gs_lcp=CgZwc3ktYWIQAzICCAAyAggAMgIIADICCAAyAggAMgQIABAeMgQIABAeMgQIABAeMgYIABAFEB4yBggAEAUQHjoECAAQQ1D9ibEDWO2fsQNghaOxA2gAcAF4AIAB6QmIAYAhkgEJMi05LjYtMS4xmAEAoAEBqgEHZ3dzLXdpesABAQ&sclient=psy-ab&ved=0ahUKEwjErcjhns7uAhUPCjQIHapxAf4Q4dUDCA0&uact=5
EOF


/v/bin/git-stevxxxx-dir.sh:

#/usr/bin/bash
#针对stevxxxx名下仓库,push/commit前检查用户名,如果不是stevxxxx则设为stevxxxx

GIT=/usr/bin/git

if [[ "${*,,}" =~ ^(push|commit)(\ .*)?$ ]];
then
	gitRInfo=$($GIT remote -v)
	if [ ! -z "$gitRInfo" ] && [[ "$gitRInfo" =~ "stevxxxx" ]];
	then
		gitUInfo=$($GIT config --get-regexp ^user|tail -n 2)
		if [[ ! "$gitUInfo" =~ "stevxxxx" ]];
		then
			echo "Set Commit user to stevxxxx..."
			$GIT config --local user.name stevxxxx
			$GIT config --local user.email stevxxxx@gmail.com
		fi
	fi
fi
posted @ 2021-11-17 09:32  晴云孤魂  阅读(133)  评论(0编辑  收藏  举报