Remova o diretório do repositório remoto após adicioná-los ao .gitignore

599

Eu cometi e enviei algum diretório para o github. Depois disso, alterei o .gitignorearquivo adicionando um diretório que deveria ser ignorado. Tudo funciona bem, mas o diretório (agora ignorado) permanece no github.

Como excluo esse diretório do github e do histórico do repositório?

janw
fonte

Respostas:

1067

As regras do seu .gitignorearquivo se aplicam apenas a arquivos não rastreados. Como os arquivos nesse diretório já foram confirmados em seu repositório, você deve desestabilizá-los, criar uma confirmação e enviar por push para o GitHub:

git rm -r --cached some-directory
git commit -m 'Remove the now ignored directory "some-directory"'
git push origin master

Você não pode excluir o arquivo do seu histórico sem reescrever o histórico do seu repositório - você não deve fazer isso se mais alguém estiver trabalhando com o seu repositório ou se estiver usando-o em vários computadores. Se você ainda deseja fazer isso, pode git filter-branchreescrever a história - há um guia útil para isso aqui .

Além disso, observe que a saída de git rm -r --cached some-directoryserá algo como:

rm 'some-directory/product/cache/1/small_image/130x130/small_image.jpg'
rm 'some-directory/product/cache/1/small_image/135x/small_image.jpg'
rm 'some-directory/.htaccess'
rm 'some-directory/logo.jpg'

O rmfeedback é do git sobre o repositório; os arquivos ainda estão no diretório de trabalho.

Mark Longair
fonte
3
Se alguém puxar, os arquivos agora ignorados serão excluídos ou permanecerão intocados?
Martin Konicek
3
@ Martin Konicek: se o usuário que está executando essas alterações não tiver modificações nesses arquivos, elas serão removidas.
precisa saber é o seguinte
@MarkLongair O que faz -re --cached. Obrigado.
Labanino 28/08
13
@ Labanino: -rsignifica recursivo, necessário se você estiver criando diretórios inteiros. --cachedsubstitui o comportamento normal do git de excluí-los do diretório de trabalho e preparar a exclusão para confirmação, e faz com que o git opere apenas na área de preparação pronta para confirmação. É assim que você diz ao git que deseja manter suas cópias locais dos arquivos.
entheh
2
Este agradável funciona, mas eu tinha que fazer primeiro: git reset name_of_filepara o que está descrito acima para o trabalho
Edvard Haugland
248

Eu faço isso:

git rm --cached `git ls-files -i --exclude-from=.gitignore` 
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master

O que removerá todos os arquivos / pastas que estão no seu git ignorados, economizando que você precise escolher cada um manualmente


Isso parece ter parado de funcionar para mim, agora:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master
Blundell
fonte
4
Obrigado, isso me ajudou muito! Se você estiver usando o Windows PowerShell, você pode fazerforeach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Matthew
10
Tentei sua segunda abordagem, ele removeu todos os arquivos do meu git local!
Artnikpro
2
Eu acho que você deveria navegar para o subdiretório e fazê-lo. Corrija-me se eu estiver errado.
Então, o que aprendemos hoje, crianças? "Não execute código aleatório encontrado no Stack Overflow!"
Jonathan Landrum
49

De acordo com minha resposta aqui: Como remover um diretório do repositório git?

Para remover a pasta / diretório apenas do repositório git e não do local, tente 3 etapas simples.


Etapas para remover o diretório

git rm -r --cached FolderName
git commit -m "Removed folder from repository"
git push origin master

Etapas para ignorar essa pasta nas próximas confirmações

Para ignorar essa pasta das próximas confirmações, crie um arquivo na raiz chamado .gitignore e coloque o nome dessa pasta nela. Você pode colocar quantas quiser

O arquivo .gitignore ficará assim

/FolderName

remover diretório

eirenaios
fonte
1
Era exatamente isso que eu estava procurando. Obrigado :)
Rohit Singh
Estou feliz que ajudou @Rohit Singh
eirenaios
9

A primeira resposta de Blundell não funcionou para mim. No entanto, me mostrou o caminho certo. Eu fiz a mesma coisa assim:

> for i in `git ls-files -i --exclude-from=.gitignore`; do git rm --cached $i; done
> git commit -m 'Removed all files that are in the .gitignore'
> git push origin master

Aconselho que você verifique primeiro os arquivos a serem excluídos executando a instrução abaixo:

git ls-files -i --exclude-from=.gitignore

Eu estava usando um arquivo .gitignore padrão para o visual studio e notei que ele estava removendo todas as pastas de log e bin do projeto, o que não era minha ação pretendida.

Oncel Umut TURER
fonte
5

Nota: Esta solução funciona apenas com a GUI do Github Desktop .

Ao usar a GUI do Github Desktop , é muito simples.

  1. Mova a pasta para outro local (para fora da pasta do projeto) temporariamente.

  2. Edite seu .gitignorearquivo e remova a entrada da pasta que seria remover o repositório principal na página do github.

  3. Confirme e sincronize a pasta do projeto.

  4. Mover novamente a pasta para a pasta do projeto

  5. Reedite o .gitignorearquivo.

Isso é tudo.

efkan
fonte
5

A resposta de Blundell deve funcionar, mas por algum motivo bizarro, isso não aconteceu comigo. Eu tive que canalizar primeiro os nomes dos arquivos gerados pelo primeiro comando em um arquivo e depois percorrer o arquivo e excluí-lo um por um.

git ls-files -i --exclude-from=.gitignore > to_remove.txt
while read line; do `git rm -r --cached "$line"`; done < to_remove.txt
rm to_remove.txt
git commit -m 'Removed all files that are in the .gitignore' 
git push origin master
Chris Aelbrecht
fonte
4

Este método aplica o comportamento padrão do .gitignore e não requer a especificação manual dos arquivos que precisam ser ignorados .

Não é --exclude-from=.gitignoremais possível usar : / - Aqui está o método atualizado:

Conselho geral: comece com um repositório limpo - tudo comprometido, nada pendente no diretório ou índice de trabalho e faça um backup !

#commit up-to-date .gitignore (if not already existing)
#this command must be run on each branch
git add .gitignore
git commit -m "Create .gitignore"

#apply standard git ignore behavior only to current index, not working directory (--cached)
#if this command returns nothing, ensure /.git/info/exclude AND/OR .gitignore exist
#this command must be run on each branch
git ls-files -z --ignored --exclude-standard | xargs -0 git rm --cached

#optionally add anything to the index that was previously ignored but now shouldn't be:
git add *

#commit again
#optionally use the --amend flag to merge this commit with the previous one instead of creating 2 commits.

git commit -m "re-applied modified .gitignore"

#other devs who pull after this commit is pushed will see the  newly-.gitignored files DELETED

Se você também precisar limpar os arquivos recém-ignorados do histórico de consolidação da filial ou se não desejar que os arquivos recém-ignorados sejam excluídos de futuras tentativas , consulte esta resposta .

goofology
fonte
0

Se você estiver trabalhando no PowerShell, tente o seguinte como um único comando.

PS MyRepo> git filter-branch --force --index-filter
>> "git rm --cached --ignore-unmatch -r .\\\path\\\to\\\directory"
>> --prune-empty --tag-name-filter cat -- --all

Então git push --force --all,.

Documentação: https://git-scm.com/docs/git-filter-branch

Shaun Luttin
fonte
Qual é a git filter-branchdiferença entre usar e usar git rm? Eu estava originalmente pensando que tinha que usar uma versão, git filter-branchmas a maioria dos comentários aqui recomenda o uso git rm. Pelo que entendi, git rmapenas o remove do diretório e índice de trabalho atuais. Mas se seu múltiplo adicionado foi confirmado antes, ele ainda estará no repositório.
alpha_989
Direita. git rmremoverá o arquivo da confirmação mais recente no futuro. git filter-branchvamos removê-lo de toda a história. Veja também: help.github.com/articles/…
Shaun Luttin