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

我可以在.gitconfig中为自己指定多个用户吗?,git,git-config,Git,Git Config,在我的~/.gitconfig中,我在[user]下列出了我的个人电子邮件地址,因为这是我想要用于Github回购的 但是,我最近也开始在工作中使用git。我公司的git repo允许我提交,但当它发布新变更集的公告时,它说它们来自匿名,因为它无法识别我的.gitconfig中的电子邮件地址-至少,这是我的理论 是否可以在.gitconfig中指定多个[user]定义?或者是否有其他方法覆盖特定目录的默认.gitconfig?在我的例子中,我检查了~/worksrc/中的所有工作代码-是否有办法

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

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


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

您可以将单个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 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
文件中添加以下信息

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

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

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

从中获得一些灵感后,我编写了一个预提交钩子(驻留在
~/.git/templates/hooks
),它将根据本地repositorie的
/.git/config
中的信息设置特定的用户名和电子邮件地址:

[init]
    templatedir = ~/.git/templates
[alias]
  changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"
您必须将模板目录的路径放入
~/.gitconfig

[init]
    templatedir = ~/.git/templates
[alias]
  changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"
然后,每个
git init
git clone
将拾取该钩子,并在下一次
git提交期间应用用户数据。如果您想将钩子应用于已经存在的回购,那么只需在回购内部运行一个
git init
,以重新初始化它

这是我想出的钩子(它仍然需要一些改进-欢迎建议)。 另存为

~/.git/templates/hooks/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命令调用(
gitpassport
)。此外,还可以在配置文件(
~/.gitpassport
)中定义任意数量的ID,这些ID可在提示下选择。您可以在github.com上找到该项目:.

从我写的预提交钩子(驻留在
~/.git/templates/hooks
)中获得一些灵感后,它将根据本地repositorie的
/.git/config
中的信息设置特定用户名和电子邮件地址:

[init]
    templatedir = ~/.git/templates
[alias]
  changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"
您必须将模板目录的路径放入
~/.gitconfig

[init]
    templatedir = ~/.git/templates
[alias]
  changeremotehost = !sh -c \"git remote -v | grep '$1.*fetch' | sed s/..fetch.// | sed s/$1/$2/ | xargs git remote set-url\"
然后,每个
git init
git clone
将拾取该钩子,并在下一次
git提交期间应用用户数据。如果您想将钩子应用于已经存在的回购,那么只需在回购内部运行一个
git init
,以重新初始化它

这是我想出的钩子(它仍然需要一些改进-欢迎建议)。 另存为

~/.git/templates/hooks/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命令调用(
gitpassport
)。此外,还可以在配置文件(
~/.gitpassport
)中定义任意数量的ID,这些ID可在提示下选择。您可以在github.com上找到该项目:。

Windows环境

另外,如果系统中安装了Git Extensions-->设置-->全局设置,则可以从中修改此设置

在Windows环境中的文件夹/目录上单击鼠标右键可访问这些设置。

更新:如何在2.49版中切换/维护多个设置
Windows环境

另外,如果系统中安装了Git Extensions-->设置-->全局设置,则可以从中修改此设置

在Windows环境中的文件夹/目录上单击鼠标右键可访问这些设置。

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

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

例如,通过定义别名:

别名git='/usr/bin/git-c user.name=“您的名字”-c user.email=”name@example.com"'
要查看它是否有效,只需键入
git config user.email

$git config user.email
name@example.com
您还可以在
$PATH
中放置自定义的
git
可执行文件,而不是别名

#/垃圾箱/垃圾箱
/usr/bin/git-c user.name=“您的名字”-c user.email=”name@example.com" "$@"
与特定于存储库的
.git/config
相比,这些方法的一个优点是,当自定义
git
程序处于活动状态时,它适用于每个
git
存储库。通过这种方式,您可以轻松地在用户/名称之间切换,而无需修改任何(共享)配置。

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

例如,通过定义别名:

ali
[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\"
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'
export GIT_AUTHOR_EMAIL='me@work.com'
export GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"
F="$HOME/.bashrc_local"
if [ -r "$F" ]; then
    . "$F"
fi
[github]
    name = <github username>
    email = <github email>
[gitlab]
    name = <gitlab username>
    email = <gitlab email>
[init]
    templatedir = ~/.git-templates
[user]
    useConfigOnly = true
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]-----+
cp ~/.ssh/work ~/.ssh/id_rsa
cp ~/.ssh/work.pub ~/.ssh/id_rsa.pub
cp ~/.ssh/personal ~/.ssh/id_rsa
cp ~/.ssh/personal.pub ~/.ssh/id_rsa.pub
alias crev="sh ~/.ssh/crev.sh"
alias prev="sh ~/.ssh/prev.sh"
source ~/.bashrc
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
git config --global --unset user.name
git config --global --unset user.email
git config --global user.useConfigOnly true
[user]
    name = John Doe
    email = john@doe.tld

[includeIf "gitdir:~/work/"]
    path = ~/work/.gitconfig
[user]
    email = john.doe@company.tld
# ~/.gitconfig
[include]
    path = user.gitconfig
[includeIf "gitdir/i:c:/work/"]
    path = work-user.gitconfig
[includeIf "gitdir/i:c:/work/github/"]
    path = user.gitconfig
#!/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" $@
# 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'
$ ssh-add -l
$ ssh-add -D
$ 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-add id_rsa_work
$ ssh-add id_rsa_pers
$ ssh-add -l
$ git config user.name "Working Hard"
$ git config user.email "work@company.com" 
$ git config user.name "Personal Account"
$ git config user.email "pers@email.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"
 # 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