Usunięcie pliku z repozytorium git (historia)

(rozwiązane, patrz spód ciała pytania)
Szukam tego od dawna, to co mam do tej pory to:

Prawie ta sama metoda, ale obie pozostawiają obiekty w plikach pack... Utknąłem.
Czego próbowałem:

git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_name'
rm -Rf .git/refs/original
rm -Rf .git/logs/
git gc

Nadal mam pliki w paczce, i stąd To wiem:

git verify-pack -v .git/objects/pack/pack-3f8c0...bb.idx | sort -k 3 -n | tail -3

I to:

git filter-branch --index-filter "git rm -rf --cached --ignore-unmatch file_name" HEAD
rm -rf .git/refs/original/ && git reflog expire --all &&  git gc --aggressive --prune
To samo...

Próbował git clone trick, usunął niektóre pliki (~3000 z nich), ale największe pliki nadal tam są...

Mam kilka dużych plików w repozytorium, ~200m, i naprawdę nie chcę ich tam... A ja nie chcę resetować repozytorium na 0: (

Rozwiązanie: Jest to najkrótszy sposób na pozbycie się Plików:

    Szach .git / packed-refs-moim problemem było to, że miałem tam refs/remotes/origin/master w przeciwnym razie git nie usunie tych plików]}
  1. (opcjonalnie) git verify-pack -v .git/objects/pack/#{pack-name}.idx | sort -k 3 -n | tail -5 - aby sprawdzić największe pliki
  2. (opcjonalnie) git rev-list --objects --all | grep a0d770a97ff0fac0be1d777b32cc67fe69eb9a98 - aby sprawdzić, czym są te pliki
  3. git filter-branch --index-filter 'git rm --cached --ignore-unmatch file_names' - aby usunąć plik ze wszystkich wersji
  4. rm -rf .git/refs/original/ - aby usunąć kopię zapasową Gita
  5. git reflog expire --all --expire='0 days' - aby wygasnąć wszystkie luźne obiekty
  6. git fsck --full --unreachable - aby sprawdzić, czy są jakieś luźne przedmioty
  7. git repack -A -d - przepakowywanie
  8. git prune - aby ostatecznie usunąć te obiekty
Author: Boris Churzin, 2010-01-29

8 answers

Nie mogę powiedzieć na pewno bez dostępu do danych repozytorium, ale wierzę, że prawdopodobnie jest jeden lub więcej spakowanych refów, które nadal odwołują się do starych commitów sprzed uruchomienia git filter-branch. To by wyjaśniało, dlaczego git fsck --full --unreachable nie nazywa dużego obiektu blob nieosiągalnym obiektem, mimo że wygasł Twój reflog i usunięto oryginalne (rozpakowane) refy.

Oto co bym zrobił (po git filter-branch i git gc zostały zrobione):

1) Upewnij się, że oryginalne refy są gone:

rm -rf .git/refs/original

2) Expire all reflog entries:

git reflog expire --all --expire='0 days'

3) Sprawdź stare spakowane refy

To może być trudne, w zależności od tego, ile masz zapakowanych refów. Nie znam żadnych komend Git, które automatyzują to, więc myślę, że będziesz musiał to zrobić ręcznie. Wykonaj kopię zapasową .git/packed-refs. Teraz edytuj .git/packed-refs. Sprawdź, czy nie ma starych refów (w szczególności sprawdź, czy spakował któryś z refów z .git/refs/original). Jeśli znajdziesz jakieś stare, które nie musisz tam być, usuń je (usuń linię dla tego ref).

Po zakończeniu czyszczenia pliku packed-refs sprawdź, czy git fsck zauważy nieosiągalne obiekty:

git fsck --full --unreachable

Jeśli to zadziałało i git fsck Teraz zgłosi twój duży blob jako nieosiągalny, możesz przejść do następnego kroku.

4) przepakuj spakowane archiwum

git repack -A -d

Zapewni to, że nieosiągalne obiekty zostaną rozpakowane i pozostaną rozpakowany.

5) ścinanie luźnych (nieosiągalnych) przedmiotów

git prune

I to powinno wystarczyć. Git naprawdę powinien mieć lepszy sposób na zarządzanie spakowanymi refami. Może jest lepszy sposób, o którym Nie wiem. W przypadku braku lepszego sposobu, ręczna edycja pliku packed-refs może być jedynym sposobem.
 61
Author: Dan Moulding,
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
2010-02-01 21:39:55

Zalecałbym użycie BFG Repo-Cleaner, prostszej i szybszej alternatywy dla git-filter-branch specjalnie zaprojektowanej do przepisywania plików z historii Gita. Jednym ze sposobów, w jaki ułatwia Ci to życie, jest to, że domyślnie obsługuje Wszystkie odniesienia (wszystkie tagi, gałęzie, rzeczy takie jak refs/remotes/origin/master, itp.), ale jest również 10-50x szybciej.

Należy dokładnie wykonać te kroki tutaj: http://rtyley.github.com/bfg-repo-cleaner/#usage - ale bit rdzenia jest taki: Pobierz jar BFG (wymaga Javy 6 lub nowszej) i uruchom następujące polecenie:

$ java -jar bfg.jar  --delete-files file_name  my-repo.git

Każdy plik o nazwie file_name (który nie znajduje się w twoim najnowszym commicie) zostanie całkowicie usunięty z historii Twojego repozytorium. Następnie możesz użyć git gc, Aby wyczyścić martwe dane:

$ git gc --prune=now --aggressive

BFG jest na ogół znacznie prostszy w użyciu niż git-filter-branch - opcje są dopasowane do tych dwóch powszechnych przypadków użycia:

  • usuwanie Crazy Big Files
  • usuwanie haseł, poświadczeń i innych prywatnych danych

pełne ujawnienie: jestem autorem BFG Repo-Cleaner.

 9
Author: Roberto Tyley,
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
2013-04-16 20:06:49

Uznałem to za bardzo pomocne w usuwaniu całego folderu, ponieważ powyższe nie pomogło mi: https://help.github.com/articles/remove-sensitive-data .

Użyłem:

git filter-branch -f --force \
--index-filter 'git rm -rf --cached --ignore-unmatch folder/sub-folder' \
--prune-empty --tag-name-filter cat -- --all

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
git gc --aggressive --prune=now
 6
Author: Mike Averto,
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-04-04 00:06:34

Próbowałem pozbyć się dużego pliku w historii, i powyższe odpowiedzi zadziałały, do pewnego stopnia. Chodzi o to, że nie działają, jeśli masz tagi. Jeśli commit zawierający duży plik jest osiągalny ze znacznika, wtedy będziesz musiał dostosować polecenie filter-branches w ten sposób:

git filter-branch --tag-name-filter cat \
--index-filter 'git rm --cached --ignore-unmatch huge_file_name' -- \
--all --tags
 4
Author: BHMulder,
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-04-04 00:08:52

Zobacz: Jak usunąć poufne pliki z historii Gita

Powyższe nie powiedzie się, jeśli plik nie istnieje w Rev. w takim przypadku przełącznik '--ignore-unmatch'to naprawi:

git filter-branch -f --index-filter 'git rm --cached --ignore-unmatch <filename>' HEAD

Następnie, aby usunąć wszystkie luźne przedmioty z repostiry:

git gc --prune='0 days ago'
 2
Author: Wayne Conrad,
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-05-23 12:10:50

Masz różne powody dla wciąż dużego rozmiaru repo git po git gc, ponieważ nie usuwa wszystkich luźnych obiektów.

Opisuję te powody w "reduce the Git repozytorium size "

Ale jedną sztuczką do przetestowania w Twoim przypadku byłoby klon Twój "oczyszczony" Git repo i sprawdź, czy klon ma odpowiedni rozmiar.

('oczyszczony' repo ' jest tym, w którym zastosowałeś filter-branch, a następnie gc i prune)

 1
Author: VonC,
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-05-23 12:26:29

Powinno to być objęte poleceniem git obliterate w Git Extras ( https://github.com/visionmedia/git-extras).

git obliterate <filename>
 0
Author: Spain Train,
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
2013-03-25 20:25:49

Miałem ten sam problem i znalazłem świetny tutorial na GitHubie, który wyjaśnia krok po kroku, jak pozbyć się Plików, które przypadkowo popełniłeś.

Oto małe podsumowanie procedury zgodnie z sugestią Cupcake.

Jeśli Masz plik o nazwie file_to_remove do usunięcia z historii:

cd path_to_parent_dir

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch file_to_remove' \
  --prune-empty --tag-name-filter cat -- --all
 0
Author: Cyril Leroux,
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-04-04 09:57:07