在我的~/。gitconfig,我列出我的个人电子邮件地址下[用户],因为这是我想用于Github回购。
但是,我最近也开始在工作中使用git。我公司的git回购允许我提交,但是当它发出新的变更集通知时,它说它们来自匿名,因为它不识别我的.gitconfig中的电子邮件地址——至少,这是我的理论。
是否可以在.gitconfig中指定多个[用户]定义?或者是否有其他方法覆盖特定目录的默认.gitconfig ?在我的情况下,我检查了~/worksrc/中的所有工作代码-是否有一种方法只为该目录(及其子目录)指定.gitconfig ?
从Orr Sella的博客文章中得到一些灵感后,我写了一个预提交钩子(驻留在~/.git/templates/hooks中),它会根据本地存储库的。/.git/config中的信息设置特定的用户名和电子邮件地址:
你必须把模板目录的路径放到~/.gitconfig中:
[init]
templatedir = ~/.git/templates
然后,每个git init或git克隆都将获得该钩子,并在下一次git提交期间应用用户数据。如果你想将钩子应用到已经存在的repo上,那么只需在repo中运行git init来重新初始化它。
这是我想出的钩子(它仍然需要一些抛光-欢迎提出建议)。
另存为
~/.git/templates/hooks/pre_commit
or
~/.git/templates/hooks/post-checkout
并确保它是可执行的:chmod +x ./post-checkout || chmod +x ./pre_commit
#!/usr/bin/env bash
# -------- USER CONFIG
# Patterns to match a repo's "remote.origin.url" - beginning portion of the hostname
git_remotes[0]="Github"
git_remotes[1]="Gitlab"
# Adjust names and e-mail addresses
local_id_0[0]="my_name_0"
local_id_0[1]="my_email_0"
local_id_1[0]="my_name_1"
local_id_1[1]="my_email_1"
local_fallback_id[0]="${local_id_0[0]}"
local_fallback_id[1]="${local_id_0[1]}"
# -------- FUNCTIONS
setIdentity()
{
local current_id local_id
current_id[0]="$(git config --get --local user.name)"
current_id[1]="$(git config --get --local user.email)"
local_id=("$@")
if [[ "${current_id[0]}" == "${local_id[0]}" &&
"${current_id[1]}" == "${local_id[1]}" ]]; then
printf " Local identity is:\n"
printf "» User: %s\n» Mail: %s\n\n" "${current_id[@]}"
else
printf "» User: %s\n» Mail: %s\n\n" "${local_id[@]}"
git config --local user.name "${local_id[0]}"
git config --local user.email "${local_id[1]}"
fi
return 0
}
# -------- IMPLEMENTATION
current_remote_url="$(git config --get --local remote.origin.url)"
if [[ "$current_remote_url" ]]; then
for service in "${git_remotes[@]}"; do
# Disable case sensitivity for regex matching
shopt -s nocasematch
if [[ "$current_remote_url" =~ $service ]]; then
case "$service" in
"${git_remotes[0]}" )
printf "\n»» An Intermission\n» %s repository found." "${git_remotes[0]}"
setIdentity "${local_id_0[@]}"
exit 0
;;
"${git_remotes[1]}" )
printf "\n»» An Intermission\n» %s repository found." "${git_remotes[1]}"
setIdentity "${local_id_1[@]}"
exit 0
;;
* )
printf "\n» pre-commit hook: unknown error\n» Quitting.\n"
exit 1
;;
esac
fi
done
else
printf "\n»» An Intermission\n» No remote repository set. Using local fallback identity:\n"
printf "» User: %s\n» Mail: %s\n\n" "${local_fallback_id[@]}"
# Get the user's attention for a second
sleep 1
git config --local user.name "${local_fallback_id[0]}"
git config --local user.email "${local_fallback_id[1]}"
fi
exit 0
编辑:
因此,我将钩子重写为Python中的钩子和命令。此外,还可以将脚本作为Git命令(Git passport)调用。此外,还可以在configfile (~/.gitpassport)中定义任意数量的id,这些id可以在提示符中选择。你可以在github.com上找到这个项目:Git -passport -一个用Python编写的Git命令和钩子,用于管理多个Git帐户/用户身份。
让git使用多个名称/电子邮件的另一个选项是通过别名git并使用-c标志来覆盖全局和特定于存储库的配置。
例如,通过定义别名:
alias git='/usr/bin/git -c user.name="Your name" -c user.email="name@example.com"'
要查看它是否有效,只需输入git config user.email:
$ git config user.email
name@example.com
你也可以在$PATH中放置一个自定义的git可执行文件,而不是一个别名。
#!/bin/sh
/usr/bin/git -c user.name="Your name" -c user.email="name@example.com" "$@"
这些方法相对于特定于存储库的.git/config的优点是,当自定义git程序处于活动状态时,它适用于每个git存储库。通过这种方式,您可以轻松地在用户/名称之间切换,而无需修改任何(共享的)配置。
可以有多种方法来做到这一点,但我通过下面的shell函数来实现这一点。
function gitprofile() {
if [[ $1 == "private" ]]; then
if grep -q "tom@workmail.com" "/Users/tomtaylor/.gitconfig"; then
echo "Found in gitconfig. No action required."
else
echo "Found in gitconfig1"
cp /Users/tomtaylor/.gitconfig /Users/tomtaylor/.gitconfig2
mv /Users/tomtaylor/.gitconfig1 /Users/tomtaylor/.gitconfig
mv /Users/tomtaylor/.gitconfig2 /Users/tomtaylor/.gitconfig1
fi
elif [[ $1 == "public" ]]; then
if grep -q "tom@gmail.com" "/Users/tomtaylor/.gitconfig"; then
echo "Found in gitconfig. No action required."
else
echo "Found in gitconfig1"
cp /Users/tomtaylor/.gitconfig /Users/tomtaylor/.gitconfig2
mv /Users/tomtaylor/.gitconfig1 /Users/tomtaylor/.gitconfig
mv /Users/tomtaylor/.gitconfig2 /Users/tomtaylor/.gitconfig1
fi
}
比如,
gitprofile "public" ->这将切换到配置tom@gmail.com和
gitprofile "private" ->这会切换到tom@workmail.com。
将此函数添加到~/。Bash_profile或~/。ZSHRC基于您当前的终端偏好。重新启动终端或像这样编译脚本
. ~ / . bash_profile
使函数有效。希望能有所帮助!
本地邮箱/邮箱/ bashrc
.bashrc_local:不要跟踪这个文件,只把它放在你的工作电脑上:
export GIT_AUTHOR_EMAIL='me@work.com'
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
.bashrc:跟踪这个文件,让它在工作电脑和家用电脑上都一样:
F="$HOME/.bashrc_local"
if [ -r "$F" ]; then
. "$F"
fi
我正在使用https://github.com/technicalpickles/homesick来同步我的dotfiles。
如果只有git配置可以接受环境变量:git配置中的Shell变量扩展
通过Git 2.13中的条件包含,现在可以在一台机器上用很少的工作同时拥有多个用户/电子邮件。
用户。Gitconfig有我的个人姓名和电子邮件。work-user。Gitconfig有我的工作名称和电子邮件。两个文件都位于~ path。
所以我的个人姓名/电子邮件默认适用。对于c:/work/ dir,应用的是我的工作名称/电子邮件。c:/work/github/ dir,应用我的个人姓名/邮箱。这在应用最后一个设置时起作用。
# ~/.gitconfig
[include]
path = user.gitconfig
[includeIf "gitdir/i:c:/work/"]
path = work-user.gitconfig
[includeIf "gitdir/i:c:/work/github/"]
path = user.gitconfig
Gitdir区分大小写,Gitdir /i不区分大小写。
"gitdir/i:github/"将对路径中包含github的任何目录应用条件包含。