Come posso eseguire il commit delle modifiche al nome del file solo sensibili al maiuscolo / minuscolo in Git?


1303

Ho cambiato un nome alcuni file da de-maiuscolo la prima lettera, come in Name.jpga name.jpg. Git non riconosce queste modifiche e ho dovuto eliminare i file e caricarli di nuovo. Esiste un modo in cui Git può distinguere tra maiuscole e minuscole quando si verificano le modifiche ai nomi dei file? Non ho apportato alcuna modifica al file stesso.


4
@se questo non è del tutto corretto, Git ha in realtà un'impostazione di configurazione che controlla se ignora o meno la distinzione tra maiuscole e minuscole.


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


Segnala questo post. Sono stato in grado di eseguire il commit, ma solo usando git commit -m "msg" senza percorsi di file come parametri. Ha aggiornato l'indice e verificato nel file. [Link] stackoverflow.com/questions/35790113/...
ARCHI

Risposte:


1518

Puoi usare git mv :

git mv -f OldFileNameCase newfilenamecase

12
questo mi dà 'la directory di origine è vuota' mentre non lo è
WiseStrawberry,

6
Usando MacOS qui (senza distinzione tra maiuscole e minuscole) e -f ha funzionato! Grazie per la punta
caesarsol il

49
Nelle versioni recenti, non è più necessario il -fflag.
Joshua Pinter,

8
Non dimenticare di fornire il percorso completo del file. Ovvio, lo so, ma mi ha preso per un po '
rickrizzo il

7
Per la parte superiore ha votato commento: si fa necessario l' -finterruttore con l'ultima git (2.18) altrimenti si potrebbe ottenere l' fatal: destination existserrore.
DeepSpace101,

1038

Git ha un'impostazione di configurazione che gli dice se essere case sensitive o insensibili: core.ignorecase. Per dire a Git di distinguere tra maiuscole e minuscole, è sufficiente impostare questa impostazione su false:

git config core.ignorecase false

Documentazione

Dalla git configdocumentazione :

core.ignorecase

Se vera, questa opzione abilita varie soluzioni alternative per consentire a git di funzionare meglio su filesystem che non fanno distinzione tra maiuscole e minuscole, come FAT. Ad esempio, se un elenco di directory trova makefilequando git si aspetta Makefile, git supporrà che sia davvero lo stesso file e continuerà a ricordarlo come Makefile.

L'impostazione predefinita è false, tranne git-clone (1) o git-init (1) eseguirà il probe e imposterà core.ignorecasetrue se appropriato quando viene creato il repository.

File system senza distinzione tra maiuscole e minuscole

I due sistemi operativi più popolari che dispongono di file system senza distinzione tra maiuscole e minuscole che conosco sono

  • finestre
  • OS X

9
Per contro, non penso che Mac OS X stesso non faccia distinzione tra maiuscole e minuscole. Invece, è il filesystem che determina la distinzione tra maiuscole e minuscole. Durante la formattazione di una partizione HFS +, gli utenti possono scegliere se renderlo sensibile al maiuscolo / minuscolo o non sensibile. La distinzione tra maiuscole e minuscole è l'impostazione predefinita.
spaaarky21,

225
Sembra molto interessante notare in questa risposta che impostare questa opzione falsesu un file system senza distinzione tra maiuscole e minuscole è una cattiva idea . Questo non è necessariamente ovvio. Ad esempio, ho appena provato questo sul mio Mac, pensando che avrebbe risolto i miei problemi, quindi ho rinominato un file da productPageCtrl.jsa ProductPageCtrl.js. git statusho visto un nuovo file chiamato ProductPageCtrl.jsma non pensavo che productPageCtrl.jsfosse stato eliminato. Quando ho aggiunto i nuovi file, eseguito il commit e inviato a GitHub, il repository GitHub ora conteneva entrambi i file anche se il mio repository locale (presumibilmente aggiornato) ne aveva solo uno.
Mark Amery,

5
@MarkAmery Sembra un bug nel tuo client Git. Hai presentato una segnalazione?
Domi,

24
@Domi questo non è un bug, questo è un comportamento previsto. In effetti è una cattiva idea impostare questo su false su un filesystem insensibile perché è quello che succede. Il motivo per cui git non ha visto il file minuscolo è stato cancellato è che il filesystem non lo segnala come cancellato in quanto ignora il caso mentre git non ha questa opzione impostata su false. Non è che i nomi dei file non abbiano maiuscole o minuscole su ntfs o fat, è solo che la ricerca del nome file sta ignorando il caso.
ohcibi,

15
@Domi git è abbastanza intelligente. Ecco perché si dovrebbe non attivare questa falsa su un file system insensibile caso. Utilizzare git mvper spostare il file e vedere come git lo gestisce. Se sposti il ​​file senza git, non c'è nulla che git possa fare poiché il filesystem non dice la verità a git. Questo è un problema di ntfs / fat / hfs e simili e non git / linux.
ohcibi,

158

Usando SourceTree sono stato in grado di fare tutto questo dall'interfaccia utente

  1. Rinomina FILE.ext inwhatever.ext
  2. Metti in scena quel file
  3. Ora rinomina whatever.ext infile.ext
  4. Metti di nuovo in scena quel file

È un po 'noioso, ma se hai solo bisogno di farlo in pochi file è piuttosto veloce


5
Lo stesso con git bash
Alex78191,

3
"Fase quel file" è la parte importante - nessuna delle altre risposte sopra ha funzionato per me. In realtà ha funzionato con il semplice prompt dei comandi di Windows.
Vlad Sabev,

1
Non mi ero reso conto che funzionasse attraverso l'area di stadiazione. Ma nel mio caso, volevo modificare i nomi delle cartelle e alcuni file all'interno di quelle cartelle. Quindi ho prima rinominato tutte le cartelle con nomi temporanei. Commessi i nuovi nomi (tutti i file all'interno) e i file "eliminati". Git li ha contrassegnati tutti come "rinominati". Quindi rinominato tutte quelle cartelle con le nuove versioni del caso e eseguito nuovamente il commit. Infine, ho unito questi 2 commit. Ma sulla base di ciò che hai scritto, avrei potuto fare tutto direttamente attraverso l'area di incontro, senza creare 2 commit + unisci.
ThermoX,

3
Funziona anche con gitkraken sul nome della cartella.
Philippe Matray,

Ho scritto uno script Python 3 per fare questo lavoro noioso: stackoverflow.com/a/58159822/4934640
utente

126

Questo è quello che ho fatto su OS X:

git mv File file.tmp
git mv file.tmp file

Due passaggi perché altrimenti ho ricevuto un errore "file esiste". Forse può essere fatto in un solo passaggio aggiungendo --cachedo simili.


21
come suggerisce la risposta in alto, -f(forza) è la bandiera che stai cercando
rperryng

5
@rperryng - no, il -fflag non aiuta nel caso in cui il FS sottostante non faccia distinzione tra maiuscole e minuscole. Tuttavia, la soluzione in due passaggi ha funzionato per me
HEKTO,

Utilizzando un FS senza distinzione tra maiuscole e minuscole (su Mac) e ha -ffunzionato! Grazie per la punta
caesarsol il

Questo ha funzionato anche con una cartella su Windows senza il -fflag.
nich

git -c "core.ignorecase=false" add .prenderà in considerazione i file il cui caso è stato modificato per il commit.
nietonfir,

67

A volte è utile cambiare temporaneamente la distinzione tra maiuscole e minuscole di Git:

Metodo n. 1: modifica della distinzione tra maiuscole e minuscole per un singolo comando:

git -c core.ignorecase=true checkout mybranchper disattivare la distinzione tra maiuscole e minuscole per un singolo checkoutcomando. O più in generale: . (Ringraziamo VonC per averlo suggerito nei commenti.)git -c core.ignorecase= <<true or false>> <<command>>

Metodo n. 2: modifica della distinzione tra maiuscole e minuscole per più comandi:

Per modificare l'impostazione più a lungo (ad es. Se è necessario eseguire più comandi prima di modificarla nuovamente):

  1. git config core.ignorecase(questo restituisce l'impostazione corrente, ad es false.).
  2. git config core.ignorecase <<true or false>> - imposta la nuova impostazione desiderata.
  3. ... Esegui più altri comandi ...
  4. git config core.ignorecase <<false or true>> - riporta il valore di configurazione alla sua impostazione precedente.

1
Perché non direttamente git -c core.ignorecase=<true or false> checkout <<branch>>? Nulla da resettare dopo.
VonC,

2
Ho avuto una strana esperienza del lavoro core.ignorecase proposto quando ho cambiato da minuscolo a maiuscolo, ma non per maiuscolo e minuscolo. sembra che l'unica soluzione affidabile sia smettere di usare un sistema operativo che non riconosce il caso del nome file.
aspirante

C'è un motivo per cui dovrebbe essere un cambiamento temporaneo? Ciò causerebbe qualche problema se lascio solo le impostazioni modificate in maiuscolo / minuscolo?
cytsunny,

Ciò può dipendere da alcuni fattori, in particolare se il file system di destinazione fa distinzione tra maiuscole e minuscole - consultare en.wikipedia.org/wiki/Case_sensitivity#In_filesystems . La modifica temporanea potrebbe essere necessaria se il file system di distribuzione ha una distinzione tra maiuscole e minuscole diversa rispetto al file system utilizzato per lo sviluppo. Anche nel mio caso lavoro in un team in cui tutti dovrebbero avere le stesse impostazioni Git (ovvero maiuscole e minuscole), quindi se lo spengo deve essere temporaneo.
Steve Chambers,

44

In OSX, per evitare questo problema ed evitare altri problemi con lo sviluppo su un filesystem senza distinzione tra maiuscole e minuscole, è possibile utilizzare Utility Disco per creare un'immagine disco / disco virtuale con distinzione tra maiuscole e minuscole .

Esegui l'utilità del disco, crea una nuova immagine del disco e usa le seguenti impostazioni (o modifica a tuo piacimento, ma mantieni la distinzione tra maiuscole e minuscole):

Schermata Utilità disco Mac

Assicurati di dire a Git che ora è su un case sensitive case:

git config core.ignorecase false

15
No, il nucleare sta eseguendo un'unità di avvio con distinzione tra maiuscole e minuscole su OSX. Dovrai vivere senza app scritte male (ahem, Adobe) o eseguirle nella loro macchina virtuale stupida, ma ne vale la pena se esegui il codice principalmente per i sistemi * nix.
Mike Marcacci,

1
Questa è l'unica opzione che funziona correttamente. Ho provato il resto e finisci in un sottaceto in un modo o nell'altro. Risolvi correttamente il problema facendo questo.
John Hunt,

2
Nota che Utility Disco ha un bug OS X 10.11: non creerà immagini con distinzione tra maiuscole e minuscole. È necessario utilizzare lo strumento da riga di comando hdiutil. apple.stackexchange.com/questions/217915/…
dellsala il

7
Con APFS in High Sierra questo è ancora più semplice. Fare clic sull'icona di un'unità con un plus e aggiungere un volume con distinzione tra maiuscole e minuscole senza limiti di dimensioni. Condivide solo lo spazio con il volume principale e si monta su / Volumes / volume-name.
Michael Fox,

21

Ho provato le seguenti soluzioni dalle altre risposte e non hanno funzionato:

Se il repository è ospitato in remoto (GitHub, GitLab, BitBucket), è possibile rinominare il file sull'origine (GitHub.com) e forzare la ridenominazione del file in modo discendente.

Le istruzioni seguenti si riferiscono a GitHub, tuttavia l'idea generale dietro di esse dovrebbe applicarsi a qualsiasi piattaforma di hosting di repository remota. Tieni presente il tipo di file che stai tentando di rinominare le questioni, ovvero se si tratta di un tipo di file che GitHub considera modificabile (codice, testo, ecc.) O non modificabile (immagine, binario, ecc.) Nel browser.

  1. Visita GitHub.com
  2. Passare al repository su GitHub.com e selezionare il ramo in cui si sta lavorando
  3. Usando lo strumento di navigazione dei file del sito, vai al file che intendi rinominare
  4. GitHub ti consente di modificare il file all'interno del browser?
    • a.) Modificabile
      1. Fai clic sull'icona "Modifica questo file" (sembra una matita)
      2. Modificare il nome file nell'input di testo del nome file
    • b.) non modificabile
      1. Apri il pulsante "Scarica" ​​in una nuova scheda e salva il file sul tuo computer
      2. Rinomina il file scaricato
      3. Nella scheda precedente su GitHub.com, fai clic sull'icona "Elimina questo file" (sembra un cestino)
      4. Assicurati che il branchnamepulsante di opzione "Conferma direttamente nella diramazione" sia selezionato e fai clic sul pulsante "Conferma modifiche"
      5. Nella stessa directory su GitHub.com, fai clic sul pulsante "Carica file"
      6. Carica il file rinominato dal tuo computer
  5. Assicurati che il branchnamepulsante di opzione "Conferma direttamente nella diramazione" sia selezionato e fai clic sul pulsante "Conferma modifiche"
  6. A livello locale, controlla / recupera / tira il ramo
  7. Fatto

Ho rinominato direttamente su BitBucket e ha funzionato. Grazie.
rsc,

Buono a sapersi. Questa tecnica dovrebbe teoricamente funzionare su qualsiasi piattaforma di hosting di repository, ma sarei interessato a sapere se ce ne sono con cui non funzionerebbe.
gmeben,

Non funziona per i file che non possono essere modificati nel browser, come immagini o PDF; non c'è alcuna opzione di modifica, ovviamente.
Abhijit Sarkar,

@AbhijitSarkar Ottimo punto. Ho aggiornato la mia risposta per quei casi. Ho testato e verificato il funzionamento di queste istruzioni.
gmeben,

Qualcuno riesce a rinominare una directory in questo modo?
Solvitieg,

21

Simile alla risposta di @ Sijmen, questo è ciò che ha funzionato per me su OSX quando ho rinominato una directory (ispirata a questa risposta da un altro post):

git mv CSS CSS2
git mv CSS2 css

Il semplice fatto ha git mv CSS cssdato l'errore dell'argomento non valido: fatal: renaming '/static/CSS' failed: Invalid argumentforse perché il file system di OSX non distingue tra maiuscole e minuscole

ps BTW se stai usando Django, anche collectstatic non riconoscerebbe la differenza tra maiuscole e minuscole e dovresti fare quanto sopra, manualmente, anche nella directory root statica


19

1) rinominare il file Name.jpginname1.jpg

2) commit file rimosso Name.jpg

3) rinominare il file name1.jpginname.jpg

4) ammendare il file aggiunto name.jpgal commit precedente

git add
git commit --amend

2
Ricevo questo fatal: bad source, source=name1.jpg, destination=name.jpgal passaggio 3. Hai suggerimenti? Grazie
Anthony Kong,

1
Non puoi fare un commit, solo git add.
Alex78191,

Sembra molto confuso, vero? O patch di scimmia.
Jeromej,

18

Ho usato i seguenti passaggi:

git rm -r --cached .
git add --all .
git commit -a -m "Versioning untracked files"
git push origin master

Per me è una soluzione semplice


Questa è la soluzione E a differenza delle altre risposte, funziona bene quando si eseguono rinominazioni batch. Su glamourphilly.org dovevamo cambiare ogni .Jpg in .jpg. In Finder puoi fare rinominazioni batch come questa e questa risposta ti consente di effettuare il check-in.
William Entriken

11

Possiamo usare il comando git mv. Esempio di seguito, se abbiamo rinominato il file abcDEF.js in abcdef.js, possiamo eseguire il seguente comando dal terminale

git mv -f .\abcDEF.js  .\abcdef.js

8

Mac OSX High Sierra 10.13 risolve questo problema. Crea una partizione APFS virtuale per i tuoi progetti git, per impostazione predefinita non ha limiti di dimensioni e non occupa spazio.

  1. In Utility Disco, fai clic sul pulsante + mentre il disco contenitore è selezionato
  2. Seleziona APFS (sensibile al maiuscolo / minuscolo) sotto il formato
  3. Nominalo Sensitive
  4. Profitto
  5. Facoltativo: crea una cartella in Sensitive chiamata giteln -s /Volumes/Sensitive/git /Users/johndoe/git

Il tuo disco sarà dentro /Volumes/Sensitive/

inserisci qui la descrizione dell'immagine

Come posso eseguire il commit delle modifiche al nome del file solo sensibili al maiuscolo / minuscolo in Git?


Adoro questo suggerimento, risolve il problema in modo elegante e indolore senza ricorrere a brutte soluzioni. Grazie!
Phil Gleghorn,

4

Ho affrontato questo problema più volte su MacOS. Git fa distinzione tra maiuscole e minuscole, ma Mac conserva solo le maiuscole.

Qualcuno impegna un file: Foobar.javae dopo qualche giorno decide di rinominarlo FooBar.java. Quando si estrae l'ultimo codice con cui fallisceThe following untracked working tree files would be overwritten by checkout...

L'unico modo affidabile che ho visto per risolvere questo problema è:

  1. git rm Foobar.java
  2. Commettilo con un messaggio da non perdere git commit -m 'TEMP COMMIT!!'
  3. Tirare
  4. Questo farà apparire un conflitto costringendoti a unire il conflitto - perché la tua modifica lo ha eliminato, ma l'altra modifica rinominata (da qui il problema)
    1. Accetta la modifica che è la "cancellazione"
    2. git rebase --continue
  5. Ora rilascia la soluzione alternativa git rebase -i HEAD~2e dropilTEMP COMMIT!!
  6. Conferma che il file è ora chiamato FooBar.java

3

Quando hai fatto un sacco di ridenominazione dei file e alcuni di essi sono solo un cambio di case, è difficile ricordare quale sia quale. "spostare git" manualmente il file può essere abbastanza efficace. Quindi cosa farei durante le mie attività di modifica del nome file è:

  1. rimuovere tutti i file e git non git in una cartella / repository differente.
  2. commit della cartella git vuota corrente (questo mostrerà come tutti i file eliminati.)
  3. aggiungere nuovamente tutti i file nella cartella / repository git originale.
  4. commit della cartella git non vuota corrente.

Ciò risolverà tutti i problemi del caso senza cercare di capire quali file o cartelle sono stati rinominati.


Perché non git commmit --amendal paragrafo 4? Altrimenti, ci sarà un ulteriore impegno con la rimozione di tutti i file. Oppure puoi usare git rebase -icon squash.
Alex78191,

1

Se non ha funzionato, utilizzare git rm nomefile per eliminare il file dal disco e aggiungerlo nuovamente.


0

Ho preso la risposta di @CBarr e ho scritto uno script Python 3 per farlo con un elenco di file:

#!/usr/bin/env python3
# -*- coding: UTF-8 -*-

import os
import shlex
import subprocess

def run_command(absolute_path, command_name):
    print( "Running", command_name, absolute_path )

    command = shlex.split( command_name )
    command_line_interface = subprocess.Popen( 
          command, stdout=subprocess.PIPE, cwd=absolute_path )

    output = command_line_interface.communicate()[0]
    print( output )

    if command_line_interface.returncode != 0:
        raise RuntimeError( "A process exited with the error '%s'..." % ( 
              command_line_interface.returncode ) )

def main():
    FILENAMES_MAPPING = \
    [
        (r"F:\\SublimeText\\Data", r"README.MD", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\Alignment", r"readme.md", r"README.md"),
        (r"F:\\SublimeText\\Data\\Packages\\AmxxEditor", r"README.MD", r"README.md"),
    ]

    for absolute_path, oldname, newname in FILENAMES_MAPPING:
        run_command( absolute_path, "git mv '%s' '%s1'" % ( oldname, newname ) )
        run_command( absolute_path, "git add '%s1'" % ( newname ) )
        run_command( absolute_path, 
             "git commit -m 'Normalized the \'%s\' with case-sensitive name'" % (
              newname ) )

        run_command( absolute_path, "git mv '%s1' '%s'" % ( newname, newname ) )
        run_command( absolute_path, "git add '%s'" % ( newname ) )
        run_command( absolute_path, "git commit --amend --no-edit" )

if __name__ == "__main__":
    main()
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.