Easy Way ™
Okazuje się, że jest to tak powszechna i przydatna praktyka, że zwierzchnicy Gita sprawili, że było to naprawdę łatwe, ale musisz mieć nowszą wersję Git (> = 1.7.11 maja 2012 r.). Zobacz dodatek, aby dowiedzieć się, jak zainstalować najnowszą wersję Git. Ponadto, nie jest przykładem w świecie rzeczywistym w poradniku poniżej.
Przygotuj stare repozytorium
cd <big-repo>
git subtree split -P <name-of-folder> -b <name-of-new-branch>
Uwaga: <name-of-folder>
NIE może zawierać wiodących ani końcowych znaków. Na przykład folder o nazwie subproject
MUSI zostać przekazany jako subproject
NIE./subproject/
Uwaga dla użytkowników systemu Windows: gdy głębokość folderu wynosi> 1, <name-of-folder>
musi mieć separator folderów w stylu * nix (/). Na przykład folder o nazwie path1\path2\subproject
MUSI zostać przekazany jakopath1/path2/subproject
Utwórz nowe repozytorium
mkdir ~/<new-repo> && cd ~/<new-repo>
git init
git pull </path/to/big-repo> <name-of-new-branch>
Połącz nowe repozytorium z GitHub lub gdziekolwiek
git remote add origin <git@github.com:user/new-repo.git>
git push -u origin master
Oczyszczanie w środku <big-repo>
, jeśli jest to pożądane
git rm -rf <name-of-folder>
Uwaga : pozostawia to wszystkie historyczne odniesienia w repozytorium.Zobacz dodatek poniżej, jeśli naprawdę obawiasz się, że podałeś hasło lub chcesz zmniejszyć rozmiar pliku w .git
folderze.
...
Przewodnik
Są to te same kroki, co powyżej , ale wykonuję moje dokładne kroki dla mojego repozytorium zamiast używać <meta-named-things>
.
Oto projekt, który mam zaimplementować moduły przeglądarki JavaScript w węźle:
tree ~/node-browser-compat
node-browser-compat
├── ArrayBuffer
├── Audio
├── Blob
├── FormData
├── atob
├── btoa
├── location
└── navigator
Chcę podzielić pojedynczy folder btoa
na osobne repozytorium Git
cd ~/node-browser-compat/
git subtree split -P btoa -b btoa-only
Mam teraz nowy oddział, btoa-only
który tylko zatwierdza btoa
i chcę utworzyć nowe repozytorium.
mkdir ~/btoa/ && cd ~/btoa/
git init
git pull ~/node-browser-compat btoa-only
Następnie tworzę nowe repozytorium na GitHub lub Bitbucket lub cokolwiek innego i dodam jako origin
git remote add origin git@github.com:node-browser-compat/btoa.git
git push -u origin master
Szczęśliwy dzień!
Uwaga: jeśli utworzyłeś repozytorium za pomocą README.md
, .gitignore
i LICENSE
, musisz najpierw pobrać:
git pull origin master
git push origin master
Na koniec chcę usunąć folder z większego repozytorium
git rm -rf btoa
...
dodatek
Najnowsza wersja Git na macOS
Aby uzyskać najnowszą wersję Git za pomocą Homebrew :
brew install git
Najnowsza wersja Git na Ubuntu
sudo apt-get update
sudo apt-get install git
git --version
Jeśli to nie zadziała (masz bardzo starą wersję Ubuntu), spróbuj
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
Jeśli to nadal nie działa, spróbuj
sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s \
/usr/share/doc/git/contrib/subtree/git-subtree.sh \
/usr/lib/git-core/git-subtree
Dzięki rui.araujo z komentarzy.
Wyczyść swoją historię
Domyślnie usuwanie plików z Gita tak naprawdę ich nie usuwa, po prostu potwierdza, że już ich tam nie ma. Jeśli chcesz faktycznie usunąć odniesienia historyczne (tj. Masz zatwierdzone hasło), musisz to zrobić:
git filter-branch --prune-empty --tree-filter 'rm -rf <name-of-folder>' HEAD
Następnie możesz sprawdzić, czy Twój plik lub folder w ogóle nie pojawia się w historii Git
git log -- <name-of-folder> # should show nothing
Nie można jednak „usunąć” operacji usuwania do GitHub i tym podobnych. Jeśli spróbujesz, pojawi się błąd i będziesz musiał to zrobić, git pull
zanim będziesz mógł git push
- a następnie wrócisz do posiadania wszystkiego w swojej historii.
Więc jeśli chcesz usunąć historię z „pochodzenia” - co oznacza, że chcesz usunąć ją z GitHub, Bitbucket itp. - musisz usunąć repozytorium i ponownie wcisnąć przyciętą kopię repozytorium. Ale czekaj - jest więcej ! - Jeśli naprawdę martwisz się usunięciem hasła lub czegoś takiego, musisz przyciąć kopię zapasową (patrz poniżej).
Dokonywanie .git
mniejszy
Wyżej wspomniane polecenie usuwania historii wciąż pozostawia kilka plików kopii zapasowych - ponieważ Git jest zbyt uprzejmy, pomagając ci nie zepsuć repozytorium przez przypadek. W końcu usunie osierocone pliki w ciągu dni i miesięcy, ale pozostawia je tam na chwilę, na wypadek, gdybyś zdał sobie sprawę, że przypadkowo usunąłeś coś, czego nie chciałeś.
Jeśli więc naprawdę chcesz opróżnić kosz, aby natychmiast zmniejszyć rozmiar klonu repozytorium, musisz wykonać wszystkie te naprawdę dziwne rzeczy:
rm -rf .git/refs/original/ && \
git reflog expire --all && \
git gc --aggressive --prune=now
git reflog expire --all --expire-unreachable=0
git repack -A -d
git prune
To powiedziawszy, nie zalecałbym wykonywania tych kroków, chyba że wiesz, że musisz - na wypadek, gdybyś wyciął niewłaściwy podkatalog, wiesz? Pliki kopii zapasowej nie powinny zostać sklonowane po naciśnięciu repozytorium, będą one tylko w lokalnej kopii.
Kredyt
git filter-branch
patrz moja odpowiedź poniżej.