Usuń poufne pliki i ich commity z historii Gita
Chciałbym umieścić projekt Gita na Githubie, ale zawiera on pewne pliki z poufnymi danymi (nazwy użytkowników i hasła, jak /config / deploy.rb dla capistrano).
Wiem, że mogę dodać te nazwy plików do .gitignore , ale to nie usunie ich historii w Git.
Nie chcę też zaczynać od nowa usuwając /.katalog git.
Czy istnieje sposób na usunięcie wszystkich śladów konkretnego pliku w historii Gita?
10 answers
Dla wszystkich praktycznych celów, pierwszą rzeczą, którą powinieneś się martwić, jest zmiana haseł! z twojego pytania nie wynika, czy Twoje repozytorium git jest całkowicie lokalne, czy też masz zdalne repozytorium gdzie indziej; jeśli jest zdalne i nie jest zabezpieczone przed innymi, masz problem. Jeśli ktoś sklonował to repozytorium, zanim to naprawisz, będzie miał kopię Twoich haseł na swoim lokalnym komputerze i nie ma sposobu, aby zmusić go do aktualizacji do twoja "naprawiona" wersja z nią odeszła z historii. Jedyną bezpieczną rzeczą, którą możesz zrobić, jest zmiana hasła na coś innego wszędzie, gdzie go używasz.
Z tym na uboczu, oto jak to naprawić. GitHub odpowiedział dokładnie na to pytanie jako FAQ :
Uwaga dla użytkowników systemu Windows : użyj podwójnych cudzysłowów (") zamiast singli w tym poleceniu
git filter-branch --index-filter \
'git update-index --remove filename' <introduction-revision-sha1>..HEAD
git push --force --verbose --dry-run
git push --force
Należy pamiętać, że po wypchnięciu tego kodu do zdalnego repozytorium, takiego jak GitHub i inne mają sklonowane zdalne repozytorium, jesteś teraz w sytuacji, gdy przepisujesz historię. Gdy inni spróbują wyciągnąć najnowsze zmiany po tym, otrzymają komunikat informujący, że zmiany nie mogą być zastosowane, ponieważ nie jest to przewijanie do przodu.
Aby to naprawić, będą musieli albo usunąć istniejące repozytorium i sklonować je ponownie, albo postępować zgodnie z instrukcjami w sekcji "odzyskiwanie z rebase' U " na stronie Man git-rebase.
W przyszłości, jeśli przypadkowo Zatwierdź niektóre zmiany wrażliwymi informacjami, ale zauważysz przed przepchnięciem do zdalnego repozytorium, są pewne łatwiejsze poprawki. Jeśli ostatni commit jest Tym, który dodaje poufne informacje, możesz po prostu usunąć poufne informacje, a następnie uruchomić:
git commit -a --amend
, które zmienią poprzedni commit o wszelkie nowe zmiany, w tym usunięcie całego pliku za pomocą git rm
. Jeśli zmiany są dalej w historii, ale nadal nie pchane do zdalnego repozytorium, możesz zrobić interaktywną rebase:
git rebase -i origin/master
Otwiera edytor z zatwierdzeniami, które wprowadziłeś od ostatniego wspólnego przodka ze zdalnym repozytorium. Zmień "pick" na "edit" W dowolnej linii reprezentującej commit z poufnymi informacjami, a następnie zapisz i zakończ. Git przejdzie przez zmiany i pozostawi cię w miejscu, w którym możesz:
$EDITOR file-to-fix
git commit -a --amend
git rebase --continue
Dla każdej zmiany z wrażliwymi informacjami. W końcu wylądujesz z powrotem na swojej gałęzi i możesz bezpiecznie popchnąć nowy zmiany.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 12:16:07
Zmiana haseł jest dobrym pomysłem, ale w procesie usuwania haseł z historii repo, polecam BFG Repo-Cleaner, szybszą i prostszą alternatywę dla git-filter-branch
zaprojektowaną do usuwania prywatnych danych z Git repos.
Utwórz plik private.txt
z listą haseł itp., które chcesz usunąć (jeden wpis w linii), a następnie uruchom następujące polecenie:
$ java -jar bfg.jar --replace-text private.txt my-repo.git
Wszystkie pliki poniżej progu (domyślnie 1MB) w historii repo będą zeskanowany, a każdy pasujący ciąg znaków (który nie znajduje się w Twoim najnowszym commicie) zostanie zastąpiony ciągiem "***REMOVED***". Następnie możesz użyć git gc
, Aby wyczyścić martwe dane:
$ git gc --prune=now --aggressive
BFG jest zwykle 10-50x szybszy niż działanie git-filter-branch
, A opcje są uproszczone i dopasowane do tych dwóch powszechnych przypadków użycia:
- Usuwanie Crazy Big Files
- usuwanie haseł, poświadczeń i innych prywatnych dane
pełne ujawnienie: jestem autorem BFG Repo-Cleaner.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-11 06:41:03
Polecam ten skrypt autorstwa Davida Underhilla, zadziałał jak urok dla mnie.
Dodaje te polecenia w dodatku natacado filter-branch, aby oczyścić bałagan, który pozostawia po sobie:
rm -rf .git/refs/original/
git reflog expire --all
git gc --aggressive --prune
Pełny scenariusz (wszystkie podziękowania dla Davida Underhilla)
#!/bin/bash
set -o errexit
# Author: David Underhill
# Script to permanently delete files/folders from your git repository. To use
# it, cd to your repository's root and then run the script with a list of paths
# you want to delete, e.g., git-delete-history path1 path2
if [ $# -eq 0 ]; then
exit 0
fi
# make sure we're at the root of git repo
if [ ! -d .git ]; then
echo "Error: must run this script from the root of a git repository"
exit 1
fi
# remove all paths passed as arguments from the history of the repo
files=$@
git filter-branch --index-filter \
"git rm -rf --cached --ignore-unmatch $files" HEAD
# remove the temporary history git-filter-branch
# otherwise leaves behind for a long time
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune
Ostatnie dwa polecenia mogą działać lepiej, jeśli zostaną zmienione na następujące:
git reflog expire --expire=now --all && \
git gc --aggressive --prune=now
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-14 03:53:50
Jeśli już nacisnąłeś na GitHub, dane są zagrożone, nawet jeśli wymusisz wypchnięcie ich sekundę później Ponieważ:
-
GitHub długo trzyma commity.
Obsługa Githuba ma prawo usunąć takie zwisające commity, jeśli się z nimi skontaktujesz, co powinieneś zrobić: Jak usunąć zwisający commit z Githuba?
Zwisające commity można zobaczyć poprzez:
- commit Web UI: https://github.com/cirosantilli/test-dangling/commit/53df36c09f092bbb59f2faa34eba15cd89ef8e83 (Wayback machine )
- API: https://api.github.com/repos/cirosantilli/test-dangling/commits/53df36c09f092bbb59f2faa34eba15cd89ef8e83 ( Wayback machine )
Wygodnym sposobem na uzyskanie źródła w tym commicie jest użycie metody download zip, która może zaakceptować dowolne odniesienie, np.: https://github.com/cirosantilli/myrepo/archive/SHA.zip
-
Możliwe jest pobranie brakujących SHAs przez:
- wypisywanie zdarzeń API za pomocą
type": "PushEvent"
. Np. moje: https://api.github.com/users/cirosantilli/events/public ( Wayback machine ) - czasami wygodniej, patrząc na Sha żądań pull, które próbowały usunąć zawartość]}
- wypisywanie zdarzeń API za pomocą
-
Są takie scrapery jak http://ghtorrent.org / i https://www.githubarchive.org / które regularnie gromadzą dane z Githuba i przechowują je gdzie indziej.
Nie udało mi się znaleźć, czy zeskrobują rzeczywiste różnice w zatwierdzeniu, ale jest to technicznie możliwe.
Aby to przetestować, stworzyłem repo: https://github.com/cirosantilli/test-dangling i zrobione:
git init
git remote add origin [email protected]:cirosantilli/test-dangling.git
touch a
git add .
git commit -m 0
git push
touch b
git add .
git commit -m 1
git push
touch c
git rm b
git add .
git commit --amend --no-edit
git push -f
Jeśli usuniesz repozytorium , commity znikną nawet z API natychmiast i dadzą 404, np. https://api.github.com/repos/cirosantilli/test-dangling-delete/commits/8c08448b5fbf0f891696819f3b2b2d653f7a3824 to działa nawet jeśli odtworzysz inne repozytorium o tej samej nazwie.
Więc mój zalecany sposób działania to:
-
Zmień swoje referencje
-
Jeśli to za mało (np. nagie fotki):
- Usuń repozytorium
- skontaktuj się z obsługą
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-24 21:23:06
Dla jasności: przyjęta odpowiedź jest prawidłowa. Najpierw spróbuj. Jednak w niektórych przypadkach może to być niepotrzebnie skomplikowane, szczególnie jeśli napotkasz paskudne błędy, takie jak 'fatal: bad revision --prune-empty', lub naprawdę nie obchodzi cię historia repo.
Alternatywą byłoby:
- cd do podstawowej gałęzi projektu
- Usuń wrażliwy kod / plik
- rm-rf .git / # Usuń wszystkie informacje o git z Twój kod
- przejdź do github i usuń swoje repozytorium
- postępuj zgodnie z tym przewodnikiem, aby przenieść kod do nowego repozytorium, jak zwykle - https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
To oczywiście usunie wszystkie gałęzie historii zatwierdzeń i problemy zarówno z twojego repo github, jak i lokalnego repo git. Jeśli jest to niedopuszczalne, będziesz musiał użyć alternatywnego podejścia.
Nazwij to opcją nuklearną.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-25 23:38:51
Oto moje rozwiązanie w windows
Git filter-branch --tree-filter" RM-f 'filedir/filename' " HEAD
Git push --force
Upewnij się, że ścieżka jest poprawna w przeciwnym razie to nie zadziała
Mam nadzieję, że to pomoże
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-12-02 19:19:31
Użyj filter-branch :
git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch *file_path_relative_to_git_repo*' --prune-empty --tag-name-filter cat -- --all
git push origin *branch_name* -f
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-17 14:50:54
Możesz użyć git forget-blob
.
Użycie jest dość proste git forget-blob file-to-forget
. Więcej informacji znajdziesz tutaj
Zniknie ze wszystkich commitów w twojej historii, reflogu, tagach i tak dalej
Co jakiś czas napotykam ten sam problem i za każdym razem muszę wracać do tego posta i innych, dlatego zautomatyzowałem ten proces.
Napisy do współpracownicy z Stack Overflow, który pozwolił mi złożyć to razem
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-23 07:41:12
Musiałem to zrobić kilka razy do tej pory. Zauważ, że działa to tylko na jednym pliku na raz.
-
Pobiera listę wszystkich zmian, które zmodyfikowały plik. Ten na dole będzie pierwszym commitem:
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 w tym poleceniu:
git filter-branch --index-filter 'git rm --cached --ignore-unmatch <path-to-file>' -- <sha1-where-the-file-was-first-added>..
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-21 18:23:36
Więc wygląda to mniej więcej tak:
git rm --cached /config/deploy.rb
echo /config/deploy.rb >> .gitignore
Usuń pamięć podręczną śledzonego pliku z git i dodaj ten plik do listy
.gitignore
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-16 04:53:08