git mv e cambia solo il caso della directory


259

Mentre ho trovato una domanda simile, non ho trovato una risposta al mio problema

Quando provo a rinominare la directory da FOO a foo via git mv FOO fooottengo

fatal: renaming 'FOO' failed: Invalid argument

OK. Quindi ci provogit mv FOO foo2 && git mv foo2 foo

Ma quando provo a impegnarmi tramite git commit .ottengo

# 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)

Quando aggiungo la directory senza git add foocambiare nulla e git commit .mi restituisce lo stesso messaggio.

Che cosa sto facendo di sbagliato? Pensavo di usare un sistema sensibile al maiuscolo / minuscolo (OSX) perché non posso semplicemente rinominare la directory?


10
Il file system di OS X non fa distinzione tra maiuscole e minuscole.
mipadi,

2
@mipadi Può funzionare in modalità sensibile al maiuscolo / minuscolo ma di solito è disattivato per impostazione predefinita.
GordonM,

1
Questa domanda e le sue risposte sono utili anche in Windows. Prova a deselezionare "osx"
Barett il

1
Vedi stackoverflow.com/a/24979063/6309 : da git 2.0.1, git mvfunziona in modo semplice .
VonC,

Su Windows puoi usare il normale git mv foo Foose usi una shell cygwin.
Andrew Scott,

Risposte:


409

Sei in un ambiente senza distinzione tra maiuscole e minuscole. Inoltre, aggiungendo senza il -Anon ci occuperemo del lato di rimozione di mvcome Git lo capisce. Avvertimento! Assicurati che non ci siano altre modifiche o file non tracciati quando lo fai o verranno impegnati come parte di questa modifica! git stash -uprima fai questo e poi git stash popdopo. Continua: per ovviare a questo, procedi come segue:

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

Questo è il modo elaborato di cambiare la directory di lavoro, eseguire il commit e quindi comprimere i 2 commit. Puoi semplicemente spostare il file nell'indice, ma per qualcuno che è nuovo su Git, potrebbe non essere abbastanza esplicito su ciò che sta accadendo. La versione più corta è

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

Come suggerito in uno dei commenti, puoi anche fare un rebase interattivo ( git rebase -i HEAD~5se il caso sbagliato è stato introdotto 5 commit fa) per risolvere il caso lì e non far apparire il caso sbagliato in nessun punto della storia. Devi fare attenzione se lo fai poiché gli hash di commit da quel momento in poi saranno diversi e gli altri dovranno riformulare o ricongiungere il loro lavoro con quel recente passato del ramo.

Ciò è correlato alla correzione del nome di un file: git non è sensibile al maiuscolo / minuscolo?


1
Grazie. Questo mi stava facendo impazzire. Non sapevo dell'opzione -A o dell'opzione --amend.
Oschrenk,

7
Attento con -A, poiché aggiungerà in modo ricorsivo tutto il contenuto nella directory corrente, inclusi gli elementi non tracciati. Potrebbe essere meglio solo git add foo2.
rich.e

2
È corretto. Tuttavia sarà necessario mettere in scena sia la rimozione di foo2 che l'aggiunta di FOO separatamente. -Asi prende cura di entrambi. Viceversa per il primo passo. Aggiungerò l'avvertimento. Grazie!
Adam Dymitruk,

Puoi anche ripulire la tua cronologia con un rebase interattivo git rebase -i HEAD~2. Nota: per semplificare questo, impostare il messaggio finale nel primo commit e correggere il secondo.
Alex B.

5
Ho avuto successo con git mv foo foo2; git mv foo2 FOO; git commit
Chris

146

Volete impostare l'opzione core.ignorecasesu false, il che farà in modo che Git presti attenzione ai casi sui file system che non la supportano nativamente. Per abilitare nel repository:

$ git config core.ignorecase false

Quindi puoi rinominare il file con git mve funzionerà come previsto.


1
Penso che questo possa avere effetti indesiderati altrove. I sistemi con distinzione tra maiuscole e minuscole dovrebbero far pensare a Git che si tratti della stessa directory.
Adam Dymitruk,

2
Ho aggiunto l'opzione alla mia configurazione globale ma non ha aiutato
oschrenk,

3
Vedo alcuni comportamenti strani usando questo con OSX. hrm I modified a file that doesn't exist.. hrm error: The following untracked working tree files would be overwritten by checkout:ma ... quei file non esistono.
Skylar Saveland,

Questo era esattamente quello che stavo cercando. Sto eseguendo CentOS 5.6 e non ha rilevato il cambio di caso.
crmpicco,

5
Questo non funziona! Su Git 1.8.3, Git tratta il file rinominato come un nuovo file, anziché rimosso + aggiunto. Commettere tale lascerà il repository con due stessi file, ad esempio foo e FOO esistono entrambi! Ma al momento del checkout appare solo un file (ma un caso può dominare sull'altro caso)
Johnny Wong,

68

Sono stato in grado di risolvere questo problema, usando git 1.7.7 usando un nome file temporaneo:

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

Interessante. Forse GIT ha migliorato qualcosa da allora. Quando mi imbatterò di nuovo in questo problema, ci riproverò.
Oschrenk,

molto più facile farlo in questo modo
olore,

Ha funzionato per me su macOS.
Mr_Pouet,

14

(git mv variante -free.)

Ho riscontrato questo problema in Git su Mac OS X 10.9. L'ho risolto come segue:

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

Questo mette in scena la directory per la cancellazione in Git ma in realtà non rimuove alcun file fisico ( --cached). Questo rende anche la directory, ora con il caso corretto, mostrata in file non tracciati.

Quindi puoi farlo:

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

Git riconoscerà quindi che hai rinominato i file e quando lo fai git statusdovresti vedere un numero di renamed:righe. Ispezionali e assicurati che appaiano corretti e, in tal caso, puoi eseguire il commit delle modifiche normalmente.


Ho scoperto che il mvcomando non ha funzionato per rinominare effettivamente la directory; Ho dovuto rinominarlo in Finder. A parte questo, questa correzione funziona perfettamente.
Adam S,

9

Questa è una soluzione rapida e sicura per i bug:

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

Avvertimento! Rinomina sempre tutti i file nella cartella rinominata (usa /*).

Non rinominare singoli file. Questo porta a un bug, descritto in questa risposta .

Se prima vuoi vedere prima il risultato, usa -n:

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

Dopo aver fatto un mv:

  1. Effettua modifiche
  2. Vai a qualsiasi altra revisione
  3. Torna indietro.

Ora Git avrebbe dovuto rinominare la cartella ENTRAMBI nei suoi file interni e nel file system.


È solo per Git 2.0.1, come ho detto nei commenti alle domande precedenti? (riferendosi a stackoverflow.com/a/24979063/6309 )
VonC

8

Forzalo con l'opzione -f:

git mv -f FOO foo

Non lavorare per me. La mia impostazione è "ignorecase = true" di .git / config. In questo modo non è possibile mettere in scena la ridenominazione nell'area di gestione temporanea. (Git versione 1.8.3.msysgit.0) La soluzione di Adam Dymitruk è l'unica risposta giusta.
Johnny Wong,

@JohnnyWong cambia la tua impostazione false, ha funzionato per me
Inder Kumar Rathore,

Questo verrà quindi aggiornato su tutti i computer degli altri utenti se eseguono il pull, anche se il loro computer è impostato per ignorare il caso?
Bryce,

@Bryce No, dovrai eseguire il commit delle modifiche e inviarle al repository centrale prima che altri utenti possano eseguire le modifiche.
Konyak,

3

Ho avuto un problema correlato.

Una cartella denominata "Pro" (creata per prima) e un'altra "pro" (creata per errore). In Mac, è la stessa cosa, ma diversa a seconda di git.

$ git config core.ignorecase false

la configurazione git rinomina i file nella cartella giusta (grazie) e ha anche creato i file fantasma in 'pro' (No !!). Non ho potuto aggiungere le modifiche ai file fantasma alla traccia e non ho potuto effettuare il checkout di altri rami a meno che non portassi quei file con me, e in qualche modo non sono riuscito a ripristinarlo.

Invece, l'ho fatto

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

Per renderlo ancora più sicuro, l'ho fatto in un ramo di correzione separato, e poi mi sono unito al ramo principale

Per il problema del file fantasma creato da, un guru può spiegare come e perché? Grazie in anticipo.


2

Non stai usando un filesystem con distinzione tra maiuscole e minuscole in OS X a meno che tu non scelga esplicitamente tale. HFS + può fare distinzione tra maiuscole e minuscole, ma l'impostazione predefinita non distingue tra maiuscole e minuscole.


4
L'uso del file system con distinzione tra maiuscole e minuscole su OS X non è una buona idea. Molte app NON funzionano correttamente, ho imparato provando questo. Un problema particolare è che Adobe Photoshop rifiuterà l'installazione affermando che il file system con distinzione tra maiuscole e minuscole non è supportato.
jpswain,

1

Ecco una soluzione davvero semplice attorno a tutto il gitfoo in questa pagina.

  1. Copia i file dal tuo progetto manualmente.
  2. git rm tutti i file.
  3. git si impegna come di consueto.
  4. aggiungere nuovamente i file manualmente.
  5. git aggiunge tutti i file.
  6. git si impegna come di consueto.
  7. profitto.

1
Funziona localmente, ma se qualcun altro fa un pull non cambierà il loro caso.
Jason,

Grazie per avermi aiutato a correggere le doppie voci in git con casi diversi. Ho usato una variante di questo. Ho appena rinominato la cartella principale. Ha fatto un commit. Quindi rinominato la cartella principale in originale. E ha fatto un secondo impegno. Ora le voci più vecchie con il caso diverso sono sparite.
dreamerkumar,

0

Migliorare la risposta di Adam Dymitruk (sciocco che SO non mi lascia commentare la sua risposta), usando "git mv" metterà automaticamente in scena esattamente i file spostati. Non è necessario alcun ripostiglio e si può evitare il rischioso "git add -A":

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

Questo ha funzionato alla grande su Windows. Powershell usato con il seguente:

  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. (opzionale) git push

Grazie alla risposta di Adam sopra.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.