我可以在.gitconfig中为自己指定多个用户吗?

在我的~/.gitconfig ,我在[user]下面列出了我的个人电子邮件地址,因为这是我想要用于Github回购站的。

但是,我最近也开始使用git来工作。 我公司的git repo允许我提交,但是当它发出新的变更集通知时,它说它来自匿名,因为它不能识别我的.gitconfig的电子邮件地址 – 至less,这是我的理论。

是否可以在.gitconfig指定多个[user]定义? 或者是有一些其他方式来覆盖某个目录的默认.gitconfig ? 在我的情况下,我检查~/worksrc/所有工作代码 – 是否有一种方法来指定一个.gitconfig只有该目录(及其子目录)?

您可以configuration单个回购以使用覆盖全局configuration的特定用户/电子邮件地址。 从回购的根源,运行

 git config user.name "Your Name Here" git config user.email your@email.com 

而默认的用户/电子邮件是在〜/ .gitconfig中configuration的

 git config --global user.name "Your Name Here" git config --global user.email your@email.com 

或者您可以在您的本地.git/config文件中添加以下信息

 [user] name = Your Name email = your.email@gmail.com 

既然git 2.13 ,可以使用新引入的条件包含来解决这个问题。

一个例子:

全局configuration〜/ .gitconfig

 [user] name = John Doe email = john@doe.tld [includeIf "gitdir:~/work/"] path = ~/work/.gitconfig 

工作特定的configuration〜/ work / .gitconfig

 [user] email = john.doe@company.tld 

从Orr Sella的博客文章中得到一些启发后,我写了一个预先提交的钩子(驻留在~/.git/templates/hooks ),根据本地存储库中的信息设置特定的用户名和电子邮件地址。 ./.git/config

您必须将模板目录的path放入您的~/.gitconfig

 [init] templatedir = ~/.git/templates 

然后每个git init或者git clone都会拿起这个钩子,并在下一个git commit应用这个用户数据。 如果你想把钩子应用到已经存在的仓库,那么只需在仓库中运行一个git init来重新初始化它。

这是我想出的钩子(它仍然需要一些抛光 – build议是受欢迎的)。 将它保存为

 ~/.git/templates/hooks/pre_commit 

要么

 ~/.git/templates/hooks/post-checkout 

并确保它是可执行的: chmod +x ./post-checkout || chmod +x ./pre_commit 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 )来调用。 也可以在configuration文件( ~/.gitpassport )中定义任意数量的ID,这些ID可以在提示符上select。 你可以在github.com上find这个项目: git-passport – 用Python编写的Git命令和钩子来pipe理多个Git账号/用户身份 。

如果你不想有一个默认的电子邮件地址( 电子邮件地址链接到一个github用户 ),你可以configuration,你想问。 你如何做到这一点取决于你使用的git版本,见下文。

(意图)的缺点是,您必须为每个存储库configuration一次您的电子邮件地址(和您的名字)。 所以,你不能忘记去做。

版本<2.7.0

 [user] name = Your name email = "(none)" 

在你的全局configuration~/.gitconfig ,在Orr Sella的博客文章中 Dan Aloni的评论中指出。 当试图在存储库中进行第一次提交时,git会失败并显示一条好消息:

 *** Please tell me who you are. Run git config --global user.email "you@example.com" git config --global user.name "Your Name" to set your account's default identity. Omit --global to set the identity only in this repository. fatal: unable to auto-detect email address (got '(none)') 

电子邮件地址在本地设置时,该名称取自全局configuration(消息不完全准确)。

2.7.0≤版本<2.8.0

版本<2.7.0中的行为不是打算使用2.7.0修复的。 您仍然可以使用Orr Sella的博客文章中所述的预先提交挂钩。 此解决scheme也适用于其他版本,但其他解决scheme不适用于此版本。

版本≥2.8.0

Dan Aloni添加了一个选项来实现这一行为(请参阅发行说明 )。 使用它:

 [user] useConfigOnly = true 

要使其工作,您可能不会在全局configuration中给出名称或电子邮件地址。 然后,在第一次提交时,您会收到错误消息

 fatal: user.useConfigOnly set but no name given 

所以这个消息不是很有启发性,但是由于你明确地设置了选项,你应该知道该怎么做。 与<2.7.0版本的解决scheme相反,您必须手动设置名称和电子邮件。

一个命令github账号切换

这个解决scheme采用单个git别名的forms。 一旦执行,当前项目用户将被附加到另一个帐户

生成ssh密钥

 ssh-keygen -t rsa -C "rinquin.arnaud@gmail.com" -f '/Users/arnaudrinquin/.ssh/id_rsa' [...] ssh-keygen -t rsa -C "arnaud.rinquin@wopata.com" -f '/Users/arnaudrinquin/.ssh/id_rsa_pro' 

将它们链接到您的GitHub / Bitbucket帐户

  1. 复制默认公钥pbcopy < ~/.ssh/id_rsa.pub
  2. login到你的GitHub账户
  3. 将该密钥粘贴到add SSH key github页面中
  4. 复制其他公钥pbcopy < ~/.ssh/id_rsa_pro.pub
  5. 重复和适应其他帐户的步骤2至4

第1步。自动SSH密钥切换。

我们可以configurationssh根据host发送一个特定的encryption密钥。 好的是你可以为同一个hostname拥有多个别名。

看到这个例子~/.ssh/config文件:

 # Default GitHub Host github.com HostName github.com User git IdentityFile ~/.ssh/id_rsa # Professional github alias Host github_pro HostName github.com User git IdentityFile ~/.ssh/id_rsa_pro 

git远程configuration

您现在可以通过git@github_pro更改git@github.com在git远程中使用这些别名。

你可以改变你现有的项目遥控器(使用类似git remote origin set-url git@github_pro:foo/bar.git ),或者在克隆它们时直接修改它们。

 git clone git@github.com:ArnaudRinquin/atom-zentabs.git 

使用别名,它变成:

git clone git@github_pro:ArnaudRinquin/atom-zentabs.git

第2步。更改git user.email

Gitconfiguration设置可以是全局或每个项目。 在我们的情况下,我们希望每个项目的设置。 改变它非常容易:

 git config user.email 'arnaud.rinquin@wopata.com' 

虽然这很容易,但是对于我们的开发人员来说,这需要很长的时间。 我们可以为此写一个非常简单的git别名。

我们将把它添加到~/.gitconfig文件中。

 [user] name = Arnaud Rinquin email = rinquin.arnaud@gmail.com ... [alias] setpromail = "config user.email 'arnaud.rinquin@wopata.com'" 

然后,我们所要做的就是git setpromail来让我们的电子邮件只针对这个项目进行更改。

第3步。请一个命令开关?!

使用单个无参数命令从默认帐户切换到指定的帐户不是很好吗? 这绝对是可能的。 这个命令将有两个步骤:

  • 将当前的项目远程更改为所选的别名
  • 改变当前的项目user.email config

第二步我们已经有了一个单一的命令解决scheme,但第一个解决scheme比较困难。 一个命令远程主机更改

解决scheme以另一个git alias命令的forms添加到~/.gitconfig

 [alias] changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\" 

这允许从一个主机到另一个(别名)的所有遥控器。 看例子:

 $ > git remote -v origin git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git (fetch) origin git@github.com:ArnaudRinquin/arnaudrinquin.github.io.git (push) $ > git changeremotehost github.com github_pro $ > git remote -v origin git@github_pro:ArnaudRinquin/arnaudrinquin.github.io.git (fetch) origin git@github_pro:ArnaudRinquin/arnaudrinquin.github.io.git (push) 

把他们全部结合起来

我们现在只需要将这两个命令合并为一个,这很容易。 看看我还如何整合bitbucket主机切换。

 [alias] changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\" setpromail = "config user.email 'arnaud.rinquin@wopata.com'" gopro = !sh -c \"git changeremotehost github.com github_pro && git changeremotehost bitbucket.com bitbucket_pro && git setpromail\" 

源链接 – 教程

git使用多个名称/电子邮件的另一个select是通过别名git并使用-c标志覆盖全局和特定于存储库的configuration。

例如,通过定义一个别名:

 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存储库。 这样,您可以轻松地在用户/名称之间切换,而无需修改任何(共享)configuration。

有一个简单的解决scheme似乎可以很好地避免错误。

只需从~/.gitconfig删除[user]部分,这将阻止你在没有为每个存储库设置user.name情况下进行任何提交。

~/.bashrc为用户和电子邮件添加一些简单的别名:

 alias ggmail='git config user.name "My Name";git config user.email me@gmail.com' alias gwork='git config user.name "My Name";git config user.email me@work.job' 

混帐别名(和部分在Gitconfiguration)的救援!

添加一个别名(从命令行):

 git config --global alias.identity '! git config user.name $(git config user.$1.name); git config user.email $(git config user.$1.email); :' 

然后,设置,例如

 git config --global user.github.name "your github username" git config --global user.github.email your@github.email 

并在一个新的或克隆的回购你可以运行这个命令:

 git identity github 

这个解决scheme不是自动的,但是在你的全局〜/ .gitconfig中设置用户和电子邮件将会强制git提醒你在每个新的或者克隆的repo中手动设置它们。

 git config --global --unset user.name git config --global --unset user.email 

GIT_AUTHOR_EMAIL +本地.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来同步我的点文件。;

如果只有gitconfig会接受环境variables: git config中的shellvariables扩展

这个答案部分来自于@Saucier的post,但是我正在寻找一种自动化的方式来设置user.nameuser.email ,基于远程,基于回购的基础上,这比git轻了一些 – 他开发的通行证包。 另外h / t为@John为useConfigOnly设置。 这是我的解决scheme:

.gitconfig更改:

 [github] name = <github username> email = <github email> [gitlab] name = <gitlab username> email = <gitlab email> [init] templatedir = ~/.git-templates [user] useConfigOnly = true 

post-checkout 挂钩应该保存到以下path: ~/.git-templates/hooks/post-checkout

 #!/usr/bin/env bash # make regex matching below case insensitive shopt -s nocasematch # values in the services array should have a corresponding section in # .gitconfig where the 'name' and 'email' for that service are specified remote_url="$( git config --get --local remote.origin.url )" services=( 'github' 'gitlab' ) set_local_user_config() { local service="${1}" local config="${2}" local service_config="$( git config --get ${service}.${config} )" local local_config="$( git config --get --local user.${config} )" if [[ "${local_config}" != "${service_config}" ]]; then git config --local "user.${config}" "${service_config}" echo "repo 'user.${config}' has been set to '${service_config}'" fi } # if remote_url doesn't contain the any of the values in the services # array the user name and email will remain unset and the # user.useConfigOnly = true setting in .gitconfig will prompt for those # credentials and prevent commits until they are defined for s in "${services[@]}"; do if [[ "${remote_url}" =~ "${s}" ]]; then set_local_user_config "${s}" 'name' set_local_user_config "${s}" 'email' break fi done 

我为github和gitlab使用了不同的证书,但是上面代码中的那些引用可以被你使用的任何服务replace或者扩充。 为了让签出后的钩子在签出后自动设置用户名和电子邮件地址作为回购请确保服务名称出现在远程URL中,将其添加到post-checkout脚本中的services数组中,并创build一个部分在你的.gitconfig中包含你的用户名和该服务的邮件。

如果没有服务名称出现在远程URL或回购没有远程用户名和电子邮件将不会在本地设置。 在这些情况下, user.useConfigOnly设置将在播放中,直到用户名和电子邮件设置为repo级别,才会允许您进行提交,并提示用户configuration该信息。

Windows环境

另外这个可以从Git Extensions --> Settings --> Global Settings ,如果你已经安装在你的系统中进行修改。

gitextensions -最新释放

右键单击Windows环境中的文件夹/目录以访问这些设置。 在这里输入图像说明

有了Git 2.13中的条件包含 ,现在可以在一台机器上同时存在多个用户/电子邮件,而且工作量很less。

user.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在其path。

可能是简单的黑客攻击,但它是有用的。 只需要像下面那样生成2个ssh密钥。

 Generating public/private rsa key pair. Enter file in which to save the key (/Users/GowthamSai/.ssh/id_rsa): work Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in damsn. Your public key has been saved in damsn.pub. The key fingerprint is: SHA256:CrsKDJWVVek5GTCqmq8/8RnwvAo1G6UOmQFbzddcoAY GowthamSai@Gowtham-MacBook-Air.local The key's randomart image is: +---[RSA 4096]----+ |. .oEo+=o+. | |.o o+oo= | |oo oo + | | =.+ . = | |= *+. S. | |o*.++o . | |=.oo.+. | | +. +. | |.o=+. | +----[SHA256]-----+ 

同样的方式创造一个更多的个人。 所以,你有2个密钥,工作和公司。 复制work.pub,work,personal.pub,个人到〜/ .ssh /目录。

然后使用以下命令创buildshell脚本,并将其命名为crev.sh(Company Reverse),其中包含以下内容。

 cp ~/.ssh/work ~/.ssh/id_rsa cp ~/.ssh/work.pub ~/.ssh/id_rsa.pub 

同样的方法,创build一个名为prev.sh(个人反向)以下内容。

 cp ~/.ssh/personal ~/.ssh/id_rsa cp ~/.ssh/personal.pub ~/.ssh/id_rsa.pub 

在〜/ .bashrc中为下面的脚本添加别名

 alias crev="sh ~/.ssh/crev.sh" alias prev="sh ~/.ssh/prev.sh" source ~/.bashrc 

当你想使用公司,只要做crev,如果你想用个人做prev :-p。

将这些ssh密钥添加到您的github帐户。 确保你没有id_rsa生成,因为这些脚本将覆盖id_rsa。 如果您已经生成了id_rsa,请将其用于其中一个帐户。 将它们复制为个人密钥并跳过生成个人密钥。

像Rob W的答案 ,但允许不同的SSH密钥,并与旧的GIT版本(它没有例如一个core.sshCommandconfiguration)。

我创build了具有可执行权限的文件~/bin/git_poweruser ,并在PATH中:

 #!/bin/bash TMPDIR=$(mktemp -d) trap 'rm -rf "$TMPDIR"' EXIT cat > $TMPDIR/ssh << 'EOF' #!/bin/bash ssh -i $HOME/.ssh/poweruserprivatekey $@ EOF chmod +x $TMPDIR/ssh export GIT_SSH=$TMPDIR/ssh git -c user.name="Power User name" -c user.email="power@user.email" $@ 

每当我想提交或推“Power User”,我使用git_poweruser而不是git 。 它应该在任何目录下工作,并且不需要在.gitconfig.ssh/config进行更改,至less不在我的。