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.