2014-09-29 16 views
11

Wiele księżyców temu dodałem poddrzewo do mojego repozytorium git. To poddrzewo zawierało kilka folderów i plików. Dodałem poddrzewo zamiast tworzyć submoduł (zgodnie z zaleceniami). Teraz zdaję sobie sprawę, że chcę tylko jednego z plików w poddrzewie i żadnej z pozostałych. Co gorsza, kiedy moje repozytorium jest inne, to, co dostają, nie jest tym, czego się spodziewam - jest jakiś konflikt z poddrzewem i innym kodem, który stworzyłem.Jak usunąć wcześniej dodane poddrzewo git i jego historię

mogę jeździć z plików/folderów z

git rm subtree–folder1 subtree_folder2 subtree_files.* 

Jednak jestem nadal pozostaje dłuższy popełnienia historii z poddrzewa.

Zrobiłem sporo rozwoju, ponieważ początkowo dodałem poddrzewo i nie mogę stracić historii zatwierdzenia, którą wygenerowałem.

W skrócie jest to, co chciałbym:

  1. Usuń wszystkie pliki poddrzewie/foldery.
  2. Zapomnij historię wszystkich zgłoszeń poddrzewa.
  3. Zostawiłem tylko z moim kodem i moją historią.

Czy to możliwe?

PS. Jedną z możliwych komplikacji jest to, że przeniosłem pojedynczy plik nagłówkowy, który chciałem zatrzymać z poddrzewa do jakiegoś folderu w moim kodzie. Mam nadzieję, że to nie jest to, co powstrzymuje mnie przed zapomnieniem historii podtekstów.

Próba

Po świeżej kasie ze zdalnego serwera mam następujące:

$ ls 
.git    CMakeLists.txt Read.cpp   logging.conf 
.gitignore  ENDF6   TestData   src 
.sparse-checkout LICENCE   doc    test 
.travis.yml  README.md  include   tools 

Gdzie .gitignore ma tylko: build/ debug/

Kiedy próbuję polecenie zgodnie z sugestią nie otrzymuję bardzo szczęśliwej odpowiedzi:

$ git filter-branch --index-filter 'git rm --cached -rf test tools src doc LICENCE README.md .travis.yml' HEAD 
Rewrite 2fec85e41e40ae18efd1b130f55b14166a422c7f (1/1701)fatal: pathspec 'test' did not match any files 
index filter failed: git rm --cached -rf test tools src doc LICENCE README.md .travis.yml 

Nie jestem pewien, dlaczego mówi, że ma problem z test, kiedy wyraźnie tam jest. Jestem zdziwiony.

+0

Czy próbowałeś po prostu użyć 'git rm ', aby usunąć poddrzewo? –

+0

@hunch_hunch Zrobiłem to tak samo jak polecenia tutaj: http://stackoverflow.com/questions/15890047/how-to-remove-history-of-deleted-git-subtree-folder, ale wciąż mam całą historię poddrzewo. Wsparcie! – jlconlin

+0

Masz problem z ponownym zapisywaniem historii repozytorium za pomocą rebase lub gałęzi filtru? –

Odpowiedz

15

Musisz użyj gałęzi filtru wraz z opcją --prune-empty, aby usunąć wszystkie zatwierdzenia, które nie wprowadzają już nowych zmian.

git filter-branch --index-filter 'git rm --cached --ignore-unmatch -rf dir1 dir2 dirN file1 file2 fileN' --prune-empty -f HEAD 

Po tym, jeśli chcesz, aby odzyskać miejsce na dysku trzeba będzie usunąć wszystkie oryginalne bibl że oddział filtr zapisane, wygasają z reflog i zbierać śmieci.

+0

Dzięki za pomoc! Nie jest to tutaj pokazane, ale w naszym czacie @AndrewC pod warunkiem, że odpowiedź jest potrzebna. – jlconlin

+0

Dziennik git wciąż pokazuje historię. Może brakuje mi czegoś ... –

+0

@ SylylarSaveland Zobacz [czat] (http://chat.stackoverflow.com/rooms/62556/discussion-between-jeremy-and-andrew-c) jlconlin odnosi się, chociaż powinno być tutaj rozwiązaniem. Mm – Llopis

2

Możesz użyć git filter-branch, aby zastosować operację do wszystkich zatwierdzeń wykonanych w oddziale. Obejmuje to usuwanie plików z każdego zatwierdzenia podczas przepisywania całej historii. Dobry opis i instrukcje są dostępne tutaj: http://gitready.com/beginner/2009/03/06/ignoring-doesnt-remove-a-file.html. Możesz również znaleźć następujące pytanie: Completely remove files from Git repo and remote on GitHub (tam znalazłem link). Rzeczywiste polecenie, które uruchomisz przy użyciu tego rozwiązania, będzie wyglądało jak git filter-branch --index-filter 'git rm --cached -rf subtree–folder1 subtree_folder2' HEAD.

Innym sposobem, który jest prawdopodobnie przesadą dla tego, co robisz, jest wybieranie wiśni. Wybór wiśni pozwala przepisać dowolną część historii, którą lubisz, na dowolnym poziomie szczegółowości: http://git-scm.com/docs/git-cherry-pick. Będziemy chcieli, aby zrobić coś podobnego git reset --hard <HASH of commit that introduced the subtree>, a następnie przez szereg

git cherry-pick -n <following commit hashes> 
git reset 
git add -p 
git commit 

za każdy kolejny popełnić ty uczynił.Umożliwi to usunięcie poddrzewa z każdego zatwierdzenia dokonanego w przeszłości. Więcej informacji na temat skutecznego zbierania wiśni można uzyskać pod numerem telefonu partly cherry-picking a commit with git. Gdy skończysz z tą wersją skreślenia, będziemy chcieli, aby usunąć stare zobowiązuje które nie są już częścią twojego oddziału:

git reflog expire --expire-unreachable=now --all 
git gc --prune=now 

Inne odwołuje pytania: How to move a branch backwards in git? Listing and deleting Git commits that are under no branch (dangling?)