git mv i zmieniaj tylko wielkość liter katalogu


259

Podczas gdy znalazłem podobne pytanie , nie znalazłem odpowiedzi na mój problem

Kiedy próbuję zmienić nazwę katalogu z FOO na foo przez git mv FOO foo, dostaję

fatal: renaming 'FOO' failed: Invalid argument

DOBRZE. Więc próbujęgit mv FOO foo2 && git mv foo2 foo

Ale kiedy próbuję dokonać transakcji za pośrednictwem git commit ., dostaję

# On branch master
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
# foo
nothing added to commit but untracked files present (use "git add" to track)

Gdy dodam katalog przez git add foonic, nic się nie zmieni i ponownie git commit .otrzymam ten sam komunikat.

Co ja robię źle? Myślałem, że używam systemu z rozróżnianiem wielkości liter (OSX), dlaczego nie mogę po prostu zmienić nazwy katalogu?


10
System plików OS X nie rozróżnia wielkości liter.
mipadi

2
@mipadi Może działać w trybie rozróżniania wielkości liter, ale zwykle jest to domyślnie wyłączone.
GordonM

1
To pytanie i jego odpowiedzi są również przydatne w systemie Windows. Rozważ odznaczenie „osx”
Barett

1
Zobacz stackoverflow.com/a/24979063/6309 : od wersji git 2.0.1 prosta git mvpraca.
VonC

W systemie Windows możesz użyć zwykłego, git mv foo Foojeśli używasz powłoki cygwin.
Andrew Scott,

Odpowiedzi:


409

Jesteś w środowisku niewrażliwym na wielkość liter. Co więcej, dodając bez, -Anie zajmie się usunięciem strony, mvponieważ Git to rozumie. Ostrzeżenie! Upewnij się, że nie ma w pobliżu żadnych innych zmian ani nieśledzonych plików, ponieważ zostaną one zatwierdzone w ramach tej zmiany! git stash -unajpierw zrób to, a potem git stash pop. Kontynuacja: Aby obejść ten problem, wykonaj następujące czynności:

mv foo foo2
git add -A
git commit -m "renaming"
mv foo2 FOO
git add -A
git commit --amend -m "renamed foo to FOO"

Jest to wyciągnięty sposób na zmianę katalogu roboczego, zatwierdzanie, a następnie zwijanie 2 zatwierdzeń. Możesz po prostu przenieść plik do indeksu, ale dla kogoś, kto jest nowy w git, może nie być wystarczająco wyraźne, co się dzieje. Krótsza wersja to

git mv foo foo2
git mv foo2 FOO
git commit -m "changed case of dir"

Jak zasugerowano w jednym z komentarzy, możesz również zrobić interaktywny rebase ( git rebase -i HEAD~5jeśli wprowadzono niewłaściwy przypadek 5 zatwierdzeń temu), aby go naprawić i nie wyświetlać niewłaściwego przypadku w dowolnym miejscu w historii. Musisz być ostrożny, jeśli to zrobisz, ponieważ odtąd skróty zatwierdzania będą inne, a inni będą musieli bazować lub ponownie łączyć swoją pracę z niedawną przeszłością oddziału.

Jest to związane z poprawieniem nazwy pliku: czy w git nie jest rozróżniana wielkość liter?


1
Dzięki. Doprowadzało mnie to do szału. Nie wiedziałem o opcji -A lub --amend.
oschrenk

7
Ostrożnie z opcją -A, ponieważ rekurencyjnie doda ona całą zawartość do twojego bieżącego katalogu, w tym nieśledzone rzeczy. Może lepiej być po prostu git add foo2.
bogaty. E

2
To jest poprawne. Konieczne będzie jednak stopniowe usuwanie zarówno usuwania Foo2, jak i dodawania FOO osobno. -Adba o oba. Odwrotnie dla pierwszego kroku. Dodam ostrzeżenie. Dzięki!
Adam Dymitruk,

Możesz także wyczyścić swoją historię za pomocą interaktywnego bazy git rebase -i HEAD~2. Uwaga: Aby to uprościć, ustaw końcową wiadomość w pierwszym zatwierdzeniu i napraw drugą.
Alex B.

5
Miałem sukces z git mv foo foo2; git mv foo2 FOO; git commit
Chris

146

Chcesz ustawić opcję core.ignorecasena false, co spowoduje, że Git zwróci uwagę na wielkość liter w systemach plików, które nie obsługują go natywnie. Aby włączyć w repozytorium:

$ git config core.ignorecase false

Następnie możesz zmienić nazwę pliku za pomocą git mvi będzie działać zgodnie z oczekiwaniami.


1
Myślę, że może to mieć niepożądane skutki w innym miejscu. Systemy bez rozróżniania wielkości liter powinny pozwolić Gitowi myśleć, że to ten sam katalog.
Adam Dymitruk

2
Dodałem opcję do mojej globalnej konfiguracji, ale to nie pomogło
oschrenk

3
Widzę dziwne zachowanie podczas używania tego z OSX. hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:ale ... te pliki nie istnieją.
Skylar Saveland

Właśnie tego szukałem. Korzystam z CentOS 5.6 i nie wykrył zmiany wielkości liter.
crmpicco

5
To nie działa! W Git 1.8.3 Git będzie traktował plik o zmienionej nazwie jako nowy plik, zamiast usuwać + dodawać. Zatwierdzenie spowoduje pozostawienie repozytorium z tym samym plikiem, np. Istnieją zarówno Foo, jak i FOO! Ale kiedy w kasie pojawia się tylko jeden plik (ale jeden przypadek może dominować nad drugim)
Johnny Wong

68

Udało mi się to rozwiązać, używając git 1.7.7, używając tymczasowej nazwy pliku:

$ git mv improper_Case improve_case2
$ git mv improve_case2 improve_case
$ git commit -m "<your message>"

Ciekawy. Może od tego czasu GIT coś ulepszył. Kiedy znów napotkam ten problem, spróbuję ponownie.
oschrenk

o wiele łatwiej robić to w ten sposób
więcej

Pracował dla mnie na macOS.
Mr_Pouet,

14

(git mv -bezpłatny wariant.)

Ten problem napotkałem w Git na Mac OS X 10.9. Rozwiązałem to w następujący sposób:

git rm -r --cached /path/to/directory

To ustawia katalog do usunięcia w Git, ale tak naprawdę nie usuwa żadnych fizycznych plików (--cached ). To sprawia, że ​​katalog, teraz z odpowiednią literą, pojawia się w nieśledzonych plikach.

Możesz to zrobić:

mv /path/to/directory /path/to/DIRECTORY
git add -A /path/to/DIRECTORY

Git rozpozna wtedy, że zmieniłeś nazwy plików, a kiedy to zrobisz git status, powinieneś zobaczyć kilka renamed:linii. Sprawdź je i upewnij się, że wyglądają poprawnie, a jeśli tak, możesz zatwierdzić zmiany normalnie.


Odkryłem, że mvpolecenie nie działało, aby faktycznie zmienić nazwę katalogu; Musiałem zmienić nazwę w Finderze. Poza tym ta poprawka działa idealnie.
Adam S

9

Jest to szybkie i bezpieczne rozwiązanie:

git mv -f path/to/foo/* path/to/FOO/

Ostrzeżenie! Zawsze zmieniaj nazwy wszystkich plików w folderze o zmienionej nazwie (użyj /*).

Nie zmieniaj nazw pojedynczych plików. Prowadzi to do błędu opisanego w tej odpowiedzi .

Jeśli chcesz najpierw zobaczyć wynik, użyj -n:

git mv -f -n path/to/foo/* path/to/FOO/

Po dokonaniu mv:

  1. Zatwierdź zmiany
  2. Kasa do dowolnej innej wersji
  3. Kasa z powrotem.

Teraz Git powinien zmienić nazwę folderu ZARÓWNO w swoich plikach wewnętrznych i systemie plików.


Czy to dotyczy tylko Git 2.0.1, jak wspomniałem w komentarzach do pytania powyżej? (w odniesieniu do stackoverflow.com/a/24979063/6309 )
VonC

8

Wymuś to z opcją -f:

git mv -f FOO foo

Nie pracuj dla mnie. Moje ustawienie to „ignorecase = true” .git / config. W ten sposób zmiana nazwy nie może być realizowana w obszarze przeciwności. (Git wersja 1.8.3.msysgit.0) Rozwiązanie Adama Dymitruka jest jedyną prawidłową odpowiedzią.
Johnny Wong,

@JohnnyWong zmień ustawienie na false, zadziałało dla mnie
Inder Kumar Rathore

Czy to się zaktualizuje na wszystkich komputerach innych użytkowników, jeśli będą pobierać, nawet jeśli ich komputer jest ustawiony tak, aby ignorować wielkość liter?
Bryce

@Bryce Nie, musisz zatwierdzić zmiany i przekazać je do centralnego repozytorium, zanim inni użytkownicy będą mogli je pobrać.
konyak

3

Miałem jeden związany problem.

Jeden folder o nazwie „Pro” (utworzony jako pierwszy) i inny „pro” (utworzony przez pomyłkę). Na Macu jest to to samo, ale różni się w zależności od git.

$ git config core.ignorecase false

git config zmienia nazwy plików na właściwy folder (dzięki), a także tworzy pliki duchów w 'pro' (Nie !!). Nie mogłem dodać zmian pliku widma do ścieżki i nie mogłem wyewidencjonować innych gałęzi, chyba że niosę te pliki ze sobą, a także nie mogłem go zresetować.

Zamiast tego zrobiłem

$ git rm -r --cached pro
$ git status // => pro files removed, new Pro files untracked
$ git add Pro

Aby uczynić go wyjątkowo bezpiecznym, zrobiłem to w oddzielnej gałęzi napraw, a następnie ponownie połączyłem się z główną gałęzią

Czy dla guru utworzonego przez plik ducha każdy guru może wyjaśnić, jak i dlaczego? Z góry dziękuję.


2

Nie używasz systemu plików z rozróżnianiem wielkości liter w OS X, chyba że wyraźnie wybierzesz taki system. HFS + może być wielkość liter, ale domyślnie jest wielkość liter.


4
Używanie systemu plików z rozróżnianiem wielkości liter w systemie OS X nie jest dobrym pomysłem. Wiele aplikacji NIE działa poprawnie, nauczyłem się, próbując tego. Jednym szczególnym problemem jest to, że Adobe Photoshop odmówi instalacji, mówiąc, że system plików z rozróżnianiem wielkości liter nie jest obsługiwany.
jpswain

1

Oto naprawdę proste rozwiązanie dotyczące całego gitfoo na tej stronie.

  1. Skopiuj pliki z projektu ręcznie.
  2. git rm wszystkie pliki.
  3. git commit jak zwykle.
  4. dodaj pliki z powrotem ręcznie.
  5. git dodaj wszystkie pliki.
  6. git commit jak zwykle.
  7. zysk.

1
Działa to lokalnie, ale jeśli ktoś wykona pociągnięcie, nie zmieni to swojego przypadku.
Jason

Dzięki za to, że pomogłem mi naprawić podwójne wpisy w git w różnych przypadkach. Użyłem wariantu tego. Właśnie zmieniłem nazwę folderu nadrzędnego. Dokonał zatwierdzenia. Następnie zmieniono nazwę folderu nadrzędnego z powrotem na oryginalny. I zrobił drugie zatwierdzenie. Teraz zniknęły starsze wpisy z inną literą.
dreamerkumar 12.04.17

0

Poprawienie odpowiedzi Adama Dymitruka (głupie, że SO nie pozwala mi skomentować jego odpowiedzi), użycie „git mv” automatycznie ustawi dokładnie przeniesione pliki. Nie jest konieczne składowanie i ryzykownego „git add -A” można uniknąć:

old="abc";    new="ABC";
tmp="$old-renamed";
git mv "$old" "$tmp";
git commit -m "Renamed '$old' to '$tmp'.";
git mv "$tmp" "$new";
git commit --amend -m "Renamed '$old' to '$new'.";

0

Działa to świetnie dla mnie w systemie Windows. Używany PowerShell z następującymi elementami:

  1. mv .\Folder-With-Wrong-Casing .\temp
  2. git add -A
  3. git commit -m "renamed folder with wrong casing to temp"
  4. mv .\temp .\Folder-with-Correct-Casing
  5. git add -A
  6. git commit --amend -m "Renamed to proper casing"
  7. (opcjonalny) git push

Dzięki powyższej odpowiedzi Adama.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.