Eu tenho um script que é executado rsync
com um diretório de trabalho Git como destino. Quero que o script tenha um comportamento diferente, dependendo se o diretório de trabalho estiver limpo (sem alterações a confirmar) ou não. Por exemplo, se a saída de git status
for como abaixo, quero que o script saia:
git status
Already up-to-date.
# On branch master
nothing to commit (working directory clean)
Everything up-to-date
Se o diretório não estiver limpo, eu gostaria que ele executasse mais alguns comandos.
Como posso verificar a saída como a acima em um script de shell?
shell-script
git
brentwpeterson
fonte
fonte
git reset --hard origin/branch
se é isso que você está indo para ... como se você está tentando limpeza depois de compilar algo, etc.Respostas:
Analisar a saída de
git status
é uma péssima idéia, pois a saída deve ser legível por humanos, não legível por máquina. Não há garantia de que a saída permaneça a mesma nas versões futuras do Git ou em ambientes configurados de maneira diferente.O comentário dos UVVs está no caminho certo, mas, infelizmente, o código de retorno de
git status
não muda quando há alterações não confirmadas. No entanto, ele fornece a--porcelain
opção, que faz com que a saídagit status --porcelain
seja formatada em um formato fácil de analisar para scripts e permanecerá estável nas versões do Git e independentemente da configuração do usuário.Podemos usar a saída vazia
git status --porcelain
como um indicador de que não há alterações a serem confirmadas:Se não nos importamos com arquivos não rastreados no diretório de trabalho, podemos usar a
--untracked-files=no
opção para desconsiderar aqueles:Para tornar isso mais robusto em relação às condições que realmente causam
git status
falhas sem saídastdout
, podemos refinar a verificação para:Também é importante notar que, embora
git status
não dê um código de saída significativo quando o diretório de trabalho é impuro,git diff
fornece a--exit-code
opção, o que o comporta de maneira semelhante ao utilitário diff , ou seja, sair com status1
quando houve diferenças e0
quando nenhuma foi encontrada.Usando isso, podemos verificar se há alterações em estágios com:
e preparadas, mas não confirmadas, alterações com:
Embora
git diff
possa relatar arquivos não rastreados em sub-módulos por meio de argumentos apropriados--ignore-submodules
, infelizmente parece que não há como reportar arquivos não rastreados no diretório de trabalho real. Se arquivos não rastreados no diretório de trabalho forem relevantes,git status --porcelain
provavelmente é a melhor aposta.fonte
git status --porcelain
será encerrado com o código 0, mesmo que haja alterações não preparadas para arquivos de confirmação e não rastreados.git stash
faria alguma coisa (não gera um código de retorno útil). Eu tive que adicionar--ignore-submodules
, caso contráriogit status
indicaria alterações no sub-módulo quegit stash
ignoram.if [ -z
estava fazendo. O-z
que significa que, se a seguinte sequência estiver vazia, o if será avaliado comotrue
. Em outras palavras, se issogit status --porcelain
resultar em nenhuma sequência, o repositório estará limpo. Caso contrário, ele lista os arquivos modificados / adicionados / removidos e não é mais uma sequência vazia. Oif
então avalia comofalse
.Usar:
O código de retorno reflete o estado do diretório ativo (0 = limpo, 1 = sujo). Arquivos não rastreados são ignorados.
fonte
git update-index --refresh
antesgit diff-index HEAD
. Mais informações: stackoverflow.com/q/34807971/1407170git add .
antes de emiti-lo. Geralmente é a maneira de usá-lo em um scriptset +e
antes da chamadagit
e adicionandoset -e
novamente após a avaliação$?
.Pequena extensão à excelente resposta de André .
Essa é uma maneira de avaliar os resultados e também evitar uma armadilha se você estiver em um script que emitiu anteriormente set -e .
Arquivos não rastreados são ignorados.
fonte