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
本文来自博客园,作者:晴云孤魂,转载请注明原文链接:https://www.cnblogs.com/cnhack/p/15565753.html