2014-10-10 16 views
11

Mam wiele podkatalogów, które chcę wyciągnąć na oddzielne repozytorium. Aby wyodrębnić je za pomocą pojedynczego polecenia, przenosimy je (zmieniając nazwę) do jednego podkatalogu wewnątrz katalogu głównego.Śledź nazwy podczas podziału podrzędnego git

Następnie uruchom: git subtree split -P my_new_subdir -b newbranch

Gdybym wtedy kasy to nowy oddział i uruchomić git log --follow someoldfile to tylko pokazuje mi wpisy dziennika związane z przeprowadzką do podkatalogu tymczasowego. Chcę przenieść pełną historię tych plików.

Czy istnieje sposób na zachowanie pełnej historii, łącznie z nazwami podczas dzielenia poddrzewa? Czy istnieją inne sposoby osiągnięcia pożądanego rezultatu?

Rozważałem użycie filtra-gałęzi na klonie repo, ale wiem, że będzie to bardzo powolne.

+0

Interesujące lektury: http://stackoverflow.com/q/5760331/6309, http://stackoverflow.com/a/16416818/6309. Nie jestem pewien, czy to możliwe. – VonC

+0

Sądzę, że ma to sens, ponieważ nie byłoby możliwości użycia starszych zmian, jeśli struktura katalogów jest zupełnie inna. –

Odpowiedz

8

W rzeczywistości jest to możliwe i kwestia ta została podniesiona tutaj kilka razy, chociaż nie ma uniwersalnego sposobu i wygląda na to, że trzeba skomponować własny przepis.

Jeśli chcesz tylko opuścić pliki z my_new_subdir, musisz usunąć wszystkie pozostałe pliki samodzielnie. Koncepcja jest użycie:

git filter-branch --tag-name-filter cat --index-filter \ 
    'git rm -r --cached --ignore-unmatch 
    unneeded-subdir-1 unneeded-pattern-* unneeded-etc' \ 
--prune-empty -f -- --all 

następnie do pomocy w znalezieniu co jeszcze muszą być usunięte można użyć sth jak:

git log --name-status --all | grep -P '^\w\s+[\S]+$' 

lub nawet np

git log --name-status --all | grep -P '^\w\s+[\S]+$' | \ 
    sed s/^.// | cut -f 1-2 -d '/' | sort -u 

ten sposób może znaleźć wszystkie pliki/katalogi (lub tylko pierwsze dwa segmenty ścieżki w drugim przypadku), które były obecne w repozytorium w dowolnym czasie. Po tym można użyć następującego polecenia, aby wyczyścić repo:

git gc --aggressive 

Więc po przeniesieniu plików do lewo w my_new_subdir Użyłem kombinacji powyższych poleceń, aby oczyścić niepotrzebne pliki z historii. Jednak wciąż znajdowałem niezwiązane z sobą połączenia w historii, ale ostatecznie byłem zadowolony z wyniku. Zauważ, że powyżej jest wiele parametrów poleceń git, które są niezbędne do przejścia przez całą historię, gałęzie i znaczniki.

Aby przyspieszyć operacje, możesz zidentyfikować największe części repozytorium do usunięcia w pierwszej iteracji, a następnie wykonaj git gc --aggressive. Posiadanie procesora i dysku SSD i5 zajęło mi około minuty, aby wykonać jedną iterację git filter-branch i przetworzono około 1000 wpisów historii.

+0

To było rozwiązanie, na które się zdecydowałem, ale nigdy nie byłem w stanie go wypróbować. Dziękuję za poświęcenie czasu na odpowiedź. –