Oba przykłady w pytaniu są w rzeczywistości bardzo złymi przykładami, które mogą prowadzić do utraty danych!
Moja rada: nigdy nie dołączaj /*
do katalogów w plikach .gitignore, chyba że masz dobry powód!
Dobrym powodem byłoby na przykład to, co napisał Jefromi: „jeśli zamierzasz później zignorować coś w katalogu” .
Powodem, dla którego inaczej nie należy tego robić, jest to, że dołączanie /*
do katalogów z jednej strony działa w taki sposób, że właściwie ignoruje całą zawartość katalogu, ale z drugiej strony ma niebezpieczny efekt uboczny:
Jeśli wykonasz git stash -u
(aby tymczasowo ukryć śledzone i nieśledzone pliki) lub git clean -df
(aby usunąć nieśledzone, ale zachowaj zignorowane pliki) w swoim repozytorium, wszystkie katalogi, które zostaną zignorowane za pomocą dołączonego, /*
zostaną nieodwracalnie usunięte !
Trochę tła
Musiałem się tego nauczyć na własnej skórze. Ktoś z mojego zespołu dołączał /*
do niektórych katalogów w naszym .gitignore. Z czasem miałem okazje, aby niektóre katalogi nagle zniknęły. Katalogi z gigabajtami danych lokalnych wymaganych przez naszą aplikację. Nikt nie mógł tego wyjaśnić i zawsze nie mogę ponownie pobrać wszystkich danych. Po chwili zrozumiałem, że może to mieć związek z tym git stash
. Pewnego dnia chciałem wyczyścić moje lokalne repozytorium (zachowując zignorowane pliki) i używałem git clean -df
i znowu moje dane zniknęły. Tym razem miałem dość i zbadałem problem. W końcu doszedłem do wniosku, że przyczyną jest dołączony dodatek /*
.
Zakładam, że można to jakoś wyjaśnić faktem, że directory/*
ignoruje całą zawartość katalogu, ale nie sam katalog. Dlatego nie jest uważane za śledzone ani ignorowane, gdy rzeczy są usuwane. Chociaż git status
i git status --ignored
dać nieco inny obraz na nim.
Jak się rozmnażać
Oto jak odtworzyć zachowanie. Obecnie używam Git 2.8.4.
Katalog wywoływany localdata/
z fikcyjnym plikiem ( important.dat
) zostanie utworzony w lokalnym repozytorium git, a zawartość zostanie zignorowana przez umieszczenie /localdata/*
w .gitignore
pliku. Kiedy jedno z dwóch wymienionych poleceń git zostanie teraz wykonane, katalog zostanie (nieoczekiwanie) utracony.
mkdir test
cd test
git init
echo "/localdata/*" >.gitignore
git add .gitignore
git commit -m "Add .gitignore."
mkdir localdata
echo "Important data" >localdata/important.dat
touch untracked-file
Jeśli to zrobisz git status --ignored
, otrzymasz:
On branch master
Untracked files:
(use "git add <file>..." to include in what will be committed)
untracked-file
Ignored files:
(use "git add -f <file>..." to include in what will be committed)
localdata/
Teraz albo zrób
git stash -u
git stash pop
lub
git clean -df
W obu przypadkach rzekomo zignorowany katalog localdata
zniknie!
Nie jestem pewien, czy można to uznać za błąd, ale myślę, że jest to przynajmniej funkcja, której nikt nie potrzebuje.
Zgłoszę to na listę deweloperów git i zobaczę, co o tym myślą.
.gitignore
rozróżnia pliki i katalogi, które ignoruje? na przykład, czydata
vsdata/
oznacza różne rzeczy?