A configuração do git pode ser definida em vários repositórios?

18

O Git parece suportar valores de configuração em três níveis:

  • Configurações globais por sistema (armazenadas em /etc/git-core)
  • Configurações globais por usuário (armazenadas em ~/.gitconfig)
  • Configurações locais por repositório (armazenadas em $REPO/.git/config)

Essas opções cobrem a maior parte das bases, mas estou procurando uma maneira de lidar com o quarto nível. Eu tenho uma coleção (muito) grande de repositórios para os quais preciso usar um valor diferente do user.emailque o habitual. Esses repositórios geralmente são criados e manipulados por meio de scripts automatizados, e a configuração local por repositório é complicada.

Todos os repositórios em questão estão localizados em um determinado prefixo de caminho no meu sistema local. Existe uma maneira de definir um valor de configuração em algum lugar que será herdado por todos os repositórios nesse caminho? (Algumas .htaccessconfigurações semelhantes herdam todo o sistema de arquivos.) Talvez haja uma maneira de definir valores condicionais no arquivo de configuração global? Que outros arranjos poderiam ser feitos em um ambiente UNIX para lidar com um conjunto de repositórios como o meu?

Caleb
fonte
Meu primeiro reflexo é hackear os scripts para ajustar .gitconfigem cada diretório que eles criam. Por exemplo, o repo do IIRC Android pode fazer isso, mas você precisa ler a fonte com cuidado para descobrir. (Eu não estou completamente certo, eu não tenho feito isso há algum tempo.)
Gilles 'SO parada sendo maus'
@ Gilles: Essa é certamente uma possibilidade. Os repositórios em questão são o repositório de pacotes para uma distribuição Linux que migrou recentemente do CVS para o Git. Ainda estamos trabalhando para refazer todas as nossas ferramentas. A longo prazo, é provavelmente onde isso é corrigido, mas, a curto prazo, aqueles de nós trabalhando nisso estão experimentando quais são as opções.
Caleb

Respostas:

11

Não encontrei nenhuma maneira de configurar o git neste quarto nível. A única maneira parece ser o valor de configuração por comando que substitui o uso git -c key=value.

Minha solução hacky atual é definir uma função de shell que serve como um invólucro para o git. Quando chamado, ele passa os argumentos para o comando git do sistema, mas não antes de verificar o diretório de trabalho atual e adicionar um argumento extra ao comando, se aplicável.

function git () {
    case "$PWD" in
        /path/to/repos/*)
            command git -c user.email=alternate@credentials.org "$@"
            ;;
        *)
            command git "$@"
            ;;
    esac
}
Caleb
fonte
posso fazer command git -c [email protected] user.name="Alter Ego" "$@"ou como devo fazer isso? Pesquisei alta e baixa e a única referência a essa bandeira -c que encontrei foi a sua, muito apreciada.
Vic Goldfeld
para constar, eu trabalhei com elecommand git -c [email protected] -c user.name="Alter Ego" "$@"
Vic Goldfeld 28/01
6

Você pode configurar o endereço de email para git com a variável de ambiente GIT_AUTHOR_EMAIL. Se você combinar isso com Executar scripts bash ao inserir uma configuração de shell específica de diretório ou diretório com o zsh, poderá alterar facilmente as configurações por diretório ou diretório pai; por exemplo, se você entrar em um diretório, ~/workpoderá ajustar automaticamente as variáveis ​​de ambiente para alterar seu email. endereço.

Ulrich Dangel
fonte
2

Veja a solução baseada na configuração do git:

http://gik.firetrot.com/index.php/2018/05/06/git-configuration-across-multiple-repositories/

Adicione ao arquivo "~ / .gitconfig":

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

Crie o arquivo “~ / .gitconfig-project1 ″ com o conteúdo:

    [core]  
      sshCommand = "ssh -i ~/.ssh/project1 -F /dev/null"  

    [user]  
      name = user1  
      email = user1@email.com  
gik
fonte
O predicado "includeIf" salva minha dor de cabeça!
Truong Nguyen
1

Com base na resposta de Caleb, podemos definir um gitcomando modificado que configura permanentemente todos os repositórios neste diretório corretamente, para que todos os usos futuros do vanilla git usem a nova configuração. Eu uso hub, que é outro wrapper git, então substituí o meu alias git=hubpor isso e chamei hubminha função - se você não usar hub, substitua todas as hubinvocações por command git:

function git() {
    case "$PWD" in
        /home/robin/git/3RD_PARTY)
            hub "$@"
            # We don't know which repository was cloned / operated on, so let's just reconfigure them all
            for f in *; do
                [[ -d "$f" ]] && hub -C "$f" config user.email $my_private_email
            done
            ;;
        /home/robin/git/3RD_PARTY/*)
            hub "$@"
            hub config user.email $my_private_email
            ;;
        *)
            hub "$@"
            ;;
    esac
}

Diferentemente da resposta de Caleb, que só funciona em um shell (e, a menos que seja explicitamente originada, apenas em um shell interativo), isso também afeta outros front-ends do git que leem corretamente a configuração do git, como o emacs magit.

Robin Green
fonte