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

Posted

技术标签:

【中文标题】我可以在 .gitconfig 中为自己指定多个用户吗?【英文标题】:Can I specify multiple users for myself in .gitconfig? 【发布时间】:2011-05-12 08:22:09 【问题描述】:

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

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

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

【问题讨论】:

见git-config#FILES。 我很惊讶您的公司服务器会这样做 - 它必须更改您提交的 sha 才能使其工作。如果您提交到本地结帐,您会看到什么用户名? @Alex:忘记了重要的一点——它很可能只是电子邮件通知上的一个名称,实际上并没有改变提交上的任何内容。 您可以使用 git-hook 自动执行此重复性工作:github.com/DrVanScott/git-clone-init 请接受这个答案:***.com/a/43654115/482899。这是自 git 2.13 以来的最佳解决方案。 【参考方案1】:

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

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

而默认用户/电子邮件是在您的 ~/.gitconfig 中配置的

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

【讨论】:

你可以在.git/config文件中看到这些设置的效果 您可以使用git config --editgit config --global --edit 手动编辑这些配置文件。如果您错过了 Abizern 的 comment,存储库的配置文件位于 <repo-root>/.git/config 您还应该取消设置 GIT_AUTHOR_EMAILGIT_COMMITTER_EMAIL(和 *_NAME),因为它们会覆盖本地设置 有没有办法对给定文件夹中的所有存储库执行此操作,而不是针对单个存储库?在这里查看我的问题:***.com/questions/21307793/… 查看this answer below 了解更多最新解决方案,Git 2.13 今天发布。【参考方案2】:

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

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

【讨论】:

...这是手动执行@discomurray 推荐的命令为您执行的操作。 每个遥控器可以添加多行吗?【参考方案3】:

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

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

[init]
    templatedir = ~/.git/templates

然后每个git initgit clone 将选择该钩子并在下一个git commit 期间应用用户数据。如果您想将钩子应用于已经存在的存储库,那么只需在存储库中运行 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。

【讨论】:

这很好用。但是,通过将其设置为结帐后(而不是提交后)挂钩,它对我来说效果更好。我改进这个答案的建议是,提一下:1. sn-p 需要保存为 ~/.git/templates/hooks/post-checkout 并获得权限chmod +x post-checkout, 2. git_remotes 值开始整个主机名的一部分,例如git@github.com, 3. local_id 值应由用户编辑为各自的姓名和电子邮件地址。 @ShantanuKumar 感谢您的评论。我按照您的建议调整了答案。也许我很快会用 Python 重写脚本。 增加了对正则表达式和没有遥控器的存储库的支持。为了方便下载所有合并的here。用于区分同一服务上不同项目的身份的正则表达式。并支持远程回购,例如如果您 git init 来自 IDE 的新项目,例如 eclipse(无法处理交互式预提交触发器),则默认标识是有意义的【参考方案4】:

Windows 环境

如果您的系统中安装了它,可以从 Git Extensions --> Settings --> Global Settings 进行修改。

gitextensions-latest-release

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

更新如何在 2.49 版本中切换/维护多个设置

【讨论】:

这如何处理多个用户,而不仅仅是编辑他们? @D_N 更新了带有切换设置选项的新屏幕截图。 打开本地 repo 文件夹并从导航菜单中选择 git-config 然后单击本地 repo 选项卡,内容将应用到 $local_repo_path/.git/config 如上答案。【参考方案5】:

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

【讨论】:

【参考方案6】:

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

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

版本
[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 "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)')

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

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

因此该消息不是很有指导意义,但是由于您明确设置了该选项,因此您应该知道该怎么做。与

【讨论】:

这个方法我用了几个月,效果很好。我有多个电子邮件地址(个人、工作),我不想在全局 gitconfig 中配置一个“默认”地址。使用特殊值 "(none)" 时,git 会在我每次启动一个新的 repo 时提示我提供一个有效地址,而不是根据用户名和主机名猜测一个(这很烦人,我需要 -- 修改它)。但是,最近随着 Git 的升级版本(2.7.0,可能更早),我发现特殊值“(无)”不再触发致命错误。相反,它只会使用“John Doe ”... @wzyboy:哦,你是对的。我使用git bisect 发现提交19ce497c... 引入了这种行为。但是,独立于版本(2.5 - 2.7),我可以在配置中使用email =(不带参数),它显示与旧版本中的email = "(none)" 相同的行为。你能证实这一点吗?如果是这样,我将编辑我的答案。我只是持怀疑态度,因为它看起来很明显,而且我以前没有使用过。 我在 2.7.0 中尝试过email =,Git 仍然根据用户名和主机名猜测电子邮件地址。我现在在 Sella 的博客中使用 pre-commit 方法。我还通知了在 Sella 的帖子中提出 "(none)" 想法的 Dan Aloni,他提交了一个补丁以正式将其作为一项功能实现:permalink.gmane.org/gmane.comp.version-control.git/285301 从 git-2.8 开始:“user.useConfigOnly”配置变量可用于强制用户始终设置 user.email & user.name github.com/git/git/blob/master/Documentation/RelNotes/2.8.0.txt @rofrol 感谢您的信息。我相应地更新了我的答案。【参考方案7】:

一个命令github账号切换

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

生成 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 帐户

    复制默认公钥pbcopy < ~/.ssh/id_rsa.pub 登录您的 GitHub 帐户 将密钥粘贴到add SSH key github页面中 复制其他公钥pbcopy < ~/.ssh/id_rsa_pro.pub 为所有其他帐户重复并调整步骤 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 远程配置

您现在可以通过将 git@github.com 更改为 git@github_pro 来在 git 遥控器中使用这些别名。

您可以更改现有项目的遥控器(使用类似git remote set-url origin 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

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

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 配置

我们已经为第二步提供了一个命令解决方案,但第一步要困难得多。 一个命令远程主机更改

解决方案以另一个 git 别名命令的形式添加到您的 ~/.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\"

Source Link -Github

Source Link -Tutorial

【讨论】:

这太棒了,谢谢。我在每封电子邮件中处理一堆 repos,所以我的 setpromail 别名改为 config --global(我还有其他设置的别名来设置不同的电子邮件地址)。它有效! 对于这 2 个不同的帐户,我如何使用不同的 gpg 密钥进行签名?我有 2 个 gpg 密钥用于 2 个 github 帐户,并且想以不同的方式签名。 "git config --global user.signingkey xxxx" 这个答案太棒了。我几乎没有读过它,因为我认为我从另一个答案中找到了什么。绝对值得更多的支持。 PS。与另一个答案中的useConfigOnly = true 结合使用会更好。 不是IdentifyFile,是IdenfityFile。 教程链接已失效。我在github.com/ArnaudRinquin/blog/blob/master/… 找到了它【参考方案8】:

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

只需从您的~/.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'

【讨论】:

不是很好,因为你会在每个 git repo 中复制配置【参考方案9】:

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 会接受环境变量:Shell variable expansion in git config

【讨论】:

【参考方案10】:

这个答案的部分灵感来自@Saucier 的帖子,但我一直在寻找一种基于遥控器在每个 repo 基础上自动设置 user.nameuser.email 的方法,重量更轻比他开发的 git-passport 包。对于 useConfigOnly 设置,也向@John 发送 h/t。这是我的解决方案:

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

如果远程 url 中没有出现任何服务名称,或者 repo 没有远程,则不会在本地设置用户名和电子邮件。在这些情况下,user.useConfigOnly 设置将发挥作用,在用户名和电子邮件设置在 repo 级别之前不允许您进行提交,并会提示用户配置该信息。

【讨论】:

很好的解决方案。不要忘记chmod 755钩子脚本。否则,它将被复制但从不执行。【参考方案11】:

也许这是一个简单的 hack,但它很有用。只需生成 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+o.o=        |
|o o o.o. +       |
| =.+ .  =        |
|= *+.   S.       |
|o*.++o .         |
|=.oo.+.          |
| +. +.           |
|.o=+.            |
+----[SHA256]-----+

以同样的方式为个人再创建一个。所以,你有 2 个 ssh 密钥,工作和公司。将 work.pub、work、personal.pub、personal 复制到 ~/.ssh/ 目录。

然后使用以下行创建一个 shell 脚本,并将其命名为 crev.sh(公司反向),内容如下。

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

以同样的方式,再创建一个名为 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,请将其用于其中一个帐户。将它们复制为个人并跳过个人密钥的生成。

【讨论】:

【参考方案12】:

git 别名(和 git 配置中的部分)来救援!

添加别名(从命令行):

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

在新的或克隆的 repo 中,您可以运行以下命令:

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

【讨论】:

我喜欢你的解决方案;但是,当我取消设置全局时,它只是使用我的计算机的主机名进行提交,而不是让 git 提醒我在任何给定的 repo 中设置它们:(【参考方案13】:

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

一个例子:

全局配置~/.gitconfig

[user]
    name = John Doe
    email = john@doe.tld

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

工作特定配置 ~/work/.gitconfig

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

请记住,[includeIf...] 应遵循顶部的默认 [user]

【讨论】:

现在 git 2.13 已经发布,这是最好的答案。 假设它们没有自己的 .gitconfig 文件,此解决方案是否适用于包含语句中指定的子目录中的所有子目录?我会这么认为,但到目前为止测试还没有证明这一点。 @Gary 是的,根据我的经验和文档:“如果模式以 / 结尾,将自动添加 **。例如,模式 foo/ 变为 foo/**。换句话说,它递归地匹配“foo”和里面的所有东西。”,“;包括 $HOME/to/group [includeIf "gitdir:~/to/group/"]" 中的所有存储库 gitdir 应该包含最后一个'/'。 您可以通过在不同目录中运行git config --list 来检查它是否递归工作。在包含 git 存储库的 ~/work/ 的子目录中,includeIf 生效。请注意,~/work/ 的不包含 git 存储库的子目录中,includeIf 不会执行。【参考方案14】:

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

【讨论】:

虽然您的回答很受赞赏,并且好 Tomáš Janoušek 在您之前给出了同样的 20 天。请考虑删除此答案。 @Hedge 是的,我赞成他的回答,但我花了一段时间在 Windows 上进行配置,这就是 gitdir/i 帮助我的地方(他的回答没有提到)。 @hIpPy 实现这一点的特殊方式直接应用于我的用例,并且比 Tomas 的回答更容易理解。我都投了赞成票。【参考方案15】:

类似于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="power@user.email" $@

每当我想以“超级用户”的身份提交或推送某些内容时,我都会使用git_poweruser 而不是git。它应该适用于任何目录,并且不需要更改.gitconfig.ssh/config,至少在我的目录中没有。

【讨论】:

【参考方案16】:

我制作了一个 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'

【讨论】:

【参考方案17】:

这里是阅读许多答案后的完整步骤

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

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

$ ssh-add -l

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

$ ssh-add -D

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

$ cd ~/.ssh
$ ssh-keygen -t rsa -C "work@company.com" <-- save it as "id_rsa_work"
$ ssh-keygen -t rsa -C "pers@email.com" <-- 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/bickbuket 服务器访问密钥

将每个存储库克隆到不同的文件夹

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

$ git config user.name "Working Hard"
$ git config user.email "work@company.com" 

只是为了看看这会检查“.git/config”的内容

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

$ git config user.name "Personal Account"
$ git config user.email "pers@email.com" 

只是为了看看这会检查“.git/config”的内容

在这一切之后,您只需在这两个文件夹之间切换即可提交您的个人和工作代码

如果您使用 Git Bash 并且需要在 Windows 下生成 ssh 密钥,请按照以下步骤操作:

https://support.automaticsync.com/hc/en-us/articles/202357115-Generating-an-SSH-Key-on-Windows

【讨论】:

【参考方案18】:

虽然大多数问题都在某种程度上回答了 OP,但我只需要自己解决这个问题,甚至不用谷歌搜索就能找到最快、最简单的解决方案。以下是简单的步骤:

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

【讨论】:

【参考方案19】:

只需将其添加到您的 ~/.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"

【讨论】:

【参考方案20】:

您还可以在您希望以其他用户身份提交的仓库中进行提交时使用git commit --author "Your Name &lt;your@email.com&gt;"

【讨论】:

【参考方案21】:

有多种方法可以做到这一点,但我是通过下面的 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
    else 
        echo "Nothing matched. Have some good sleep!"
    fi

像这样调用它,

gitprofile "public" -> 这将切换到带有tom@gmail.com 和的配置文件

gitprofile "private" -> 这将切换到tom@workmail.com

根据您当前的终端偏好将此函数添加到您的 ~/.bash_profile 或 ~/.zshrc 中。重启终端或者像这样编译脚本

。 ~/.bash_profile

使功能生效。希望对您有所帮助!

【讨论】:

【参考方案22】:

让我们重新定义规范 - 您只是希望能够通过 git 对不同的组织使用多个身份 - 您只需要 2 个 oneliner:

 # generate a new private public key pair for org1  
 email=me@org1.eu;ssh-keygen -t rsa -b 4096 -C $email -f $HOME/.ssh/id_rsa.$email

 # use org1 auth in THIS shell session - Ctrl + R, type org1 in new one 
 email=me@org1.eu;export GIT_SSH_COMMAND="ssh -p 22 -i ~/.ssh/id_rsa.$email"

为什么我知道这是迄今为止最简单的解决方案:

  # me using 9 different orgs with separate git auths dynamically
  find $HOME/.ssh/id_rsa.*@* | wc -l
  18

【讨论】:

您不能将相同的 SSH 密钥添加到多个 github 帐户【参考方案23】:

阅读完所有答案后,这就是我的解决方案:

场景:

本地操作系统:Linux (bash) GitHub 上的两个帐户(工作/个人) 使用不同的密钥进行 ssh 访问 我的工作帐户将是“主要”帐户(因此不需要自定义配置)

配置:

    设置一个 “假” 主机,它允许我选择正确的 SSH 密钥对。 在~/.ssh/config:
    # Personal GitHub account
    Host github-personal
      HostName github.com
      User git
      IdentityFile ~/.ssh/id_rsa_personal
      IdentitiesOnly yes
    
    “告诉” git 它应该在给定的目录子树中使用自定义配置: 在~/.gitconfig:
    # My personal projects
    [includeIf "gitdir/i:~/REPOS/PERSONAL/"]
       path = ~/REPOS/PERSONAL/personal.gitconfig
    
    
    最后,我在~/REPOS/PERSONAL/personal.gitconfig 的配置:
    # gitconfig for personal projects
    [user]
      email = personalemail@example.com
    
    [url "git@github-personal"]
      insteadOf = git@github.com
    

一旦上述三个都到位,我可以像这样克隆一个个人仓库:

user@host:~/REPOS/PERSONAL$ git clone git@github.com:jmnavarrol/python-multigit.git
Cloning in 'python-multigit'...
(...)
user@host:~/REPOS/PERSONAL$ cd python-multigit && git remote -v
origin  git@github-personal:jmnavarrol/python-multigit.git (fetch)
origin  git@github-personal:jmnavarrol/python-multigit.git (push)
user@host:~/REPOS/PERSONAL/python-multigit$

~/REPOS/PERSONAL/personal.gitconfig添加url重写...

[url "git@github-personal"]
  insteadOf = git@github.com

...是什么允许我仅通过脚本中的 “标准” URL 引用回购,子回购(即python-multigit itself 的情况@ -是的,有点蹩脚的自我尝试促销)而不冒使用“错误” URL 的风险,因此,错误的身份验证。

我的两分钱。

【讨论】:

以上是关于我可以在 .gitconfig 中为自己指定多个用户吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 Pail Tap Hadoop 作业中为输入指定多个文件夹

如何在 Tweepy 中为 API.search 的地理编码参数指定多个坐标

如何在MSON中为数组指定多个可能的类型(类型union)?

如何在我的 podfile 中为我的 Xcode 项目指定多个目标?

如何在 Maven 中为依赖项指定存储库

是否可以在 MATLAB 中为每个文件定义多个函数,并从该文件外部访问它们?