Git checkout / pull nie usuwa katalogów?

83

Mam repozytorium @ github. Zrobiłem trochę pracy w domu i wrzuciłem to na github. Wymagało to pewnego usunięcia plików i katalogów. Teraz jestem na moim polu roboczym, które miało kopię kodu przed usunięciem plików i katalogów.

Wydałem:

git remote update
git checkout HEAD
git pull origin HEAD

Usunął wszystkie pliki, które powinien mieć, ale nie katalogi, w których się znajdowały.

Dwa pytania:

  1. Dlaczego nie usunął katalogów?
  2. Czy istnieje polecenie git, które mogę wydać w obecnym stanie, aby je usunąć?
mculp
źródło
Zgoda, git checkout HEAD nic nie robi, ponieważ HEAD jest odniesieniem wskazującym na aktualnie wyewidencjonowane zatwierdzenie. Prawdopodobnie w obu przypadkach szedłeś na mistrza.
Cascabel
Cóż, HEAD faktycznie zaktualizował wszystko z wyjątkiem usunięcia pustych katalogów. Jak powiedziałem, jestem nowy w git.
mculp
Możliwy duplikat Jak wymusić „git pull” nadpisanie plików lokalnych? Sprawdź tam odpowiedzi, jeśli nadal potrzebujesz innych rozwiązań.
DrBeco

Odpowiedzi:

152

Git nie śledzi katalogów, więc nie usunie tych, które staną się puste w wyniku scalenia lub innej zmiany. Jednakże, można użyć git clean -fddo usunięcia nieśledzone katalogów ( -fdśrodki flag f usuwania Orce z nieśledzonej plików i d irectories).

mipadi
źródło
4
Jestem zmieszany. Dlaczego więc katalogi zostały usunięte z mojego repozytorium GitHub po zatwierdzeniu / wypchnięciu zmian?
mculp
1
Katalogi w twojej kopii roboczej mogły zawierać nieśledzone pliki (w tym ukryte nieśledzone pliki), dlatego mogą wydawać się puste, ale tak naprawdę nie są, więc Git ich nie usunął. git cleanbędzie oczywiście.
mipadi
4
Może to mieć coś wspólnego z faktem, że repozytoria GitHub są zwykłymi repozytoriami (nie mają kopii roboczych), ale twoje lokalne tak. Wyobrażam sobie, że gdybyś sklonował nowe repozytorium z pochodzenia GitHub, nie miałbyś tych katalogów.
mipadi
18
Ale oczywiście uruchom polecenie z -n(suchym uruchomieniem) zamiast -fpierwszego, abyś mógł zobaczyć, co zostanie usunięte. Zwłaszcza, że git clean -dusuwa nie tylko te kłopotliwe katalogi, ale także nieśledzone pliki.
Todd Owen
2
@EliGolin: git cleannie usuwa plików wymienionych w .gitignore, chyba że przejdziesz tę -xopcję.
mipadi
4

Jako część większości operacji, które zmieniają drzewo robocze (ściąganie, scalanie, wyewidencjonowywanie itp.) Git usunie wszystkie katalogi, które zostały opróżnione przez tę operację (tj. Git usunął ostatni plik).

git nie usunie żadnych katalogów, które nie są całkowicie puste, więc jeśli masz ukryte lub zignorowane pliki, to tylko dlatego, że git usuwa ostatni śledzony plik z tego katalogu, nie musi oznaczać, że git będzie w stanie usunąć ten katalog. git nie uważa tego za błąd, więc nie będzie narzekać.

CB Bailey
źródło
Moje repozytorium GitHub nie ma katalogów. Kiedy zatwierdziłem, poprawnie usunęło katalogi. Jednak kiedy wyewidencjonuję / ściągam, usuwa tylko pliki. Katalogi są puste. $ ls -al total 8 drwxr-xr-x 2 mculp mculp 4096 23 września 15:43 ./ drwxr-xr-x 8 mculp mculp 4096 30 września 10:51 ../
mculp
1
Nie jestem do końca pewien, co masz na myśli, mówiąc „zamieniłem HEAD na master”, przypuszczam, że masz na myśli „ git checkout master”, ale większość ludzi po prostu powie: „Przerzuciłem / sprawdziłem mistrza”. W każdym razie, kiedy git powiedział: „Już aktualne”. to znaczy, że nic nie zrobił. git usunie tylko te katalogi, które uczyni pustymi.
CB Bailey,
Złe sformułowanie. Zmieniłem „HEAD” na „master”, jak niektórzy sugerowali w komentarzach.
mculp,
@CharlesBailey, nie widzę tego, co powiedziałeś. git checkoutnie usunął całkowicie pustego katalogu.
Acumenus,
@ABB: Git usuwa tylko katalogi, które są wykonane pusty przez operację transakcji. Przetestowałem to ponownie; to nadal działa.
CB Bailey
3

Miałem ten sam problem, w moim przypadku w usłudze kompilacji (CI) .. ponieważ GIT ściąga wszystkie pliki bez czyszczenia folderów, wszystkie bin / obj, które zostały wcześniej zbudowane przez CI są brudne, więc jeśli usunę projekt testowy, bin będzie nadal zawierał bibliotekę DLL i wspomina o testach, które nie istnieją.

W celu rozwiązania tego problemu; to polecenie wydaje się działać (przynajmniej dla mnie)

git clean -fd -x

gdzie X usunie wszystkie nieśledzone pliki:

-X Usuwa tylko pliki ignorowane przez Git. Może to być przydatne do odbudowania wszystkiego od podstaw, ale zachowaj ręcznie utworzone pliki.

Yogurtu
źródło
2

Git nie śledzi katalogów, plików (wraz z ich ścieżką). Git tworzy wszystkie katalogi dla tych ścieżek, jeśli jeszcze nie istnieją (super!), Jednak nie usuwa ich, jeśli wszystkie pliki zawarte w ścieżce zostaną przeniesione lub usunięte (nie fajne ☹ ... ale są powody).

Rozwiązanie (po przeciągnięciu / przewinięciu do przodu / połączeniu):

git stash --include-untracked
git clean -fd
git stash pop

Jeśli tego nie zrobisz stashwcześniej clean, stracisz wszystkie nieśledzone pliki (nieodwracalnie).

Uwaga: ponieważ powoduje to również wyczyszczenie wszystkich ignorowanych plików, może być konieczne ponowne uruchomienie niektórych skryptów kompilacji, aby odtworzyć metadane projektu (np.:) ./gradlew eclipse. To także usuwa katalogi, które są puste i które nigdy nie były częścią ścieżek plików git.

qwertzguy
źródło
-1

Git nie śledzi obecnie katalogów (patrz git wiki ), to znaczy nie możesz dodawać pustych katalogów ani git usuwać katalogów, które kończą się puste. (EDYCJA: Dzięki, Manni, myliłem się! Nie możesz dodawać pustych katalogów, ale git usunie katalogi, które staną się puste, ponieważ ich śledzona zawartość została usunięta. )

Co do polecenia usunięcia pustych katalogów: to zależy od systemu operacyjnego.

W przypadku Linuksa możesz użyć np.

find -depth -type d -empty -exec rmdir {} \;

Jednak spowoduje to usunięcie wszystkich pustych katalogów!

janko
źródło
1
Strona wiki mówi, że git nie tworzy dla ciebie pustych katalogów. To nie nie powiedzieć, że nie usunie pustych katalogów. To, czego chce mculp, działa dla mnie.
innaM
@janko, Właściwie, git nie mógł usunąć dla mnie całkowicie pustego katalogu.
Acumenus,