Uwaga! Trwają prace nad nową wersją serwisu. Mogą występować przejściowe problemy z jego funkcjonowaniem. Przepraszam za niedogodności!

🔥 Zgarnij PŁATNY STAŻ w 3 edycji kursu programowania front end (zapisy do 22.01) 🔥

Git nie ogarnia? Jak zmienić wielkość liter w nazwach plików i katalogów

Rejestruj zmiany w historii Gita, by uniknąć błędów

To problem który może zaatakować w najmniej spodziewanym momencie, na przykład podczas rekrutacji! Czy nazwy plików lub katalogów zmieniasz za pomocą zwykłego „Rename”? Zła wiadomość jest taka, że Git może nie zauważyć tych zmian, a Ty skończysz z masą błędów. Dobra wiadomość jednak też jest: możemy temu zapobiec!

Spis treści

 Wielkość liter a Git – w czym problem?

Systemy plików mają różne domyślne ustawienia wrażliwości na wielkość liter (case sensitivity). Przykładowo system plików na Linuksie jest wrażliwy, a na Mac OS-ie i Windowsie nie.

Wrażliwość: Helper.js i helper.js to dla systemu dwa różne pliki.

Niewrażliwość: Helper.js, helper.js, a nawet HeLpEr.js to dla systemu te same pliki.

Pomyślisz: co Cię to obchodzi, gdy pracujesz tylko na jednym systemie? Oto parę możliwych problemów:

  • jeśli będziesz podpinać na GitHubie podgląd projektu na żywo (GitHub Pages), to nazwy różniące się wielkością liter nie zostaną rozpoznane jako te same,
  • jeśli rekruter używa innego systemu niż Ty, może napotkać problem przy uruchamianiu Twojego projektu,
  • korzystanie z Codespace’a na GitHubie do uruchomienia projektu w chmurze również może sypnąć błędami.

Poniżej widzisz przykład: pierwotnie katalog z fontami nazywał się Overpass. Autor projektu pracujący na Windowsie zmienił pierwszą literę nazwy katalogu na małą, zaktualizował ścieżki importu i pushował zmiany na repo. W podpiętych GitHub Pages wszystkie importy fontów się wysypały, ponieważ Git nie zarejestrował zmiany nazwy katalogu, a tym samym nie została ona uwzględniona w repozytorium zdalnym.

Katalog plików Overpass ma wielką literę, a w pliku fonts.css w ścieżkach prowadzących do tego katalogu litera jest mała.

Na stronie wyświetla się tekst z domyślnym fontem, a w konsoli są błędy "failed to load resource", ponieważ GitHub Pages nie potrafią rozpoznać ścieżek do plików z fontami.

Git został pierwotnie zbudowany jako system kontroli wersji jądra Linuksa, więc rozróżnia wielkość liter. Potrafi jednak wykryć domyślne ustawienia wrażliwości na wielkość liter w systemie i przechowuje tę informację w opcji core.ignoreCase repozytorium. Gdy opcja ta jest ustawiona na true (tak stanie się np. na Windowsie), Git nie wykrywa zmiany nazwy pliku lub katalogu po zmianie wielkości liter.

Jak możemy zapisać w historii Gita coś, czego on „nie zauważył”?

 Jak zacommitować zmianę wielkości liter pliku lub katalogu?

 Zmiana nazwy pliku

Aby zmienić wielkość liter w nazwie jednego pliku, użyj polecenia git mv:

git mv Helper.js helper.js

W Git przy zmienionym pliku widzimy literę R, co znaczy, że jego nazwa została zmieniona.

Jak widzisz, zmiana nazwy z Helper.js na helper.js została zarejestrowana (R oznacza Renamed).

 Zmiana nazwy katalogu

Załóżmy, że mamy teraz katalog Overpass z przykładu z fontami.

Teoretycznie – zgodnie z dokumentacją – zmiany nazwy katalogu na małe litery dokonasz komendą:

git mv Overpass overpass

Może to jednak nie zadziałać, a w konsoli zobaczysz błędy, na przykład:

  1. Rename from 'Overpass' to 'overpass/Overpass' failed. Should I try again? (y/n),
  2. source directory is empty, source=Overpass, destination=overpass/Overpass,
  3. The process cannot access the file because it is being used by another process,
  4. fatal: Unable to create '.git/index.lock': File exists.

Możliwe rozwiązania błędów przy zmianie nazwy katalogu

1 – Rename failed… Should I try again?

W przypadku pierwszego błędu nie wiemy nawet, dlaczego proces się nie powiódł. Możesz wówczas spróbować obejść problemy z rozróżnianiem wielkości liter, nadając katalogowi nazwę tymczasową. Uruchom po kolei komendy:

git mv Styles tmp
git mv tmp styles

Słowo tmp to nazwa tymczasowa – nie ma znaczenia w kontekście komendy, możesz wybrać inną.

2 – source directory is empty

W przypadku drugiego błędu sprawdź, czy katalog został dodany do Gita. Zweryfikuj też, czy używasz prawidłowej ścieżki. Obie te rzeczy sprawdzisz komendą:

git ls-files

W ten sposób zobaczysz pliki i katalogi zarządzane przez Gita oraz ścieżki do nich prowadzące.

3 – The process cannot access the file because it is being used by another process

U mnie ten błąd wyświetlił się po polsku: proces nie może uzyskać dostępu do pliku ponieważ jest on używany przez inny proces. W przypadku tego błędu pozamykaj wszystkie procesy, które mogą korzystać z katalogu Twojego projektu. Problem może sprawiać nawet otwarty eksplorator plików (menedżer plików).

4 – fatal: Unable to create '.git/index.lock': File exists

Czwarty błąd mówi o tym, że albo Git jest w trakcie jakiegoś procesu, albo jakiś proces nie zakończył się prawidłowo (ang. gracefully) – co jest prawdopodobne, jeśli od dłuższej chwili walczymy komendami.

Plik index.lock tworzony jest tymczasowo podczas każdego procesu w Gicie. Zabezpiecza on nas przed tym, by wiele procesów nie zmieniało tych samych elementów repozytorium w jednym czasie.

Jeżeli zdarzy się, że plik index.lock nie został usunięty po przeprowadzeniu procesu, możemy usunąć go ręcznie:

rm .git/index.lock

 Zmiana kilku nazw plików jednocześnie

Jeżeli chcesz zmienić wielkie litery na małe w nazwach kilku plików jednocześnie, to w Visual Studio Code w terminalu (powershell) zadziała pętla:

foreach ($f in (git ls-files -- '*.js')) {
$newName = $f.ToLower()
git mv -k $f $newName
}

Zwróć uwagę, że akurat ta pętla dotyczy wszystkich plików z rozszerzeniem .js zarejestrowanych przez Gita. Jeżeli chodzi Ci o pliki w konkretnym podkatalogu, dodaj odpowiednią ścieżkę do komendy, na przykład:

foreach ($f in (git ls-files -- './helpers/*.js')) {
$newName = $f.ToLower()
git mv -k $f $newName
}

Gdyby komenda ta rzucała błędami, zerknij powyżej do błędów omówionych w przypadku zmiany nazwy katalogu – część z nich może się powielać.

 Nie zmieniaj core.ignoreCase

Możesz napotkać źródła, które zalecają wyłączenie (czyli ustawienie na false) opcji core.ignoreCase dla repozytorium lub nawet globalnie. Spowoduje to, że Git wykryje zmiany wielkości liter na systemach plików niewrażliwych na wielkość liter, ale niestety może doprowadzić do niepożądanych zachowań, jak ostrzega dokumentacja Gita:

Git relies on the proper configuration of this variable for your operating and file system. Modifying this value may result in unexpected behavior.

Więcej o niepożądanych działaniach przeczytasz na Slack Overflow.

 

Jeśli używasz Windowsa albo MacOS-a, pozostaje pamiętać, by po decyzji dotyczącej zmiany wielkości liter w nazwie pliku lub katalogu, zadbać o to, by Git „dowiedział się” o modyfikacji nazwy. Teraz już wiesz, jak to zrobić i jak poradzić sobie z błędami!

Udostępnij ten artykuł:

Mentoring to efektywna nauka pod okiem doświadczonej osoby, która:

  • przekazuje Ci swoją wiedzę i nadzoruje Twoje postępy w zdobywaniu umiejętności,
  • uczy Cię dobrych praktyk i wyłapuje złe nawyki,
  • wspiera Twój rozwój i zwiększa zaangażowanie w naukę.

Mam coś dla Ciebie!

W każdy piątek rozsyłam motywujący do nauki programowania newsletter!

Dodatkowo od razu otrzymasz ode mnie e-book o wartości 39 zł. To ponad 40 stron konkretów o nauce programowania i pracy w IT.

PS Zazwyczaj wysyłam 1-2 wiadomości na tydzień. Nikomu nie będę udostępniał Twojego adresu e-mail.