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

问题描述 投票:629回答:20

在我的~/.gitconfig中,我在[user]下列出了我的个人电子邮件地址,因为这是我想用于Github repos的内容。

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

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

git git-config
20个回答
888
投票

您可以将单个仓库配置为使用覆盖全局配置的特定用户/电子邮件地址。从repo的根目录开始运行

git config user.name "Your Name Here"
git config user.email [email protected]

而在〜/ .gitconfig中配置默认​​用户/电子邮件

git config --global user.name "Your Name Here"
git config --global user.email [email protected]

9
投票

git别名(以及git configs中的部分)来救援!

添加别名(从命令行):

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 [email protected]

在新的或克隆的仓库中,您可以运行此命令:

git identity github

此解决方案不是自动的,但是在全局~/.gitconfig中设置用户和电子邮件并将user.useConfigOnly设置为true会强制git提醒您在每个新的或克隆的repo中手动设置它们。

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

7
投票

这个答案部分受到了@Saucier的帖子的启发,但我正在寻找一种基于遥控器的每个回购设置user.nameuser.email的自动方式,这比git-passport包重量轻一点。他发展了。 h / t @John用于useConfigOnly设置。这是我的解决方案:

.gitconfig变化:

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

结帐后hook应该保存到以下路径:~/.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使用不同的凭据,但上面代码中的那些引用可以使用您使用的任何服务进行替换或扩充。为了让post-checkout挂钩在结账后自动在本地为回购设置用户名和电子邮件,确保服务名称出现在远程URL中,将其添加到post-checkout脚本中的services数组并为其创建一个部分在您的.gitconfig中,其中包含您的用户名和该服务的电子邮件。

如果远程URL中没有显示任何服务名称,或者repo没有远程服务器,则不会在本地设置用户名和电子邮件。在这些情况下,user.useConfigOnly设置将处于播放状态,在用户名和电子邮件设置为repo级别之前,将不允许您进行提交,并将提示用户配置该信息。


5
投票

GIT_AUTHOR_EMAIL +当地的.bashrc

.bashrc_local:不要跟踪此文件,只将其放在您的工作计算机上:

export GIT_AUTHOR_EMAIL='[email protected]'
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"

.bashrc:跟踪此文件,在工作和家庭计算机上使其相同:

F="$HOME/.bashrc_local"
if [ -r "$F" ]; then
    . "$F"
fi

我正在使用https://github.com/technicalpickles/homesick同步我的dotfiles。

如果只有gitconfig接受环境变量:Shell variable expansion in git config


4
投票

Windows环境

如果你在系统中安装了它,可以从Git Extensions --> Settings --> Global Settings修改其他内容。

gitextensions-latest-release

右键单击Windows环境中的文件夹/目录以访问这些设置。

更新:如何在版本2.49 How to switch/maintain multiple settings in Version 2.49中切换/维护多个设置


4
投票

以下是我在这里按照许多答案中的步骤后发现的内容

如何为不同的github帐户设置多个SSH密钥设置

您可能想要开始检查当前保存的密钥

$ ssh-add -l

如果您决定之前删除所有缓存键(可选,请注意)

$ ssh-add -D

然后,您可以创建一个链接到您希望/需要使用的每个电子邮件/帐户的ssh pub / priv密钥

$ cd ~/.ssh
$ ssh-keygen -t rsa -C "[email protected]" <-- save it as "id_rsa_work"
$ ssh-keygen -t rsa -C "[email protected]" <-- save it as "id_rsa_pers"

执行此命令后,您将创建以下文件

~/.ssh/id_rsa_work      
~/.ssh/id_rsa_work.pub

~/.ssh/id_rsa_pers
~/.ssh/id_rsa_pers.pub 

确保身份验证代理正在运行

$ eval `ssh-agent -s`

添加生成的密钥如下(从〜/ .ssh文件夹)

$ ssh-add id_rsa_work
$ ssh-add id_rsa_pers

现在,您可以再次检查已保存的密钥

$ ssh-add -l

现在,您需要将生成的公钥添加到您的github / bitbucket服务器访问密钥

将每个repos克隆到不同的文件夹

转到用户工作将在其中工作的文件夹并执行此操作

$ git config user.name "Working Hard"
$ git config user.email "[email protected]" 

只是看看这是什么检查“.git / config”的内容

转到用户pers将工作的文件夹并执行此操作

$ git config user.name "Personal Account"
$ git config user.email "[email protected]" 

只是看看这是什么检查“.git / config”的内容

毕竟,只需在这两个文件夹之间切换,您就可以提交个人和工作代码


3
投票

也许这是一个简单的黑客,但它很有用。只需生成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 [email protected]
The key's randomart image is:
+---[RSA 4096]----+
|. .oEo+=o+.      |
|.o o+o.o=        |
|o o o.o. +       |
| =.+ .  =        |
|= *+.   S.       |
|o*.++o .         |
|=.oo.+.          |
| +. +.           |
|.o=+.            |
+----[SHA256]-----+

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

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

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

同样,使用以下内容创建一个名为prev.sh(Personal Reverse)的名称。

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,请将其用于其中一个帐户。将它们作为个人复制并跳过生成个人密钥。


1
投票

我做了一个处理它的bash函数。 Here is the Github repo

记录:

# Look for closest .gitconfig file in parent directories
# This file will be used as main .gitconfig file.
function __recursive_gitconfig_git {
    gitconfig_file=$(__recursive_gitconfig_closest)
    if [ "$gitconfig_file" != '' ]; then
        home="$(dirname $gitconfig_file)/"
        HOME=$home /usr/bin/git "$@"
    else
        /usr/bin/git "$@"
    fi
}

# Look for closest .gitconfig file in parents directories
function __recursive_gitconfig_closest {
    slashes=${PWD//[^\/]/}
    directory="$PWD"
    for (( n=${#slashes}; n>0; --n ))
    do
        test -e "$directory/.gitconfig" && echo "$directory/.gitconfig" && return 
        directory="$directory/.."
    done
}


alias git='__recursive_gitconfig_git'

1
投票

只需将其添加到〜/ .bash_profile即可在github.com的默认密钥之间切换

# Git SSH keys swap
alias work_git="ssh-add -D  && ssh-add -K ~/.ssh/id_rsa_work"
alias personal_git="ssh-add -D && ssh-add -K ~/.ssh/id_rsa"

0
投票

类似于Rob W's answer,但允许不同的ssh密钥,并使用较旧的git版本(没有例如core.sshCommand配置)。

我创建了具有可执行权限的文件~/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="[email protected]" $@

每当我想提交或推送“高级用户”时,我使用git_poweruser而不是git。它应该适用于任何目录,并且不需要更改.gitconfig.ssh/config,至少不在我的。


0
投票

尽管大多数问题都是对OP的回答,但我只需要自己解决这个问题,甚至没有谷歌搜索,我能够找到最快捷,最简单的解决方案。这是一个简单的步骤:

  • 从您的其他回购中复制现有的.gitconfg
  • 粘贴到新添加的仓库中
  • 更改.gitconfig文件中的值,例如姓名,电子邮件和用户名 [user] name = John email = [email protected] username = john133
  • 将文件名添加到.gitignore列表,以确保您不将.gitconfig文件提交到您的工作回购

347
投票

从git 2.13开始,可以使用新引入的Conditional includes来解决这个问题。

一个例子:

全局配置〜/ .gitconfig

[user]
    name = John Doe
    email = [email protected]

[includeIf "gitdir:~/work/"]
    path = ~/work/.gitconfig

特定于工作的配置〜/ work / .gitconfig

[user]
    email = [email protected]

0
投票

您还可以在回购中使用git commit --author "Your Name <[email protected]>",以便在其中以不同的用户身份提交。


103
投票

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

[user]  
    name = Your Name
    email = [email protected]

39
投票

Orr Sella's blog post获得一些灵感后,我写了一个预提交钩子(位于~/.git/templates/hooks),它将根据本地存储库的./.git/config中的信息设置特定的用户名和电子邮件地址:

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

[init]
    templatedir = ~/.git/templates

然后每个git initgit clone将获取该钩子并将在下一个git commit中应用用户数据。如果你想将钩子应用到已经存在的repos,那么只需在repo中运行一个git init就可以重新初始化它。

这是我提出的钩子(它仍然需要一些抛光 - 欢迎提出建议)。保存为

~/.git/templates/hooks/pre_commit

要么

~/.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)。此外,还可以在配置文件(~/.gitpassport)中定义任意数量的ID,这些ID可在提示中选择。你可以在github.com找到这个项目:git-passport - A Git command and hook written in Python to manage multiple Git accounts / user identities


39
投票

一个命令github帐户切换

此解决方案采用单个git别名的形式。执行后,当前项目用户将被附加到另一个帐户

生成ssh密钥

ssh-keygen -t rsa -C "[email protected]" -f '/Users/arnaudrinquin/.ssh/id_rsa'

[...]

ssh-keygen -t rsa -C "[email protected]" -f '/Users/arnaudrinquin/.ssh/id_rsa_pro'

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

  1. 复制默认公钥pbcopy < ~/.ssh/id_rsa.pub
  2. 登录您的GitHub帐户
  3. 将密钥粘贴到add SSH key github页面中
  4. 复制其他公钥pbcopy < ~/.ssh/id_rsa_pro.pub
  5. 为每个其他帐户重复并调整步骤2到4

步骤1.自动ssh键切换。

我们可以配置ssh根据host发送使用特定的加密密钥。好的是,你可以为同一个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远程配置

您现在可以通过[email protected]更改git@github_pro在git遥控器中使用这些别名。

您可以更改现有的项目遥控器(使用git remote set-url origin git@github_pro:foo/bar.git之类的东西),也可以在克隆它们时直接调整它们。

git clone [email protected]:ArnaudRinquin/atom-zentabs.git

使用别名,它变成:

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

步骤2.更改git user.email

Git配置设置可以是全局的,也可以是每个项目。在我们的例子中,我们想要每个项目设置。它很容易改变它:

git config user.email '[email protected]'

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

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

[user]
    name = Arnaud Rinquin
    email = [email protected]

...

[alias]
    setpromail = "config user.email '[email protected]'"

然后,我们所要做的就是git setpromail只为这个项目更改了我们的电子邮件。

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

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

  • 将当前项目遥控器更改为所选的别名
  • 更改当前项目user.email配置

我们已经有第二步的一个命令解决方案,但第一步更难。一个命令远程主机更改

这里有另一个git alias命令形式的解决方案,可以添加到你的~/.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  [email protected]:ArnaudRinquin/arnaudrinquin.github.io.git (fetch)
origin  [email protected]: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 '[email protected]'"
  gopro = !sh -c \"git changeremotehost github.com github_pro && git changeremotehost bitbucket.com bitbucket_pro && git setpromail\"

Source Link -Tutorial


24
投票

如果您不想拥有默认电子邮件地址(email address links to a github user),则可以配置您想要询问的地址。如何做到这一点取决于你使用的git版本,见下文。

(预期)缺点是您必须为每个存储库配置一次您的电子邮件地址(和您的姓名)。所以,你不能忘记这样做。

版本<2.7.0

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

在您的全球配置~/.gitconfig中,如Dan Aloni在Orr Sella's blog post的评论中所述。当尝试在存储库中进行第一次提交时,git失败并显示以下消息:

*** Please tell me who you are.

Run

  git config --global user.email "[email protected]"
  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)')

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

2.7.0≤版本<2.8.0

版本<2.7.0中的行为不是用2.7.0修复的。你仍然可以使用Orr Sella's blog post中描述的预提交钩子。此解决方案也适用于其他版本,但其他解决方案不适用于此版本。

版本≥2.8.0

Dan Aloni added是实现这种行为的一种选择(参见release notes)。使用它:

[user]
    useConfigOnly = true

为了使其工作,您可能不会在全局配置中提供名称或电子邮件地址。然后,在第一次提交时,您会收到一条错误消息

fatal: user.useConfigOnly set but no name given

因此消息不是很有启发性,但是由于您明确设置了选项,因此您应该知道该怎么做。与版本<2.7.0的解决方案相比,您始终必须手动设置名称和电子邮件。


17
投票

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

例如,通过定义别名:

alias git='/usr/bin/git -c user.name="Your name" -c user.email="[email protected]"'

要查看它是否有效,只需键入git config user.email

$ git config user.email
[email protected]

您也可以在git中添加自定义$PATH可执行文件,而不是别名。

#!/bin/sh
/usr/bin/git -c user.name="Your name" -c user.email="[email protected]" "$@"

这些方法优于特定于存储库的.git/config的一个优点是,当自定义git程序处于活动状态时,它适用于每个git存储库。通过这种方式,您可以轻松地在用户/名称之间切换,而无需修改任何(共享)配置。


15
投票

使用Git 2.13中的conditional includes,现在可以在一台机器上共存多个用户/电子邮件而几乎没有工作。

user.gitconfig有我的个人姓名和电子邮件。 work-user.gitconfig有我的工作名称和电子邮件。这两个文件都在~路径。

所以我的个人姓名/电子邮件默认适用。对于c:/work/目录,我的工作名称/电子邮件已应用。对于c:/work/github/目录,我的个人姓名/电子邮件将被应用。这适用于应用的最后一个设置。

# ~/.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的任何目录应用条件包含。


9
投票

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

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

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

alias ggmail='git config user.name "My Name";git config user.email [email protected]'
alias gwork='git config user.name "My Name";git config user.email [email protected]'
© www.soinside.com 2019 - 2024. All rights reserved.