Maneira correta e rápida de testar o diretório git e git branch?

7

Enquanto tentava configurar o meu novo shell de peixe , acabei testando maneiras de obter o nome da ramificação e também testando se eu estava em um repositório git. Eu encontrei (1) git rev-parse --abbrev-ref HEAD , (2) git symbolic-ref HEAD | sed 's/refs\/heads\///' e (3) git describe --contains --all HEAD faz o truque bem.

Estou curioso porque adoro a simplicidade de (1) , mas em um repositório novo e intocado (apenas git init ed), ele me causa um erro "fatal:", enquanto (2) funciona como pretendido, isto é, dando-me um master padrão como saída. O problema é que, mesmo com um erro “fatal:”, o código de retorno é 0. Esse é o comportamento pretendido?

Para testar se eu estava em um repositório git, acabei simplesmente testando se o diretório atual tinha uma pasta “.git”: test -d ".git" . Solução rudimentar, mas funciona, e parece ser mais rápido que usar qualquer comando git.

Então, minhas perguntas são:

  1. Não deveria ser fatal: com (1) retornar um código de saída diferente de 0? Se de fato é um bug, já que eu não sei como as pessoas padronizaram seus códigos de retorno, onde devo denunciá-lo?
  2. Se eu redirecionar (1) com ^ /dev/null (para quem não sabe, ^ é o mesmo que 2> ), não receberei o erro , mas vai dizer HEAD em vez de mestre, mas se eu cat .git/HEAD , eu recebo: ref: refs/heads/master . O que isso realmente deveria dizer? Com master estou sendo ignorante e exigente, porque deveria dizer HEAD ? Quero dizer, no caso de um repositório apenas git init ed.
  3. Você realmente comparou quaisquer soluções possíveis durante sua busca para obter um bom aviso?

Este é o código que eu uso para benchmark (para peixes):

set -l before (date +%s%N)
git rev-parse --abbrev-ref HEAD
set -l after (date +%s%N)
set -l elapsed_time (expr $after - $before)
echo $elapsed_time

Obrigado antecipadamente!

PS: As ferramentas são as versões mais recentes do GNU, quero dizer, sed , date e expr . Me desculpe se há muita informação ou se algo não faz sentido. Fique comigo. Obrigado!

EDIT: Como alguém adivinhou corretamente em uma resposta, todo o erro é:

fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree.
Use '--' to separate paths from revisions
    
por Andrés Botero 12.09.2012 / 05:54

1 resposta

4

Não responde totalmente às suas perguntas, mas provavelmente é um pouco mais do que apenas um comentário:

  1. Com base em outros comentários em sua resposta, acho que o erro que você viu é fatal: ambiguous argument 'HEAD': unknown revision or path not in the working tree. . Isso ocorre porque você está realizando esses testes em um novo repositório git, que não tem nenhum trabalho confirmado. Não só isto não é realmente um teste justo (seu desempenho será, por definição, pior em um repositório maior), mas em quase todos os casos é um caso extremo. Por exemplo, .git/HEAD mostra ref: refs/heads/master por convenção. O erro é lançado porque HEAD é ambíguo. Você não tem histórico, portanto, qualquer valor passado para rev-parse seria tratado da mesma forma. Além disso, isso não sai 0 para mim:

    $ git init /tmp/test && cd /tmp/test
    $ git rev-parse --abbrev-ref HEAD
    $ echo $?
    128
    

    Em suma, não se preocupe com esse erro. Agarre-se a um dos maiores repositórios do Android, ou talvez ao kernel do linux, e teste seu prompt lá.

  2. HEAD não é um ramo. É um ponteiro para o estado de check-out. Quando você tem um branch check-out, é uma referência simbólica a esse branch. Quando você está no estado 'HEAD desconectado', o ponteiro HEAD está apontando para uma confirmação. Você obtém HEAD como o retorno usando o método (1) porque rev-parse está apenas ecoando o valor de refspec passado no erro. Experimente com blah ; você verá a mesma coisa.

  3. Na verdade, eu não testei soluções, mas algumas coisas que você pode tentar (ambas são usadas no meu prompt zsh, que eu não escrevi, e as duas tiveram um bom desempenho):

    git rev-parse --is-inside-work-tree ;# avoids your 'test -d .git' call
    ref=$(git symbolic-ref HEAD 2> /dev/null) ;# grab the full refspec
    branch=$(echo ${ref#refs/heads/}) ;# extract the branch name
    
por 12.09.2012 / 15:40