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

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

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


当前回答

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和设置用户。useConfigOnly设为true将迫使git提醒你在每次新的或克隆的repo中手动设置它们。

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

其他回答

我做了一个bash函数来处理这个。这是Github回购。

备案:

# 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'

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

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

版本< 2.7.0

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

在全局配置中~/。Dan Aloni在Orr Sella的博客文章中评论了gitconfig。当尝试在存储库中进行第一次提交时,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≤版本< 2.8.0

版本< 2.7.0中的行为不是预期的,并在2.7.0中修复。您仍然可以使用Orr Sella的博客文章中描述的预提交钩子。此解决方案也适用于其他版本,但其他解决方案不适用于此版本。

版本≥2.8.0

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

[user]
    useConfigOnly = true

为了让它工作,你可以不给一个名字或电子邮件地址在全局配置。然后,在第一次提交时,您会得到一条错误消息

fatal: user.useConfigOnly set but no name given

因此,该消息不是很有指导意义,但由于您显式地设置了该选项,您应该知道该做什么。与< 2.7.0版本的解决方案相反,您总是必须手动设置名称和电子邮件

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

它只在当前存储库中设置您的姓名和电子邮件。

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

场景:

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

配置:

Set a "fake" host, which allows me to select the proper SSH keypair. At ~/.ssh/config: # Personal GitHub account Host github-personal HostName github.com User git IdentityFile ~/.ssh/id_rsa_personal IdentitiesOnly yes "Tell" git it should use a custom configuration within a given directory subtree: At ~/.gitconfig: # My personal projects [includeIf "gitdir/i:~/REPOS/PERSONAL/"] path = ~/REPOS/PERSONAL/personal.gitconfig Finally, my config at ~/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引用repo, subrepos(即python-multigit本身的情况-是的,蹩脚的自我推销尝试),而不用冒使用“错误”URL的风险,因此,错误的身份验证。

我的意见。

在阅读了许多答案后,下面是完整的步骤

如何为不同的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/ bickbucket服务器访问密钥

克隆每个回购到不同的文件夹

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

$ 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

从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帐户/用户身份。