Chciałbym umieścić projekt Git na GitHub, ale zawiera on pewne pliki z wrażliwymi danymi (nazwy użytkowników i hasła, takie jak /config/deploy.rb dla capistrano).
Wiem, że mogę dodać te nazwy plików do .gitignore , ale nie usunęłoby to ich historii w Git.
Nie chcę też zaczynać od nowa, usuwając katalog /.git.
Czy istnieje sposób na usunięcie wszystkich śladów określonego pliku z historii Git?
Odpowiedzi:
Ze względów praktycznych pierwszą rzeczą, o którą powinieneś się martwić, jest ZMIANA HASŁA! Z twojego pytania nie wynika jasno, czy twoje repozytorium git jest całkowicie lokalne, czy też masz zdalne repozytorium gdzie indziej; jeśli jest zdalny i nie jest zabezpieczony przed innymi, masz problem. Jeśli ktokolwiek sklonował to repozytorium, zanim to naprawisz, będzie miał kopię twoich haseł na swoim komputerze lokalnym, i nie ma sposobu, aby zmusić ich do aktualizacji do „ustalonej” wersji, gdy zniknie z historii. Jedyną bezpieczną rzeczą, jaką możesz zrobić, jest zmiana hasła na coś innego, gdziekolwiek go użyjesz.
Aby to rozwiązać, oto jak to naprawić. GitHub odpowiedział dokładnie na to pytanie jako FAQ :
Uwaga dla użytkowników systemu Windows : w tym poleceniu używaj podwójnych cudzysłowów („) zamiast pojedynczych znaków
Aktualizacja 2019:
Oto aktualny kod z FAQ:
Pamiętaj, że po przekazaniu tego kodu do zdalnego repozytorium, takiego jak GitHub, a inni sklonowali to zdalne repozytorium, znajdujesz się w sytuacji, w której przepisujesz historię. Gdy inni spróbują później usunąć najnowsze zmiany, otrzymają komunikat informujący, że zmian nie można zastosować, ponieważ nie jest to przewijanie do przodu.
Aby to naprawić, będą musieli usunąć swoje istniejące repozytorium i ponownie je sklonować lub postępować zgodnie z instrukcjami w części „ODZYSKIWANIE Z REBASEU UPSTREAM” na stronie man git-rebase .
Wskazówka : Wykonaj
git rebase --interactive
W przyszłości, jeśli przypadkowo wprowadzisz pewne zmiany za pomocą poufnych informacji, ale zauważysz to przed wypchnięciem do zdalnego repozytorium, będzie kilka łatwiejszych poprawek. Jeśli ostatnim zatwierdzeniem jest dodanie poufnych informacji, możesz po prostu usunąć wrażliwe informacje, a następnie uruchomić:
Spowoduje to zmianę poprzedniego zatwierdzenia wszelkimi nowymi zmianami, które wprowadziłeś, w tym usunięcie całego pliku za pomocą
git rm
. Jeśli zmiany są dalej w historii, ale nadal nie są wypychane do zdalnego repozytorium, możesz wykonać interaktywną zmianę bazy:Spowoduje to otwarcie edytora z zatwierdzeniami dokonanymi od czasu ostatniego wspólnego przodka ze zdalnym repozytorium. Zmień „wybierz” na „edytuj” w dowolnym wierszu reprezentującym zatwierdzenie z poufnymi informacjami i zapisz i wyjdź. Git przejdzie przez zmiany i pozostawi cię w miejscu, w którym możesz:
Dla każdej zmiany z poufnymi informacjami. W końcu wrócisz do swojego oddziału i możesz bezpiecznie wprowadzać nowe zmiany.
źródło
filter-branch
kodem a tym na stronie github, do której prowadzisz link. Np. Ich trzecia linia--prune-empty --tag-name-filter cat -- --all
. Czy rozwiązanie się zmieniło, czy coś brakuje?<introduction-revision-sha1>..HEAD
, nie działa. Usuwa tylko plik od drugiego zatwierdzenia. (Jak włączyć początkowe zatwierdzenie do zakresu zatwierdzeń?) Sposób zapisywania jest wskazany tutaj: help.github.com/articles/…git filter-branch --force --index-filter \ 'git rm --cached --ignore-unmatch PATH-TO-YOUR-FILE-WITH-SENSITIVE-DATA' \ --prune-empty --tag-name-filter cat -- --all
Zmiana haseł jest dobrym pomysłem, ale do procesu usuwania haseł z historii repozytorium polecam BFG Repo-Cleaner , szybszą, prostszą alternatywę dla
git-filter-branch
jawnie zaprojektowanej do usuwania prywatnych danych z repozytoriów Git.Utwórz
private.txt
plik zawierający listę haseł itp., Które chcesz usunąć (jeden wpis w wierszu), a następnie uruchom następujące polecenie:Wszystkie pliki poniżej wielkości progowej (domyślnie 1 MB) w historii Twojego repozytorium zostaną przeskanowane, a każdy pasujący ciąg (który nie jest w twoim ostatnim zatwierdzeniu) zostanie zastąpiony ciągiem „*** REMOVED ***”. Następnie możesz użyć
git gc
do usunięcia martwych danych:BFG jest zwykle 10-50 razy szybszy niż uruchamianie,
git-filter-branch
a opcje są uproszczone i dostosowane do tych dwóch typowych przypadków użycia:Pełne ujawnienie: jestem autorem BFG Repo-Cleaner.
źródło
git commit
. W przeciwnym razie +1 za nowe narzędzie w przyborniku programisty :)These are your protected commits, and so their contents will NOT be altered
podczas przeglądania i przeglądania pozostałej historii zmian. Jeśli jednak chcesz cofnąć, to tak, musisz po prostu wyszukać***REMOVED***
w zatwierdzeniu, do którego właśnie wycofałeś.Jeśli przekazałeś do GitHub, wymuszone wypychanie nie wystarczy, usuń repozytorium lub skontaktuj się z obsługą
Nawet jeśli siłą naciskasz sekundę później, to nie wystarczy, jak wyjaśniono poniżej.
Jedyne ważne kierunki działania to:
co wyciekło zmienne dane uwierzytelniające, takie jak hasło?
nie (nagie zdjęcia):
obchodzi Cię, czy wszystkie problemy w repozytorium zostaną usunięte?
tak:
Siła pchania sekundę później nie wystarczy, ponieważ:
GitHub od dłuższego czasu zwisają zobowiązania.
Pracownicy GitHub są w stanie usunąć takie zwisające zatwierdzenia, jeśli się z nimi skontaktujesz.
Doświadczyłem tego z pierwszej ręki, gdy przesłałem wszystkie wiadomości e-mail z zatwierdzeniami GitHub do repozytorium, które poprosiły mnie o usunięcie, więc zrobiłem to i zrobili to
gc
. Żądania ściągnięcia zawierające dane muszą jednak zostać usunięte : dane repo pozostały dostępne przez rok po pierwszym usunięciu z tego powodu.Zwisające zatwierdzenia można zobaczyć poprzez:
Jednym wygodnym sposobem uzyskania źródła przy tym zatwierdzeniu jest użycie metody zip zip, która może zaakceptować dowolne odniesienie, np .: https://github.com/cirosantilli/myrepo/archive/SHA.zip
Możliwe jest pobranie brakujących SHA poprzez:
type": "PushEvent"
. Np. Moja: https://api.github.com/users/cirosantilli/events/public ( maszyna Wayback )Istnieją skrobaki, takie jak http://ghtorrent.org/ i https://www.githubarchive.org/ które regularnie gromadzą dane GitHub i przechowują je gdzie indziej.
Nie mogłem znaleźć, czy zeskrobują rzeczywistą różnicę zatwierdzeń, i jest to mało prawdopodobne, ponieważ byłoby zbyt wiele danych, ale jest to technicznie możliwe, a NSA i przyjaciele prawdopodobnie mają filtry do archiwizowania tylko rzeczy powiązanych z osobami lub zainteresowaniami.
Jeśli usuniesz repozytorium zamiast tylko wymuszać wypychanie, zatwierdzenia znikają natychmiast nawet z interfejsu API i dają 404, np. Https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 Ten działa nawet jeśli odtworzysz inne repozytorium o tej samej nazwie.
Aby to przetestować, utworzyłem repozytorium: https://github.com/cirosantilli/test-dangling i zrobiłem:
Zobacz także: Jak usunąć wiszące zatwierdzenie z GitHub?
źródło
Polecam ten skrypt Davida Underhilla, który działał dla mnie jak urok.
Dodaje te polecenia dodatkowo do gałęzi filtrów natacado, aby oczyścić bałagan, który pozostawia:
Pełny scenariusz (podziękowania dla Davida Underhilla)
Ostatnie dwa polecenia mogą działać lepiej, jeśli zostaną zmienione na następujące:
źródło
git gc --aggressive --prune=now
Żeby było jasne: zaakceptowana odpowiedź jest poprawna. Wypróbuj najpierw. Jednak w niektórych przypadkach użycia może być niepotrzebnie skomplikowany, szczególnie jeśli napotkasz nieprzyjemne błędy, takie jak „fatal: bad revision - prune-empty” lub naprawdę nie zależy ci na historii twojego repozytorium.
Alternatywą byłoby:
Spowoduje to oczywiście usunięcie wszystkich gałęzi historii zatwierdzeń i problemów zarówno z repozytorium github, jak i lokalnego repozytorium git. Jeśli jest to nie do przyjęcia, będziesz musiał zastosować alternatywne podejście.
Nazwij to opcją nuklearną.
źródło
Możesz użyć
git forget-blob
.Użycie jest dość proste
git forget-blob file-to-forget
. Możesz uzyskać więcej informacji tutajhttps://ownyourbits.com/2017/01/18/completely-remove-a-file-from-a-git-repository-with-git-forget-blob/
Zniknie ze wszystkich zmian w historii, przelogowaniu, tagach i tak dalej
Od czasu do czasu napotykam ten sam problem i za każdym razem, gdy muszę wracać do tego postu i innych, dlatego zautomatyzowałem ten proces.
Kredyty dla autorów z Stack Overflow, które pozwoliły mi to połączyć
źródło
Oto moje rozwiązanie w systemie Windows
upewnij się, że ścieżka jest poprawna, w przeciwnym razie nie zadziała
Mam nadzieję, że to pomoże
źródło
Użyj gałęzi filter :
źródło
Do tej pory musiałem to zrobić kilka razy. Pamiętaj, że działa to tylko na 1 pliku na raz.
Uzyskaj listę wszystkich zatwierdzeń, które zmodyfikowały plik. Ten na dole będzie pierwszym zatwierdzeniem:
git log --pretty=oneline --branches -- pathToFile
Aby usunąć plik z historii, użyj pierwszego zatwierdzenia sha1 i ścieżki do pliku z poprzedniego polecenia i wypełnij je tym poleceniem:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
źródło
Wygląda to mniej więcej tak:
źródło
W moim projekcie na Androida miałem admob_keys.xml jako oddzielny plik xml w folderze app / src / main / res / values / . Aby usunąć ten wrażliwy plik, użyłem poniżej skryptu i działałem idealnie.
źródło