Usuń katalog ze zdalnego repozytorium po dodaniu go do .gitignore

597

Popełniłem i wysłałem katalog do github. Następnie zmieniłem .gitignoreplik, dodając katalog, który należy zignorować. Wszystko działa dobrze, ale katalog (teraz ignorowany) pozostaje na github.

Jak usunąć ten katalog z github i historii repozytorium?

janw
źródło

Odpowiedzi:

1065

Reguły w Twoim .gitignorepliku dotyczą tylko plików nieśledzonych. Ponieważ pliki w tym katalogu zostały już zatwierdzone w Twoim repozytorium, musisz je wycofać, utworzyć zatwierdzenie i przekazać je do GitHub:

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

Nie możesz usunąć pliku ze swojej historii bez przepisania historii swojego repozytorium - nie powinieneś tego robić, jeśli ktoś inny pracuje z twoim repozytorium lub używasz go z wielu komputerów. Jeśli nadal chcesz to zrobić, możesz użyć git filter-branchdo przepisania historii - tutaj znajdziesz pomocny przewodnik .

Dodatkowo pamiętaj, że dane wyjściowe git rm -r --cached some-directorybędą takie jak:

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'

Informacje rmzwrotne od git na temat repozytorium; pliki nadal znajdują się w katalogu roboczym.

Mark Longair
źródło
3
Jeśli ktoś inny wyciągnie, czy teraz zignorowane pliki zostaną dla niego usunięte, czy pozostaną nietknięte?
Martin Konicek,
3
@Martin Konicek: jeśli użytkownik, który pobiera te zmiany, nie modyfikuje tych plików, zostaną one usunięte.
Mark Longair,
@MarkLongair Co robi -ri --cached. Dzięki.
Labanino
12
@Labanino: -roznacza rekurencyjne, konieczne, jeśli robisz całe katalogi. --cachedzastępuje normalne zachowanie git polegające na usuwaniu ich z katalogu roboczego i ustawianiu usuwania w celu zatwierdzenia, i sprawia, że ​​git działa tylko na obszarze testowym gotowym do zatwierdzenia. W ten sposób mówisz git, że chcesz zachować lokalne kopie plików.
entheh
2
Działa to dobrze, ale najpierw musiałem to zrobić: git reset name_of_fileaby to, co opisano powyżej, zadziałało
Edvard Haugland,
248

Robię to:

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

Które usunie wszystkie pliki / foldery, które są w twoim git ignorują, oszczędzając musisz wybierać każdy ręcznie


Wydaje się, że przestało to dla mnie działać, teraz:

 git rm -r --cached . 
 git add .
 git commit -m 'Removed all files that are in the .gitignore' 
 git push origin master
Blundell
źródło
4
Dzięki, bardzo mi to pomogło! Jeśli używasz Windows PowerShell, możesz to zrobićforeach ($i in iex 'git ls-files -i --exclude-from=.gitignore') { git rm --cached $i }
Matthew
10
Wypróbowałem twoje drugie podejście, usunęło wszystkie pliki z mojego lokalnego gita!
artnikpro
2
Myślę, że powinieneś przejść do podkatalogu i to zrobić. Popraw mnie, jeśli się mylę.
Czego się dzisiaj nauczyliśmy, dzieci? „Nie uruchamiaj losowego kodu, który znajdziesz w przepełnieniu stosu!”
Jonathan Landrum
49

Jak na moją odpowiedź tutaj: Jak usunąć katalog z repozytorium git?

Aby usunąć folder / katalog tylko z repozytorium git, a nie z lokalnego, spróbuj 3 prostych kroków.


Kroki, aby usunąć katalog

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

Kroki, aby zignorować ten folder w kolejnych zatwierdzeniach

Aby zignorować ten folder od następnych zatwierdzeń, utwórz jeden plik w katalogu głównym o nazwie .gitignore i umieść w nim nazwę tego folderu. Możesz umieścić tyle, ile chcesz

Plik .gitignore będzie wyglądał następująco

/FolderName

usuń katalog

eirenaios
źródło
1
Właśnie tego szukałem. Dzięki :)
Rohit Singh
Cieszę się, że pomogło @Rohit Singh
eirenaios
9

Pierwsza odpowiedź Blundella nie zadziałała dla mnie. Jednak pokazało mi to właściwą drogę. Zrobiłem to samo:

> 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

Radzę najpierw sprawdzić pliki do usunięcia, uruchamiając poniższą instrukcję:

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

Używałem domyślnego pliku .gitignore dla Visual Studio i zauważyłem, że usuwa on wszystkie foldery dziennika i bin w projekcie, co nie było moim zamierzonym działaniem.

Oncel Umut TURER
źródło
5

Uwaga: To rozwiązanie działa tylko z graficznym interfejsem użytkownika Github .

Korzystanie z graficznego interfejsu użytkownika Github jest bardzo proste.

  1. Tymczasowo przenieś folder do innej lokalizacji (poza folder projektu).

  2. Edytuj .gitignoreplik i usuń pozycję folderu, która byłaby usunięciem głównego repozytorium na stronie github.

  3. Zatwierdź i zsynchronizuj folder projektu.

  4. Ponownie przenieś folder do folderu projektu

  5. Ponownie edytuj .gitignoreplik.

To wszystko.

efkan
źródło
5

Odpowiedź Blundella powinna zadziałać, ale z jakiegoś dziwnego powodu nie zadziałała ze mną. Musiałem najpierw potokować nazwy plików wyprowadzone przez pierwsze polecenie do pliku, a następnie przejść przez ten plik i usunąć go jeden po drugim.

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
źródło
4

Ta metoda stosuje standardowe zachowanie .gitignore i nie wymaga ręcznego określania plików, które należy zignorować .

Nie można --exclude-from=.gitignorejuż używać : / - Oto zaktualizowana metoda:

Porady ogólne: zacznij od czystego repo - wszystko zostało popełnione, nic nie czeka w katalogu roboczym lub indeksie i wykonaj kopię zapasową !

#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

Jeśli musisz również usunąć nowo zignorowane pliki z historii zatwierdzeń oddziału lub jeśli nie chcesz, aby nowo zignorowane pliki zostały usunięte z przyszłych operacji pobierania , zapoznaj się z tą odpowiedzią .

goofologia
źródło
0

Jeśli pracujesz z PowerShell, spróbuj wykonać następujące czynności jako jedno polecenie.

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

Potem git push --force --all.

Dokumentacja: https://git-scm.com/docs/git-filter-branch

Shaun Luttin
źródło
Czym git filter-branchróżni się używanie od używania git rm? Początkowo myślałem, że muszę użyć wersji, git filter-branchale większość komentarzy tutaj zaleca użycie git rm. Z tego co rozumiem, git rmusuwa to tylko z bieżącego katalogu roboczego i indeksu. Ale jeśli dodano wcześniej wiele zatwierdzeń, nadal będzie w repozytorium.
alpha_989
Dobrze. git rmusunie plik z ostatniego zatwierdzenia w przyszłości. git filter-branchpozwala nam usunąć go z całej historii. Zobacz także: help.github.com/articles/…
Shaun Luttin