Kiedy używasz
git rm --cached myfile
nie usuwa się z lokalnego systemu plików, co jest celem. Ale jeśli już utworzyłeś wersję i zatwierdziłeś plik, umieściłeś go w centralnym repozytorium i przeciągnąłeś do innego repozytorium przed użyciem polecenia, usunie plik z tego systemu.
Czy istnieje sposób, aby po prostu usunąć plik z wersjonowania bez usuwania go z dowolnego systemu plików?
Edycja: wyjaśnione, mam nadzieję.
git
version-control
gitignore
git-rm
Fletcher Moore
źródło
źródło
Odpowiedzi:
Nie sądzę, aby zatwierdzenie Git mogło zarejestrować intencję typu „przestań śledzić ten plik, ale nie usuwaj go”.
Realizacja takiego zamiaru będzie wymagała interwencji poza Git we wszystkich repozytoriach, które łączą się (lub ponownie bazują na) zatwierdzeniu, które usuwa plik.
Zapisz kopię, zastosuj usunięcie, przywróć
Prawdopodobnie najłatwiejszą rzeczą do zrobienia jest poinformowanie dalszych użytkowników, aby zapisali kopię pliku, wycofali usunięcie, a następnie przywrócili plik. Jeśli ściągają przez rebase i „przenoszą” modyfikacje do pliku, będą miały konflikty. Aby rozwiązać takie konflikty, użyj
git rm foo.conf && git rebase --continue
(jeśli konfliktowe zatwierdzenie zawiera zmiany inne niż te w usuniętym pliku) lubgit rebase --skip
(jeśli konfliktujące zatwierdzenie zmieniło się tylko na usunięty plik).Przywróć plik jako nieśledzony po wyciągnięciu zatwierdzenia, które go usuwa
Jeśli już wyciągnęli zatwierdzenie usunięcia, nadal mogą odzyskać poprzednią wersję pliku za pomocą git show :
Lub z git checkout (za komentarzem Williama Pursella; ale pamiętaj, aby ponownie usunąć go z indeksu!):
Jeśli podjęli inne działania od czasu usunięcia twojego usunięcia (lub ciągną z rebase do odłączonego HEAD), mogą potrzebować czegoś innego niż
@{1}
. Mogliby użyćgit log -g
do znalezienia zatwierdzenia tuż przed usunięciem.W komentarzu wspominasz, że plik, który chcesz „odśledzić, ale zachować” to jakiś rodzaj pliku konfiguracyjnego, który jest wymagany do uruchomienia oprogramowania (bezpośrednio z repozytorium).
Zachowaj plik jako „domyślny” i aktywuj go ręcznie / automatycznie
Jeśli dalsze utrzymywanie zawartości pliku konfiguracyjnego w repozytorium nie jest całkowicie niedopuszczalne, możesz zmienić nazwę śledzonego pliku z (np.)
foo.conf
Na,foo.conf.default
a następnie poinstruować użytkowników, abycp foo.conf.default foo.conf
po zastosowaniu zmiany nazwy. Lub, jeśli użytkownicy już używają jakiejś istniejącej części repozytorium (np. Skryptu lub innego programu skonfigurowanego przez zawartość repozytorium (np.Makefile
Lub podobnego)) do uruchamiania / wdrażania oprogramowania, możesz włączyć mechanizm domyślny do uruchomienia / proces wdrażania:Mając taki mechanizm domyślny, użytkownicy powinni być w stanie pobrać zatwierdzenie, które zmienia nazwę
foo.conf
nafoo.conf.default
bez konieczności wykonywania dodatkowej pracy. Ponadto unikniesz konieczności ręcznego kopiowania pliku konfiguracyjnego, jeśli w przyszłości wykonasz dodatkowe instalacje / repozytoria.Przepisanie historii i tak wymaga ręcznej interwencji…
Jeśli utrzymywanie treści w repozytorium jest niedopuszczalne, prawdopodobnie będziesz chciał całkowicie usunąć ją z historii za pomocą czegoś podobnego
git filter-branch --index-filter …
. Sprowadza się to do przepisywania historii, co będzie wymagało ręcznej interwencji dla każdej gałęzi / repozytorium (zobacz sekcję „Recovering From Upstream Rebase” na stronie podręcznika git rebase ). Specjalne traktowanie wymagane dla twojego pliku konfiguracyjnego byłoby tylko kolejnym krokiem, który należy wykonać podczas odzyskiwania po przepisaniu:Zignoruj to, aby zapobiec nawrotom
Bez względu na to, jakiej metody użyjesz, prawdopodobnie będziesz chciał dołączyć nazwę pliku konfiguracyjnego do
.gitignore
pliku w repozytorium, aby nikt nie mógł niechcącygit add foo.conf
ponownie (jest to możliwe, ale wymaga-f
/--force
). Jeśli masz więcej niż jeden plik konfiguracyjny, możesz rozważyć `` przeniesienie '' ich wszystkich do jednego katalogu i zignorowanie całej rzeczy (przez `` przeniesienie '' mam na myśli zmianę miejsca, w którym program spodziewa się znaleźć swoje pliki konfiguracyjne i pobranie użytkowników (lub mechanizm uruchamiania / wdrażania), aby skopiować / przenieść pliki do ich nowej lokalizacji; oczywiście nie chcesz umieszczać pliku mv w katalogu, który będziesz ignorować).źródło
--{,no-}assume-unchanged
jest czysto lokalny: jego stan nie jest bezpośrednio zapisywany w zatwierdzeniach. Może pomóc zapobiec zatwierdzaniu przez repozytorium nowych zmian w pliku, ale nie usuwa go z kontroli wersji. Jeśli możesz ustawić to dla wszystkich odpowiednich, powiązanych, nie-gołych repozytoriów, może to pomóc w twojej sytuacji, ale nie jest to coś, co możesz bezpośrednio wypchnąć + pull / rebase do innych powiązanych, nie-gołych repozytoriów (szczególnie tych, które nie kontrolujesz, zgodnie z wyjaśniającymi komentarzami pierwotnego pytającego do pytania: patrz „systemy ludzi” / „systemy obce”).I do not think a Git commit can record an intention like “stop tracking this file, but do not delete it”.
- teraz może, zgit rm --cached foo.conf
Miałem ten sam problem w tym tygodniu, kiedy przypadkowo popełniłem, a następnie próbowałem usunąć plik kompilacji ze współdzielonego repozytorium, a to:
http://gitready.com/intermediate/2009/02/18/temporary-ignoring-files.html
działa dobrze dla mnie i do tej pory nie wspomniano.
Aby usunąć plik, który Cię interesuje, z kontroli wersji, użyj wszystkich innych poleceń w normalny sposób.
Jeśli kiedykolwiek chciałeś go włożyć z powrotem.
Edycja: proszę zapoznać się z komentarzami Chrisa Johnsena i KPM, działa to tylko lokalnie, a plik pozostaje pod kontrolą wersji dla innych użytkowników, jeśli oni również tego nie robią. Zaakceptowana odpowiedź podaje pełniejsze / poprawne metody radzenia sobie z tym problemem. Również kilka uwag z linku, jeśli używasz tej metody:
źródło
Aby usunąć plik z indeksu, użyj:
Nie powinno to mieć wpływu na twoją lokalną kopię ani nikogo innego.
źródło
reset
usuwa plik z indeksu tylko wtedy, gdy plik nie jest w bieżącym zatwierdzeniu HEAD, w przeciwnym razie po prostu przywraca wersję indeksu do bieżącej wersji HEAD.git rm --cached remove_file
git add .gitignore
git commit -m "Excluding"
źródło
Po wykonaniu
git rm --cached
polecenia spróbuj dodać plikmyfile
do.gitignore
pliku (utwórz go, jeśli nie istnieje). Powinno to nakazać gitowi ignorowaniemyfile
..gitignore
Plik oznaczenia wersji, więc musisz zobowiązać go i przesunąć go do zdalnego repozytorium.źródło
Moim rozwiązaniem jest pobranie drugiej kopii roboczej, a następnie:
który mówi, że pobierz wszystkie ścieżki plików w najnowszym komentarzu i sprawdź je od rodzica HEAD. Zadanie wykonane.
źródło
Powyższe rozwiązania działają dobrze w większości przypadków. Jeśli jednak chcesz również usunąć wszystkie ślady tego pliku (tj. Poufne dane, takie jak hasła), będziesz również chciał usunąć go z całej historii zatwierdzeń, ponieważ plik nadal może zostać pobrany z tego pliku.
Oto rozwiązanie, które usuwa wszystkie ślady pliku z całej historii zmian, tak jakby nigdy nie istniał, ale utrzymuje plik na miejscu w systemie.
https://help.github.com/articles/remove-sensitive-data/
W rzeczywistości możesz przejść do kroku 3, jeśli jesteś w lokalnym repozytorium git i nie musisz wykonywać testu na sucho. W moim przypadku potrzebowałem tylko kroków 3 i 6, ponieważ utworzyłem już plik .gitignore i byłem w repozytorium, nad którym chciałem pracować.
Aby zobaczyć zmiany, może być konieczne przejście do katalogu głównego GitHub repozytorium i odświeżenie strony. Następnie przejdź przez linki, aby dostać się do starego zatwierdzenia, które kiedyś miało plik, i zobacz, że został on usunięty. Dla mnie zwykłe odświeżenie starej strony zmian nie pokazało zmiany.
Z początku wyglądało to onieśmielająco, ale naprawdę było łatwe i działało jak urok! :-)
źródło