劫持Git命令
在个人配置文件(~/.bash_profile
或~/.bashrc
)中新建一个名为git
的函数,注意,此处函数名称必须为git
,这样在终端执行git命令时,才会优先调用我们定义好的Bash函数,而不是去调用git可执行文件;
Git同名劫持函数代码:
git() {
if [ $# -gt 1 ] && [[ "$1" == "-i" ]];then
/v/bin/git.sh "$@"
return
fi
/usr/bin/git "$@"
}
调用git命令时,默认读取~/.ssh/config
文件中配置的对应密钥,你也可以使用-i
选项为Git命令指定一个独立的密钥,比如使用以下命令使用git命令克隆你小号的私有仓库:
#-i 指定密钥路径,注意仓库地址要使用ssh协议,如果你使用https协议,此文介绍的操作纯属多余。你直接使用账号和密码即可;
git -i ~/.ssh/seconds_account clone [email protected]:useraaa/private-repo.git
注:因本人自建的可执行脚本与第三方可执行文件均保存在
/v/bin/
目录下,如果你的实际情况不同,你修改对应的路径以适配你自己的情况!
文件 /v/bin/git.sh 脚本代码:
#!/bin/bash
#文件名:/v/bin/git.sh
#劫持git命令,以便使用独立的SSH密钥(不使用.git/config中配置)访问Git仓库
#适用于同一平台有多个账户的情况(比如你有两个Github账户)
#其中的/v/bin/git2为另一个
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 "$@"
## 修改git外部执行进程为 /v/bin/git2,取代默认/usr/bin/git,以便于自动使用代理
/v/bin/git2 "$@"
文件 /v/bin/git2 脚本代码:
#!/bin/bash
#文件名:/v/bin/git2
## 自动检测是否需要代理环境,并应用
## 代理开启的情况下,使用代理环境变量执行后续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_stevingking -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 $@
gitOptions=( )
while [ $# -gt 0 ]; #循环处理参数,对非选项参数外加双引号包裹,以便兼容commit内容包含空格的情况
do
case "$1" in
-*)
gitOptions=(${gitOptions[@]} $1)
;;
*)
gitOptions=(${gitOptions[@]} \"$1\")
;;
esac
shift
done
#set -x
eval $PROXY_ARGS $GITBIN ${gitOptions[*]} # <--- 此处使用经过处理的$@参数,便于兼容参数中包含空格的情况;eg:git commit -m "This Commit Include Some Space information"
#eval $PROXY_ARGS $GITBIN $@
#$PROXY_ARGS $GITBIN $@ # <--- 此行会兼容commit内容有空格的情况,但是无法加载环境变量,XXX=ABC这样的环境变量赋值形式只在交互式环境中生效
#set +x
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
标签:bin,GIT,git,ARGS,PROXY,Git,SSH,bash,密钥
From: https://www.cnblogs.com/cnhack/p/17003617.html