Adicionar todos os arquivos a uma confirmação, exceto um único arquivo?

571

Eu tenho vários arquivos em um conjunto de alterações, mas quero ignorar especificamente um único arquivo modificado. É assim depois de git status:

# modified:   main/dontcheckmein.txt
# deleted:    main/plzcheckmein.c
# deleted:    main/plzcheckmein2.c
...

Existe uma maneira de fazer isso, git addmas simplesmente ignore o arquivo de texto que não quero tocar? Algo como:

git add -u -except main/dontcheckmein.txt
user291701
fonte

Respostas:

851
git add -u
git reset -- main/dontcheckmein.txt
Ben Jackson
fonte
28
como faço para excluir a pasta inteira? - principal ou principal / ou principal / *?
Alan Coromano
8
@MariusKavansky Você pode usar todos esses formulários. Se você usar main/*, é necessário adicionar --na frente dele para que o git saiba que é um caminho. As outras duas variantes funcionam sem incluir os dois traços. (Testado no prompt de comando no Windows 7 com msysGit)
dennisschagt
2
Se você deseja excluir algumas pastas que contêm uma grande quantidade de arquivos ou outras pastas: adicione-as temporariamente ao seu gitignore. executar um git resetpara essas pastas posteriormente ainda funcionará, mas levará muito tempo para o git adicionar as pastas grandes.
Michael Trouw
2
Então, não há uma fila?
BroVic
5
@ Ben Jackson seria bom comentar cada linha, você não acha?
Ed1nh0 25/09/19
140

1) Para começar a ignorar as alterações em um único arquivo já com versão

git update-index --assume-unchanged "main/dontcheckmein.txt"

e desfazer isso git update-index --no-assume-unchanged "main/dontcheckmein.txt"

docs do github para ignorar arquivos

2) Para ignorar completamente um único arquivo específico, impedindo que ele seja criado no repositório

Primeiro, veja esta postagem do stackoverflow: o Git global ignore não está funcionando

Em .gitignore, adicione o caminho relativo ao arquivo sem avanço ./.

Portanto, se seu arquivo estiver em MyProject/MyFolder/myfile.txt(onde .gittambém está oMyProject pasta), adicione MyFolder/myfile.txtao seu .gitignorearquivo at .

Você pode confirmar quais regras estão associadas a ignorar via git check-ignore "MyFolder/myfile.txt"

Sobre ignorar global

Esse link fala sobre ~/.gitignore_global, mas o arquivo está relacionado ao seu projeto. Portanto, se você colocar o padrão de exclusão MyFolder/myfile.txtem~/.gitignore_global , ele vai trabalhar, mas não fará muito sentido ...

Por outro lado, se você configurar seu projeto com git config core.excludesfile .gitignoreonde .gitignoreestá MyProject, o arquivo local será substituído ~/.gitignore_global, o que pode ter regras muito úteis ...

Então, por enquanto, acho que é melhor criar um script para misturar o seu .gitignorecom o ~/.gitignore_globalat .gitignore.

Um último aviso
Se o arquivo que você deseja ignorar já estiver no repositório, esse método não funcionará, a menos que você faça o seguinte: faça git rm "MyFolder/myfile.txt"o backup primeiro, pois ele também será removido localmente! Você pode copiá-lo mais tarde ...

Aquarius Power
fonte
5
Você pode usar git rm --cached MyFolder/myyfile.txtpara remover o arquivo do repositório, mas mantê-lo localmente. Explicação em help.github.com
dennisschagt
87

Para um arquivo

git add -u
git reset -- main/dontcheckmein.txt

Para uma pasta

git add -u
git reset -- main/*
Rituraj ratan
fonte
9
por que o -u é necessário? por que não git add . && git reset -- main/*?
2
A opção -u atualiza o índice exatamente onde ele já possui uma entrada correspondente a <pathspec>. Isso remove e modifica as entradas do índice para corresponder à árvore de trabalho, mas não adiciona novos arquivos. Se nenhum <pathspec> for fornecido quando a opção -u for usada, todos os arquivos rastreados em toda a árvore de trabalho serão atualizados (versões antigas do Git usadas para limitar a atualização ao diretório atual e seus subdiretórios).
Farhad Mammadli
6
Alguém pode explicar por que o -u é necessário em uma linguagem que os profissionais não-git entenderão?
Patrick
2
-u é usado para referenciar sua ramificação atual para a qual você está pressionando. Você não precisará mais digitar git push origin masterseu próximo push, apenas o git pushgit saberá que é isso no ramo principal. Espero que ajude.
Pepeng Hapon
69

Agora gitsuporta exclude certain paths and filespela pathspec magic :(exclude)e sua forma abreviada :!. Assim, você pode facilmente alcançá-lo como o seguinte comando.

git add --all -- :!main/dontcheckmein.txt
git add -- . :!main/dontcheckmein.txt

Na verdade, você pode especificar mais:

git add --all -- :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
git add -- . :!path/to/file1 :!path/to/file2 :!path/to/folder1/*
olhos de gato
fonte
1
A melhor resposta, obrigado! Pelo menos para o meu caso: eu precisava apenas excluir um tipo de arquivo.
22818 Andre Polykanine
15
Isto e excelente! Observe que no Linux, você precisa citar as :!...cláusulas para evitar que o shell se queixe. Assim, por exemplo: git add --all -- ':!path/to/file1' ':!path/to/file2' ':!path/to/folder1/*'.
Martin_W
Existe algo parecido :!/path/to/(file1|file2)?
Seeker_of_bacon 03/07/19
Isso colide com algo no zsh, não funciona para mim no macOS e no git mais recente.
Merlin
1
Alguém pode apontar para onde isso está oficialmente documentado?
samurai_jane 24/04
20

Enquanto Ben Jackson está correto, pensei em acrescentar como tenho usado essa solução também. Abaixo está um script muito simples que eu uso (que chamo de gitadd) para adicionar todas as alterações, exceto algumas poucas que eu continuo listadas em um arquivo chamado .gittrackignore(muito parecido com o funcionamento do .gitignore).

#!/bin/bash
set -e

git add -A
git reset `cat .gittrackignore`

E é assim que minha .gittrackignoreaparência atual .

project.properties

Estou trabalhando em um projeto Android que eu compilo na linha de comando ao implantar. Este projeto depende do SherlockActionBar, portanto ele precisa ser referenciado em project.properties, mas isso interfere com a compilação; agora, apenas digito gitadde adiciono todas as alterações ao git sem ter que desinstalar project.properties todas as vezes.

Anthony Naddeo
fonte
Eu não sabia o que --era até o seu comentário. De acordo com as páginas do manual, é opcional e não altera o resultado do comando (pelo menos neste caso). Esta questão parece apoiar isso, stackoverflow.com/questions/17800994/… . Corrija-me se eu estiver errado, mas parece que isso significa "qualquer coisa deleite depois --como argumentos, não Opções / desliga"
Anthony Naddeo
Bom uso --no git checkoutque vejo nessa pergunta. Eu não sabia o que era a corrida dupla até essa nossa troca também. Eu me pergunto se a git checkoutambiguidade entre ramificações e arquivos poderia afetar, nesta ou em uma forma diferente, git resettambém.
Giulio Piancastelli
10

Para manter a alteração no arquivo, mas não confirmar, fiz isso

git add .

git reset -- main/dontcheckmein.txt

git commit -m "commit message"

para verificar se o arquivo está excluído, faça

git status

gsumk
fonte
4

Use git add -Apara adicionar todos os arquivos modificados e recém-adicionados de uma só vez.

Exemplo

git add -A
git reset -- main/dontcheckmein.txt
Dhanuka Nuwan
fonte
4
git add .
git reset main/dontcheckmein.txt
Daniel Danielecki
fonte
2

Tente o seguinte:

git checkout -- main/dontcheckmein.txt
Abdullah Aman
fonte
1
isso desfará todas as alterações main / dontcheckmein.txt.
gsumk
stackoverflow.com/questions/41101998/… Isso desfará as alterações
Dhanapal 03/03
1

Para o caso específico da pergunta, a maneira mais fácil seria adicionar todos os arquivos com extensão .c e deixar de fora todo o resto:

git add *.c

Do git-scm (ou / e man git add):

git add <pathspec>…

Arquivos para adicionar conteúdo. Fileglobs (por exemplo, * .c) podem ser fornecidos para adicionar todos os arquivos correspondentes. <...>

Observe que isso significa que você também pode fazer algo como:

git add **/main/*

para adicionar todos os arquivos (que não são ignorados) que estão na mainpasta. Você pode até enlouquecer com padrões mais elaborados:

git add **/s?c/*Service*

O acima irá adicionar todos os arquivos que estão na s(any char)cpasta e têm Servicealgum lugar em seu nome de arquivo.

Obviamente, você não está limitado a um padrão por comando. Ou seja, você pode pedir ao git para adicionar todos os arquivos com uma extensão .c e .h :

git add *.c *.h

Esse link pode fornecer mais algumas idéias de padrões globais.

Acho isso particularmente útil quando estou fazendo muitas alterações, mas ainda quero que meus compromissos permaneçam atômicos e reflitam um processo gradual, em vez de uma mistura de mudanças que eu possa estar trabalhando no momento. Obviamente, em algum momento, o custo de criar padrões elaborados supera o custo de adicionar arquivos com métodos mais simples, ou mesmo um arquivo por vez. No entanto, na maioria das vezes, sou facilmente capaz de identificar apenas os arquivos necessários com um padrão simples e excluir todo o resto.

A propósito, você pode precisar citar seus padrões glob para que funcionem, mas isso nunca foi o meu caso.

Cegas
fonte
0

Eu uso git add --patchum pouco e queria algo assim para evitar ter que acessar do tempo todo os mesmos arquivos. Criei um par de aliases git muito hacky para fazer o trabalho:

[alias]
    HELPER-CHANGED-FILTERED = "!f() { git status --porcelain | cut -c4- | ( [[ \"$1\" ]] && egrep -v \"$1\" || cat ); }; f"
    ap                      = "!git add --patch -- $(git HELPER-CHANGED-FILTERED 'min.(js|css)$' || echo 'THIS_FILE_PROBABLY_DOESNT_EXIST' )"

No meu caso, eu só queria ignorar certos arquivos minificados o tempo todo, mas você poderia fazê-lo usar uma variável de ambiente como $GIT_EXCLUDE_PATTERNpara um caso de uso mais geral.

Chris
fonte
0

Alterações a serem confirmadas: (use "git reset HEAD ..." para unstage)

colin rickels
fonte
0

Você pode tentar isso: git add * && git reset main/dontcheckmein.txt

Rodrigo
fonte