Posso especificar vários usuários para mim no .gitconfig?

755

No meu ~/.gitconfig, listo meu endereço de e-mail pessoal em [user], pois é isso que quero usar para os repositórios do Github.

Mas recentemente comecei a usar o git também para o trabalho. O repositório git da minha empresa me permite confirmar, mas quando ele envia anúncios de novos conjuntos de alterações, ele diz que são do Anonymous porque não reconhece o endereço de email no meu .gitconfig- pelo menos, essa é a minha teoria.

É possível especificar várias [user]definições .gitconfig? Ou existe alguma outra maneira de substituir o padrão .gitconfigpara um determinado diretório? No meu caso, verifico todo o código de trabalho em ~/worksrc/- existe uma maneira de especificar um .gitconfigsomente para esse diretório (e seus subdiretórios)?

Brock Boland
fonte
Veja git-config # FILES .
Josh Lee
1
Estou surpreso que o servidor da sua empresa faça isso - teria que MUDAR o sha do seu commit para que isso funcionasse. Se você confirmar um checkout local, que nome de usuário você vê?
Alex Brown
1
@ Alex: Esqueceu a parte importante lá - poderia facilmente ser apenas um nome na notificação por email, sem realmente alterar nada na confirmação.
Cascabel
1
Você pode usar um git-hook para automatizar esse trabalho recorrente: github.com/DrVanScott/git-clone-init
Henning
1
Aceite esta resposta: stackoverflow.com/a/43654115/482899 . É a melhor solução desde o git 2.13.
Northtree 26/07

Respostas:

1017

Você pode configurar um repositório individual para usar um endereço de usuário / email específico que substitua a configuração global. Na raiz do repositório, execute

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

enquanto o usuário / email padrão está configurado no seu ~ / .gitconfig

git config --global user.name "Your Name Here"
git config --global user.email [email protected]
perturbar
fonte
83
você pode ver os efeitos dessas configurações no .git/configarquivo
Abizern
21
Você pode editar manualmente esses arquivos de configuração com git config --edite git config --global --edit. E caso você tenha perdido o comentário de Abizern , o arquivo de configuração de um repositório está em <repo-root>/.git/config.
Rory O'Kane
13
Você também deve unset GIT_AUTHOR_EMAIL e GIT_COMMITTER_EMAIL (e _NAME *) como eles vão substituir as configurações locais
acíclico
6
Existe uma maneira de fazer isso para todos os repositórios em uma determinada pasta, e não para repositórios individuais? Veja minha pergunta aqui: stackoverflow.com/questions/21307793/…
scubbo 23/01
6
Veja esta resposta abaixo para obter uma solução mais atualizada Git 2.13lançada hoje.
Tejasbubane 10/05
491

Desde o git 2.13 , é possível resolver isso usando as inclusões Condicionais recém-introduzidas .

Um exemplo:

Configuração global ~ / .gitconfig

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

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

Configuração específica do trabalho ~ / work / .gitconfig

[user]
    email = [email protected]
Tomáš Janoušek
fonte
48
Esta é a melhor resposta agora que o git 2.13 foi lançado.
Tejasbubane
1
Essa solução funcionaria para todos os subdiretórios dentro do especificado na instrução include, supondo que eles não tenham seus próprios arquivos .gitconfig? Eu acho que sim, mas até agora os testes não confirmam isso.
Gary
2
@ Gary Sim, de acordo com minha experiência e os documentos: “Se o padrão terminar com /, ** será automaticamente adicionado. Por exemplo, o padrão foo / torna-se foo / **. Em outras palavras, ele combina "foo" e tudo dentro, recursivamente. ”,“; include para todos os repositórios dentro de $ HOME / to / group [includeIf "gitdir: ~ / to / group /"] ”
Tomáš Janoušek
6
O gitdir deve incluir o último '/'.
precisa saber é o seguinte
5
Você pode verificar se funciona recursivamente executando git config --listem diretórios diferentes. Nos subdiretórios ~/work/que contêm um repositório git, o includeIfefeito entra em vigor. Observe que nos subdiretórios ~/work/que não contêm um repositório git, o includeIfnão é executado.
NZD
105

Ou você pode adicionar as seguintes informações no seu .git/configarquivo local

[user]  
    name = Your Name
    email = [email protected]
Rahul Prasad
fonte
27
... que é a maneira manual de fazer o que os comandos recomendados por @discomurray fazem por você.
precisa saber é o seguinte
1
é possível adicionar várias linhas por controle remoto?
Abel Callejo
55

Um comando github accounts switch

Essa solução assume a forma de um único alias do git. Uma vez executado, o usuário do projeto atual será anexado a outra conta

Gerar chaves 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'

Vincule-os às suas contas GitHub / Bitbucket

  1. copiar chave pública padrão pbcopy < ~/.ssh/id_rsa.pub
  2. Faça login na sua conta do GitHub
  3. cole a chave na add SSH keypágina do github
  4. copiar outra chave pública pbcopy < ~/.ssh/id_rsa_pro.pub
  5. repita e adapte as etapas 2 a 4 para todas as outras contas

Etapa 1. Troca automática de chave ssh.

Podemos configurar sshpara enviar um uso de uma chave de criptografia específica, dependendo do host. O bom é que você pode ter vários aliases para o mesmo hostname.

Veja este ~/.ssh/configarquivo de exemplo :

# 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

configuração remota git

Agora você pode usar esses aliases nos controles remotos git alterando [email protected]por git@github_pro.

Você pode alterar os controles remotos de seus projetos existentes (usando algo como git remote set-url origin git@github_pro:foo/bar.git) ou adaptá-los diretamente ao cloná-los.

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

usando o alias, ele se torna:

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

Etapa 2. Alterando o git user.email

As configurações do Git podem ser globais ou por projeto. No nosso caso, queremos uma configuração por projeto. É muito fácil mudar isso:

git config user.email '[email protected]'

Embora isso seja fácil, leva muito tempo para os desenvolvedores que somos. Podemos escrever um alias git muito simples para isso.

Nós vamos adicioná-lo ao ~/.gitconfigarquivo.

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

...

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

Então, tudo o que precisamos fazer é git setpromailalterar nosso email apenas para este projeto.

Etapa 3. Uma chave de comando, por favor ?!

Não seria bom mudar da conta padrão para a conta especificada com um único comando sem parâmetros? Isso é definitivamente possível. Este comando terá duas etapas:

  • alterar controles remotos do projeto atual para os aliases escolhidos
  • alterar a configuração atual de user.email do projeto

Já temos uma solução de comando único para o segundo passo, mas o primeiro é muito mais difícil. Alteração de host remoto de um comando

Aí vem a solução na forma de outro comando git alias para adicionar ao seu ~/.gitconfig:

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

Isso permite alterar todos os controles remotos de um host para outro (o alias). Veja o exemplo:

$ > 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)

Combine todos eles

Agora só precisamos combinar os dois comandos em um, isso é bastante fácil. Veja como eu também integro a comutação de host de 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\"

Link de origem - Tutorial

Kaleem Ullah
fonte
Isso é brilhante, obrigado. Eu trabalho com um monte de repositórios por email, para que meu setpromailalias faça isso config --global(e eu tenho outros aliases definidos para definir endereços de email diferentes). Funciona!
Michel-slm
1
Para essas duas contas diferentes, como posso assinar com diferentes chaves de gpg? Eu tenho duas chaves gpg para duas contas github e gostaria de assinar de forma diferente. "git config --global user.signingkey xxxx"
hakkican 6/18
Essa resposta é incrível. Eu quase não li, porque achei que encontrei o que da outra resposta. Definitivamente merece mais votos. PS. É ainda melhor quando combinado com useConfigOnly = truea outra resposta.
steinybot
Não é IdentifyFile, é IdenfityFile.
Christian
40

Depois de me inspirar no post de Orr Sella, escrevi um gancho de pré-confirmação (reside em ~/.git/templates/hooks) que definiria nomes de usuário e endereços de email específicos com base nas informações dentro de um repositório local ./.git/config:

Você deve colocar o caminho para o diretório do modelo em seu ~/.gitconfig:

[init]
    templatedir = ~/.git/templates

Em seguida, cada git initou git clonevai pegar esse gancho e aplicará os dados do usuário durante a próxima git commit. Se você deseja aplicar o gancho aos repositórios já existentes, basta executar um git initdentro do repositório para reinicializá-lo.

Aqui está o gancho que eu criei (ele ainda precisa de polimento - sugestões são bem-vindas). Salve-o como

~/.git/templates/hooks/pre_commit

ou

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

e verifique se é executável: 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

EDITAR:

Então, eu reescrevi o gancho como um gancho e comando em Python. Além disso, é possível chamar o script como um comando Git ( git passport) também. Também é possível definir um número arbitrário de IDs dentro de um configfile ( ~/.gitpassport) que podem ser selecionados em um prompt. Você pode encontrar o projeto em github.com: git-passport - Um comando do Git e um gancho escritos em Python para gerenciar várias contas / identidades de usuário do Git .

Saucier
fonte
1
Isso funciona perfeitamente. No entanto, funcionou melhor para mim, tornando isso um gancho pós-checkout (em vez de pós-commit). Minhas sugestões para melhorar esta resposta são: mencione que: 1. o snippet precisa ser salvo como ~ / .git / templates / hooks / pós-checkout e recebe permissão chmod +x post-checkout, 2. os git_remotesvalores são parte inicial de todo o nome do host, por exemplo [email protected], 3. os local_idvalores devem ser editados pelo usuário para os respectivos nomes e endereços de email.
Shantanu Kumar
Obrigado por seu comentário. Eu ajustei a resposta como você propôs. Talvez eu reescreva o script em Python em breve.
Saucier
Adicionado suporte para expressões regulares e para repositórios sem controles remotos. Para facilitar o download de tudo mesclado aqui . Regexps para distinguir identidades para diferentes projetos no mesmo serviço. E apoiar repos remoteless com por exemplo, uma identidade padrão faz sentido se você git initnovos projetos de uma IDE, como eclipse(que não podem lidar com interativo pré-commit gatilhos)
TPI
25

Se você não deseja ter um endereço de email padrão ( links de endereço de email para um usuário do github ), você pode configurar o que deseja que seja solicitado. Como você pode fazer isso depende da versão do git usada, veja abaixo.

A desvantagem (pretendida) é que você deve configurar seu endereço de email (e seu nome) uma vez para cada repositório. Então, você não pode esquecer de fazê-lo.

Versão <2.7.0

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

na sua configuração global, ~/.gitconfigconforme declarado em um comentário de Dan Aloni na postagem do blog de Orr Sella . Ao tentar fazer o primeiro commit em um repositório, o git falha com a boa mensagem:

*** 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)')

O nome é obtido da configuração global quando o endereço de email é definido localmente (a mensagem não é perfeitamente precisa).

2.7.0 ≤ Versão <2.8.0

O comportamento nas versões <2.7.0 não foi planejado e corrigido com 2.7.0. Você ainda pode usar um gancho de pré-confirmação, conforme descrito na postagem do blog de Orr Sella . Esta solução também funciona para outras versões, mas as outras soluções não para esta versão.

Versão ≥ 2.8.0

Dan Aloni adicionou uma opção para atingir esse comportamento (consulte as notas da versão ). Use-o com:

[user]
    useConfigOnly = true

Para fazê-lo funcionar, você não deve fornecer um nome ou endereço de email na configuração global. Em seguida, na primeira confirmação, você recebe uma mensagem de erro

fatal: user.useConfigOnly set but no name given

Portanto, a mensagem não é muito instrutiva, mas como você define explicitamente a opção, você deve saber o que fazer. Ao contrário da solução das versões <2.7.0, você sempre precisa definir o nome e o email manualmente.

John
fonte
Eu uso esse método por alguns meses, funcionou muito bem. Eu tenho vários endereços de email (pessoais, profissionais) e não quero ter um "padrão" configurado no gitconfig global. Com o valor especial "(none)", o git solicitará que eu forneça um endereço válido toda vez que criar um novo repositório, em vez de adivinhar um com base no nome de usuário e nome do host (o que é irritante e preciso - emendá-lo). No entanto, recentemente com a versão atualizada do Git (2.7.0, talvez mais cedo), descobri que o valor especial "(none)" não aciona mais erros fatais. Em vez disso, só vai usar "John Doe <(nenhum)>" como é ...
Zhuoyun Wei
@wzyboy: Oh, você está certo. Eu git bisectachava que o commit 19ce497c ... introduzia esse comportamento. No entanto, independente da versão (2.5 - 2.7) eu posso usar email =(sem argumento) na configuração e mostra o mesmo comportamento email = "(none)"das versões antigas. Você pode confirmar isso? Nesse caso, editarei minha resposta. Sou apenas cético, pois parece tão óbvio e não o usei antes.
John John
Eu tentei email =na 2.7.0, o Git ainda adivinha o endereço de email com base no nome de usuário e no host. Agora uso pre-commitabordagem no blog de Sella. Também informei o Dan Aloni que teve a "(none)"ideia no post de Sella e ele registrou um patch para implementá-lo formalmente como um recurso: permalink.gmane.org/gmane.comp.version-control.git/285301
Zhuoyun Wei
3
desde git-2.8: A variável de configuração "user.useConfigOnly" pode ser usada para forçar o usuário a sempre definir user.email & user.name github.com/git/git/blob/master/Documentation/RelNotes/2.8.0. txt
rofrol 29/03
@rofrol Obrigado pela informação. Eu atualizei minha resposta de acordo.
John
24

Com inclusões condicionais no Git 2.13, agora é possível coexistir vários usuários / email em uma máquina com pouco trabalho.

user.gitconfigtem meu nome e email pessoais. work-user.gitconfigtem meu nome e e-mail de trabalho. Ambos os arquivos estão no ~caminho.

Portanto, meu nome / email pessoal se aplica por padrão. Para c:/work/dir, meu nome / email de trabalho é aplicado. Para c:/work/github/dir, meu nome / email pessoal é aplicado. Isso funciona quando a última configuração é aplicada.

# ~/.gitconfig
[include]
    path = user.gitconfig
[includeIf "gitdir/i:c:/work/"]
    path = work-user.gitconfig
[includeIf "gitdir/i:c:/work/github/"]
    path = user.gitconfig

gitdirdiferencia maiúsculas de minúsculas e gitdir/inão diferencia maiúsculas de minúsculas.

"gitdir/i:github/"aplicaria a inclusão condicional para qualquer diretório com githubem seu caminho.

hIpPy
fonte
Enquanto sua resposta é apreciada e boa, Tomáš Janoušek deu os mesmos 20 dias antes de você. Por favor, considere excluir esta resposta.
Hedge
5
@ Hedge Sim, votei positivamente na sua resposta, mas demorei um pouco para configurar no Windows e foi aí que gitdir/ime ajudou (que sua resposta não menciona).
HIpPy 15/09
A maneira específica como o @hIpPy implementou isso se aplica diretamente ao meu caso de uso e facilita muito o acompanhamento da resposta do Tomas. Eu votei em ambos.
Isaac Adams
18

Outra opção para gittrabalhar com vários nomes / e-mails é gitusando o alias e usando o -csinalizador para substituir a configuração global e específica do repositório.

Por exemplo, definindo um alias:

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

Para ver se funciona, basta digitar git config user.email:

$ git config user.email
name@example.com

Em vez de um alias, você também pode colocar um gitexecutável personalizado dentro do seu $PATH.

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

Uma vantagem desse método em relação a um repositório específico .git/configé que ele se aplica a todos os gitrepositórios quando o gitprograma customizado está ativo. Dessa maneira, você pode alternar facilmente entre usuários / nomes sem modificar nenhuma configuração (compartilhada).

Rob W
fonte
14

aliases do git (e seções em git configs) para o resgate!

adicione um alias (da linha de comando):

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

então, defina, por exemplo

git config --global user.github.name "your github username"
git config --global user.github.email [email protected]

e em um repo novo ou clonado, você pode executar este comando:

git identity github

Esta solução não é automática, mas o usuário desactivação e-mail no seu global, ~/.gitconfige definindo user.useConfigOnlya trueforçaria git para lembrá-lo para configurá-los manualmente em cada repo novo ou clonado.

git config --global --unset user.name
git config --global --unset user.email
git config --global user.useConfigOnly true
codesnik
fonte
1
Eu gosto da sua solução; no entanto, quando desmarco minha global, ela apenas efetua o commit com o nome do host do meu computador, em vez de com o git, para que eu os defina em um determinado
repositório
12

Aqui estão as etapas completas depois de ler muitas respostas aqui

Como definir várias configurações de chaves SSH para diferentes contas do github

Você pode começar a verificar as chaves salvas no momento

$ ssh-add -l

Se você decidir excluir todas as chaves em cache antes ( opcional, tenha cuidado com isso )

$ ssh-add -D

Em seguida, você pode criar uma chave ssh pub / priv vinculada a cada email / conta que você deseja / precisa usar

$ 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"

Após executar esses comandos, você terá os seguintes arquivos criados

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

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

Verifique se o agente de autenticação está em execução

$ eval `ssh-agent -s`

Adicione as chaves geradas da seguinte forma (da pasta ~ / .ssh)

$ ssh-add id_rsa_work
$ ssh-add id_rsa_pers

Agora você pode verificar suas chaves salvas novamente

$ ssh-add -l

Agora você precisa adicionar as chaves públicas geradas ao seu servidor github / bickbuket

Clone cada um dos repositórios para pastas diferentes

Vá para a pasta onde o trabalho do usuário trabalhará e execute este

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

Apenas para ver o que isso faz, verifique o conteúdo do ".git / config"

Vá para a pasta onde o usuário pers trabalhará e executará este

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

Apenas para ver o que isso faz, verifique o conteúdo do ".git / config"

Depois de tudo isso, você poderá confirmar seu código pessoal e de trabalho apenas alternando entre essas duas pastas

Caso você esteja usando o Git Bash e precise gerar chaves ssh no Windows, siga estas etapas:

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

Mauricio Gracia Gutierrez
fonte
9

Existe uma solução simples que parece funcionar bem para evitar erros.

Simplesmente remova a [user]seção do seu ~/.gitconfig, o que impedirá que você faça quaisquer confirmações sem definir user.namepara cada repositório.

No seu ~/.bashrc, adicione alguns aliases simples para o usuário e email:

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]'
Zantier
fonte
Não é bom, porque você duplicará a configuração em todos os
repositórios
9

Essa resposta foi parcialmente inspirada no post do @Saucier, mas eu estava procurando uma maneira automatizada de definir user.namee user.emailpor repo, com base no controle remoto, um pouco mais leve que o pacote git-passport que ele desenvolveu . Também h / t para @John para a configuração useConfigOnly. Aqui está a minha solução:

.gitconfig alterar:

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

gancho pós-checkout, que deve ser salvo no seguinte caminho ~/.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

Uso credenciais diferentes para o github e o gitlab, mas essas referências no código acima podem ser substituídas ou aumentadas por qualquer serviço que você usar. Para que o gancho pós-checkout defina automaticamente o nome de usuário e o email localmente para um repo após um check-out, verifique se o nome do serviço aparece no URL remoto, adicione-o à matriz de serviços no post-checkoutscript e crie uma seção em seu .gitconfigque contém seu nome de usuário e email para esse serviço.

Se nenhum dos nomes de serviço aparecer no URL remoto ou o repositório não tiver um remoto, o nome do usuário e o email não serão definidos localmente. Nesses casos, a user.useConfigOnlyconfiguração estará em jogo, o que não permitirá que você faça confirmações até que o nome do usuário e o email sejam definidos no nível do repo e solicitará que o usuário configure essas informações.

Grant Humphries
fonte
1
Ótima solução. Não se esqueça chmod 755do script do gancho. Caso contrário, ele será copiado, mas nunca executado.
Onekiloparsec
5

GIT_AUTHOR_EMAIL + local .bashrc

.bashrc_local: não rastreie este arquivo, coloque-o apenas no seu computador de trabalho:

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

.bashrc: rastreie esse arquivo, faça o mesmo nos computadores doméstico e comercial:

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

Estou usando https://github.com/technicalpickles/homesick para sincronizar meus arquivos de ponto.

Se apenas o gitconfig aceitasse variáveis ​​de ambiente: Expansão da variável do shell no git config

Ciro Santilli adicionou uma nova foto
fonte
5

Ambiente Windows

Adicional, isso pode ser modificado Git Extensions --> Settings --> Global Settings, se você o tiver instalado em seus sistemas.

gitextensions-latest-release

Clique com o botão direito do mouse em uma pasta / diretório no Ambiente do Windows para acessar essas configurações. insira a descrição da imagem aqui

Atualização : Como alternar / manter várias configurações na versão 2.49 Como alternar / manter várias configurações na versão 2.49

Abhijeet
fonte
Como isso aborda vários usuários, em vez de apenas editá-los?
@D_N Atualizado com uma nova captura de tela com opções para alterar as configurações.
Abhijeet
Abra a pasta de repo local e selecione git-config no menu de navegação e clique na guia repo local, o conteúdo será aplicado a $ local_repo_path / .git / config como resposta acima.
Maxwu # 12/18
3

Talvez seja um hack simples, mas é útil. Basta gerar 2 chaves ssh como abaixo.

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]-----+

Da mesma forma, crie mais um para uso pessoal. Então, você tem 2 chaves ssh, trabalho e empresa. Copie work.pub, work, personal.pub, personal para ~ / .ssh / Directory.

Em seguida, crie um script de shell com as seguintes linhas e nomeie-o como crev.sh (Company Reverse) com o seguinte conteúdo.

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

Da mesma forma, crie mais um chamado prev.sh (Reverse Pessoal) com o seguinte conteúdo.

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

em ~ / .bashrc adicione aliases para os scripts como abaixo

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

Sempre que quiser usar a empresa, faça crev, e se quiser usar o pessoal, prev :-p.

Adicione essas chaves ssh às suas contas do GitHub. Verifique se você não possui o id_rsa gerado anteriormente, porque esses scripts substituirão o id_rsa. Se você já gerou id_rsa, use-o para uma das contas. Copie-os como pessoais e pule a geração de chaves pessoais.

7H3 IN5ID3R
fonte
1

Eu criei uma função bash que lida com isso. Aqui está o repositório do Github .

Para gravar:

# 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'
Arount
fonte
1

Basta adicionar isso ao seu ~ / .bash_profile para alternar entre as chaves padrão do 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"
Jason DeBolt
fonte
1

Você também pode usar git commit --author "Your Name <[email protected]>"no momento da confirmação em um repositório em que deseja confirmar como um usuário diferente.

szx
fonte
0

Algo parecido com a resposta de Rob W , mas permitindo uma chave ssh diferente e funciona com versões mais antigas do git (que não possuem, por exemplo, uma configuração core.sshCommand).

Eu criei o arquivo ~/bin/git_poweruser, com permissão de executável, e no 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]" $@

Sempre que eu quero confirmar ou enviar algo como "Usuário Avançado", eu uso em git_poweruservez de git. Ele deve funcionar em qualquer diretório e não requer alterações .gitconfigou .ssh/config, pelo menos, não no meu.

Jellby
fonte
0

Embora a maioria das perguntas tenha respondido ao OP, eu só precisei passar por isso e, mesmo sem pesquisar no Google, consegui encontrar a solução mais rápida e simples. Aqui estão as etapas simples:

  • copiar existente .gitconfgde seu outro repositório
  • cole em seu repo adicionado recentemente
  • alterar valores no .gitconfigarquivo, como nome, email e nome de usuário [user] name = John email = [email protected] username = john133
  • adicione o nome do arquivo à .gitignorelista, para garantir que você não confirme o .gitconfigarquivo no seu repositório de trabalho
Tatarin
fonte