Como saber se um arquivo é rastreado pelo git (pelo código de saída do shell)?

357

Existe uma maneira de saber se um arquivo está sendo rastreado executando algum gitcomando e verificando seu código de saída?

Em outras palavras: o git está rastreando um arquivo?

Dale Forester
fonte
Eu acho que o ponto é: quais são os critérios para decidir um arquivo como rastreado ou não. Deve haver algum tipo de coleção de arquivos rastreados para pesquisar.
smwikipedia

Respostas:

443

tentar:

git ls-files --error-unmatch <file name>

sairá com 1 se o arquivo não for rastreado

hasen
fonte
Pelo menos com a versão mais antiga (1.6.0) do git, é necessário colocar a --error-unmatchopção antes do nome do arquivo para obter um erro. De alguma forma, a opção é aplicada apenas aos nomes de arquivos que a seguem.
AlexDupuy
Na verdade, o problema parece ser que a permutação da opção GNU getopt não está ativada e, ao aparecer após um nome de arquivo (ou depois --), ele --error-unmatché tratado como apenas outro nome de arquivo (não no índice) e não tem efeito.
AlexDupuy
29
git ls-files | grep <PATTERN>? exemplo:git ls-files | grep Main.h
gaussblurinc 21/03
11
[Uma maneira ingênua] Faça uma pequena alteração no arquivo (adicione / remova um espaço). E veja se o arquivo está sendo listado quando 'git status' é digitado. Uma maneira boba, mas pode economizar tempo.
precisa saber é o seguinte
Mas eu adicionei e confirmei com o comando "git add -A && git commit -m" blah ". Mesmo arquivos inteiros com o comando" git ls-tree --name-only -r sha1 ".
Dr.jacky
66

Se você não quiser encher seu console com mensagens de erro, também poderá executar

git ls-files file_name

e depois verifique o resultado. Se o git não retornar nada, o arquivo não será rastreado. Se for rastreado, o git retornará o caminho do arquivo.

Isso é útil se você deseja combiná-lo em um script, por exemplo, PowerShell:

$gitResult = (git ls-files $_) | out-string
if ($gitResult.length -ne 0)
{
    ## do stuff with the tracked file
}
cheesus
fonte
Eu acho que file_nameprecisa ser uma correspondência exata (caminho completo + nome do arquivo), mas pode ser usado com curingas:git ls-files *foo.rb
dechimp
16

EDITAR

Se você precisar usar o git do bash, existe a --porcelainopção de git status:

--porcelana

Forneça a saída em um formato estável e fácil de analisar para scripts. Atualmente, isso é idêntico à saída --short, mas é garantido que não será alterado no futuro, tornando-o seguro para scripts.

A saída é assim:

> git status --porcelain
 M starthudson.sh
?? bla

Ou se você criar apenas um arquivo por vez:

> git status --porcelain bla
?? bla

ORIGINAL

Faz:

git status

Você verá um relatório informando quais arquivos foram atualizados e quais não são rastreados.

Você pode ver que bla.shé rastreado e modificado e newblanão é rastreado:

# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#
#       modified:   bla.sh
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#       newbla
no changes added to commit (use "git add" and/or "git commit -a")
stefanB
fonte
Desculpe, eu deveria ter sido mais claro. O status está bom, mas eu prefiro verificar um código de saída do que analisar a saída.
Dale Forester
git status --porcelainé seu amigo, se você precisar de saída de análise pelo script, ter um olhar para o doc ligou-o mostrar algumas outras opções úteis
stefanB
Hihi, não trabalho com muito antiga Git: git status --porcelain error: unknown option porcelana Version é 1.6.0 :-)
Laryx Decídua
@ user465139 que está correto ... você precisa do git 1.7.0 ou mais recente (a opção porcelana não foi adicionada até então).
mason81
13

Tente executar git statusno arquivo. Ele imprimirá um erro se não for rastreado pelo git

PS$> git status foo.txt
error: pathspec 'foo.txt' did not match any file(s) known to git.
JaredPar
fonte
Uau. Eu devo tê-lo executado em um diretório e ele agiu como se estivesse verificando todo o repositório. Obrigado.
Dale Forester
4
Na verdade, se eu executar git status trackedfile, recebo o código de saída 1 (espera-se que 0 seja útil), mas ele não me dá "erro:" na saída. Prefiro analisar um código de saída do que a saída da string.
Dale Forester
43
Acho que nenhum erro será gerado se eu executar o status do git em um arquivo que existe na minha cópia de trabalho do git, mas que é excluído pelo .gitignore. (Ie esta resposta não vai fazer.)
JellicleCat
Por favor note que ele não funciona bem se o arquivo estiver na lista de ignorar, ou seja, no arquivo.gitignore
Robin Hsu
8
Isso não funciona. Sempre imprime a mesma coisa, mesmo que o arquivo não exista. $ git status notthere:On branch master nothing to commit, working directory clean
Chloe
6

Eu não conheço nenhum comando git que dê um código de saída "ruim", mas parece que uma maneira fácil de fazer isso seria usar um comando git que não fornece saída para um arquivo que não é rastreado, como arquivos git-log ou git-ls-files. Dessa forma, você realmente não precisa fazer nenhuma análise, pode executá-lo através de outro utilitário simples, como o grep, para ver se houve alguma saída.

Por exemplo,

Arquivos git-ls-test_file.c | grep.

sairá com um código zero se o arquivo for rastreado, mas um código de saída de um se o arquivo não for rastreado.

Jay Walker
fonte
3

Sugiro um alias personalizado para você .gitconfig.

Você tem que fazer:

1) Com o comando git:

git config --global alias.check-file <command>

2) Editando ~/.gitconfige adicione esta linha na seção de alias:

[alias]
    check-file = "!f() { if [ $# -eq 0 ]; then echo 'Filename missing!'; else tracked=$(git ls-files ${1}); if [[ -z ${tracked} ]]; then echo 'File not tracked'; else echo 'File tracked'; fi; fi;  };  f"

Uma vez iniciado o comando (1) ou o arquivo salvo (2), no seu espaço de trabalho, você pode testá-lo:

$ git check-file
$ Filename missing 

$ git check-file README.md
$ File tracked 

$ git check-file foo
$ File not tracked
Luca Davanzo
fonte
2

usando git logdará informações sobre isso. Se o arquivo for rastreado no git, o comando mostra alguns resultados (logs). Senão está vazio.

Por exemplo, se o arquivo for rastreado pelo git,

root@user-ubuntu:~/project-repo-directory# git log src/../somefile.js
commit ad9180b772d5c64dcd79a6cbb9487bd2ef08cbfc
Author: User <[email protected]>
Date:   Mon Feb 20 07:45:04 2017 -0600

    fix eslint indentation errors
....
....

Se o arquivo não for rastreado pelo git,

root@user-ubuntu:~/project-repo-directory# git log src/../somefile.js
root@user-ubuntu:~/project-repo-directory#
Super Nova
fonte
1

Apenas meus dois centavos:

git ls-files | grep -x relative/path

onde relative/pathpode ser facilmente determinado pressionando tabdentro de um shell de preenchimento automático. Adicione um adicional | wc -l para obter uma saída 1 ou 0.

andreee
fonte
Dependendo do caminho (por exemplo, se ele contém um ponto), você deve adicionar a grepopção --fixed-strings.
EndlosSchleife 24/03