Excluir um diretório do git diff

179

Eu estou querendo saber como posso excluir um diretório inteiro do meu diff Git. (Neste caso / especificação). Estou criando um diff para toda a versão do software usando o comando git diff. No entanto, as alterações nas especificações são irrelevantes para este procedimento e apenas criam dores de cabeça. agora eu sei que posso fazer

git diff previous_release..current_release app/

Isso criaria um diff para todas as alterações no diretório do aplicativo, mas não por exemplo, no diretório lib /. Alguém sabe como realizar esta tarefa? Obrigado!

Edit: Eu só quero ser claro, eu sei que posso apenas definir os parâmetros de todos os meus diretórios no final, menos / spec. Eu esperava que houvesse uma maneira de realmente excluir um único diretório no comando.

Mysrt
fonte
4
Eu encontrei essa pergunta incrível porque pretendia ignorar os submódulos . Nesse caso, se você é tão ingênuo quanto eu, essa pergunta pode ser mais útil.
Brandizzi
É estranho que ainda não tenhamos um comutador nativo do Git para fazer isso em set 2016
Michael Z

Respostas:

138

Supondo que você use o bash e tenha ativado o globbing estendido ( shopt -s extglob), você pode lidar com isso do lado do shell:

git diff previous_release current_release !(spec)

Economiza a necessidade de listar todas as outras coisas.

Ou, independente do shell:

git diff previous_release current_release --name-only | grep -v '^spec/' \
    | xargs git diff previous_release current_release --

Você pode agrupar isso em um script shell de uma linha para evitar ter que redigitar os argumentos.

Cascabel
fonte
1
O globbing do PS não corresponde aos arquivos ocultos; por isso, se você é obsessivo, convém usar .!(.|)tudo o que começa com um .sinal de adição .e ...
Cascabel
Isso não parece funcionar para arquivos que são totalmente novos ou excluídos nas ramificações. Eu recebo erros que interrompem a execução do script, dizendo que ele não pode ser diferente.
Graham Christensen
2
@ Graham: Eu acredito que o --que acabei de adicionar deve corrigir isso.
precisa
1
Resposta incrível. Eu só queria que os nomes aparecessem (não o diff real), então tive que adicionar --name-onlyno final também.
agosto
1
Depois de brincar com ele, só quero acrescentar que, se você alterar o nome de um arquivo, ele irá lançar um erro, mas tudo que você precisa fazer é adicionar -- path/of/new/filee ele vai descobrir isso :)
agosto
321

Baseado em nesta resposta, você também pode usar:

git diff previous_release..current_release -- . ':!spec'

Este é um recurso git recente que permite excluir certos caminhos. Deve ser mais confiável do que vários oneliners de casca.

Estou postando isso aqui, porque esta pergunta ainda é o hit nº 1 de "caminho de exclusão do diff do git".

cdleonard
fonte
4
Ame esta resposta. Se adicionar opções, faça-o antes do traço duplo. Por exemplo: git diff previous_release current_release --name-status -- . ':!spec'
liamvictor
Não sabia que eu poderia usar nomes de filial para o - current_releasee previous_releaseme fez sorrir quando descobri.
trueheart78
2
O que funcionou para mim git diff --stat dev -- . ':!/Mopy/Docs/*'. O que não funciona para mim git diff dev --stat -- . ':!('Mopy/Docs/Wrye Bash General Readme.html'|'Mopy/Docs/Wrye Bash Advanced Readme.html')'e variações
Mr_and_Mrs_D
Realmente util. Aqui está a sintaxe para ver se quaisquer arquivos são alterados, com excepção database.yml:git diff --check -- . ':!config/database.yml'
Dan Kohn
17
Também pode excluir vários itens como este:git diff previous_release current_release -- . ':!file_a' ':!file_b'
PseudoNoise
37

Se você deseja especificar mais de um caminho a ser excluído em um diff do git, basta adicionar parâmetros de exclusão adicionais ao final, por exemplo, para excluir tudo nos diretórios de fornecedores e bin das estatísticas: -

git diff --stat previous_release..current_release -- . ':!vendor' ':!bin'
David Graham
fonte
33

Você pode tentar desarmar o atributo diff para qualquer arquivo no diretório lib.
.gitattributes:

lib/* -diff

O racl101 acrescenta nos comentários :

Apenas para adicionar isso, para aqueles que desejam limitar a git diffsaída de arquivos de um tipo específico, dentro de um diretório específico e seus subdiretórios, como todo o JavaScript gerado pelo agrupamento de .jsarquivos do Webpack , por exemplo, você pode adicionar este para .gitattributes:

dist/js/**/*.js -diff

Então você não vê todo esse ruído na saída do git diff e apenas aparece como: o Binary files ... differque é mais útil.

VonC
fonte
isso removeria as especificações de todos os meus diffs. Eu ainda quero ver meus diffs na pasta especificação normalmente, só não quando eu estou correndo esta diff 'release'
Mysrt
2
@ Mystr: Você pode definir esse .gitattributesarquivo em uma ramificação especial feita apenas para este tipo de 'release' diff;) Rebase dessa ramificação especial em cima current_releasee fazer sua diff a partir daí.
VonC
Isso também não parece funcionar para arquivos que são excluídos entre ramificações. Os arquivos que foram removidos ainda mostram o diff completo.
Graham Christensen
Não funciona para mim. _ Caminhos são especiais? _site/* -diff
Marius
@MariusAndreiana Não, '_' não é especial. Você pode verificar que gitattributes Aplicar regra para um arquivo dessa pasta com: git-scm.com/docs/git-check-attr
VonC
22

Agora, o diff do Git aceita um formato de exclusão personalizado: git diff -- ':(exclude)lib/*'

Tenha cuidado se você tiver muitos nomes de pastas repetitivos ('/ app', '/ lib' etc.), pois isso excluirá arquivos relativos ao diretório de trabalho atual E ao diretório raiz do git.

MaxPRafferty
fonte
1
está faltando um ponto, não deveria git diff -- . ':(exclude)lib/*'?
Nicolas Dermine
1
@NicolasDermine Não, embora o que você escreveu seja equivalente. A parte "inclui" do caminho também é opcional. É por isso que você pode apenas fazer git diffpara tudo relativo ao seu caminho atual, em vez de exigirgit diff -- .
MaxPRafferty
Nota: nas máquinas Windows, use aspas duplas, comogit diff -- ":(exclude)lib/*"
cnlevy
Não sei por que, mas para mim funciona apenas com o ponto, conforme sugerido por @NicolasDermine. Eu uso o Cmder no win10.
Olivvv 27/01
3

Relativo ao diretório raiz do git

git diff aceita uma exclusão opcional

git diff -- ":(exclude)thingToExclude"

Você pode adicionar alguns curingas

git diff -- ":(exclude)*/thingToExclude/*"

Segmente tipos de arquivo específicos

git diff -- ":(exclude)*/$1/*.png"

Algum açúcar sintático aplicado

git diff -- ":!/\$1/"

Ou solte um pequeno script para seus dotfiles

Tais como .bash_profileou.zshrc

gde() {
    : '
        git diff exclude files or folders
        usage:
        gde fileOrFolderNameToExclude
    '
    git diff -- ":!/\$1/"
}
jasonleonhard
fonte
-6
git diff app lib
Jed Schneider
fonte