Eksperymentowałem z użyciem poddrzewa git i napotkałem następującą sytuację.
Użyłem poddrzewa git, aby dodać zewnętrzny projekt do mojego repozytorium, celowo zachowałem całą historię dla projektu wyższego szczebla, ponieważ chcę móc odwoływać się do historii projektu, a także później wnieść swój wkład do projektu wyższego szczebla.
Jak się okazuje, inny współpracownik projektu upstream przypadkowo wypchnął duży plik do gałęzi master. Aby to naprawić, poprzedni projekt przepisał historię i wymusił przekazanie jej na master. Tworząc moje „monorepo”, załączyłem ten zatwierdzenie i chciałbym go również usunąć.
Jak mogę zaktualizować moje repozytorium, aby odzwierciedlić nową historię poddrzewa?
Moja pierwsza próba polegała na użyciu gałęzi filter do całkowitego usunięcia poddrzewa i całej historii.
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch upstream-project-dir' --prune-empty HEAD
Po usunięciu starej wersji poddrzewa mogłem ponownie dodać poddrzewo, korzystając z nowego wzorca głównego. Jednak to nie zadziałało, ponieważ z jakiegoś powodu historia zatwierdzeń nadal pojawia się w danych wyjściowych dziennika git.
Aktualizacja
Napisałem kroki, aby stworzyć przykład w minimalnym stopniu powtarzalny.
Najpierw utwórz puste repozytorium git.
git init test-monorepo cd ./test-monorepo
Utwórz początkowe zatwierdzenie.
echo hello world > README git add README git commit -m 'initial commit'
Teraz dodaj poddrzewo dla projektu zewnętrznego.
git remote add thirdparty [email protected]:teivah/algodeck.git git fetch thirdparty git subtree add --prefix algodeck thirdparty master
Dokonaj kilku zmian na monorepo
echo dont panic >> algodeck/README.md git commit -a -m 'test commit'
Teraz spróbuj użyć git filter-branch, aby usunąć poddrzewo.
git filter-branch --index-filter 'git rm -rf --cached --ignore-unmatch algodeck' --prune-empty HEAD
Sprawdź dane wyjściowe dziennika git, oczekuję, że zobaczę tylko moje początkowe zatwierdzenie.
git log
git gc --prune=now
usunę tylko zatwierdzeń, które się nie pojawiajągit log
?git log
, bez argumentów i wciąż widzę stare zobowiązania.Odpowiedzi:
masz już złe zatwierdzenie w swojej historii i musisz się go pozbyć, zanim przejdziesz dalej
załóżmy, że zostałeś
master
ostatnio przekierowany i nie mogłeś nic zrobić (tak naprawdę nie mam twoich gałęzi w zasięgu wzroku, więc muszę założyć coś na początek)możesz przejść do poprzedniego zatwierdzenia i przesunąć znacznik gałęzi o 1 krok do tyłu (lub X kroków do tyłu), co w każdym razie byłoby nieszkodliwe, a następnie pociągnąć ponownie
na przykład
git checkout master~1
aby sprawdzić, czy rodzic zatwierdził, git ostrzega, że nie mamy oddziałówgit branch master -f
aby zmusić bieżącą kasę, aby ponownie stała się master, tj. faktycznie przewija gałąź master do poprzedniego zatwierdzenia (lub X poprzedniego zatwierdzenia), i stąd nie ma znaczenia, czy poprzednio wykonał siłę, czy nie, możemy wznowić normalnie, a nawet w razie potrzeby wróć do powyższego kroku, możemy tylko ponownie przyciągnąć mistrza, nie tracąc niczego z góry (co dla nas może być również tylko do odczytu, nie będziemy naciskać na to)git checkout master
aby znaleźć się w naszej „przewiniętej” gałęzi master, to samo zatwierdzenie, do którego wkraczamy, ale teraz będąc w gałęzigit pull
aby ponownie przyciągnąć mistrza (może być z lub bez--prune
), jeśli zostanie skierowane w górę rzeki, wrócimy stąd na ścieżkę, jeśli nie, otrzymamy to samo, co mieliśmy, jeśli otrzymamy to samo i nie przypuszczaliśmy, być może muszę wrócić do pierwszego kroku powyżej i przewinąć więcej zatwierdzeń, np.git checkout master~5
lub cokolwiek (w razie potrzeby)źródło
git subtree
w repozytorium oczyść historię zatwierdzeń dla tego pilota:
jeśli jeden z twoich zatwierdzeń ma zatwierdzenie, które zawiera duży plik, przepisz swoją historię, aby ten duży plik nie był już przywoływany
W tych dwóch krokach do dużego pliku nie będzie już odwoływać się żadne zatwierdzenie w repozytorium.
Zostanie on dodatkowo usunięty z twojego dysku twardego w pewnym momencie, kiedy git uruchomi swój moduł wyrzucania elementów bezużytecznych i osiągnięte zostaną opóźnienia wygasania dla wiszących obiektów blob.
Jeśli masz pilną potrzebę jak najszybszego usunięcia tego dużego pliku z dysku twardego:
Uruchom ręcznie
źródło