¿Cómo confirmo cambios de nombre de archivo que distinguen entre mayúsculas y minúsculas en Git?

1303

He cambiado el nombre de algunos archivos por de-mayúscula la primera letra, como en Name.jpga name.jpg. Git no reconoce estos cambios y tuve que eliminar los archivos y subirlos nuevamente. ¿Hay alguna manera de que Git distinga entre mayúsculas y minúsculas al verificar los cambios en los nombres de archivo? No he realizado ningún cambio en el archivo en sí.

Gil Shulman
fuente
44
@si esto no es del todo correcto, Git en realidad tiene una configuración que controla si ignora o no las mayúsculas y minúsculas.
66
Ver stackoverflow.com/a/24979063/6309 : desde git 2.0.1, un simple git mvfunciona.
VonC
Consulte esta publicación. Pude comprometerme pero solo usando git commit -m "msg" sin ninguna ruta de archivo como parámetro. Actualizó el índice y verificó el archivo. [Enlace] stackoverflow.com/questions/35790113/…
ARKS

Respuestas:

1518

Puedes usar git mv :

git mv -f OldFileNameCase newfilenamecase
Keith Smiley
fuente
12
esto me da 'el directorio fuente está vacío' mientras no lo está
WiseStrawberry
66
Usando MacOS aquí (FS insensible a mayúsculas y minúsculas) y -f funcionó! Gracias por el consejo
caesarsol
49
En versiones recientes, ya no necesita la -fbandera.
Joshua Pinter el
8
No olvide dar la ruta completa del archivo. Obvio, lo sé, pero me
atrapó
77
Para la parte superior votó comentario: se hace necesario el -finterruptor con la última Git (2.18) de lo contrario podría obtener el fatal: destination existserror.
DeepSpace101
1039

Git tiene un valor de configuración que le dice si sea sensible a mayúsculas o minúsculas: core.ignorecase. Para decirle a Git que distinga entre mayúsculas y minúsculas, simplemente establezca esta configuración en false:

git config core.ignorecase false

Documentación

De la git configdocumentación :

core.ignorecase

Si es cierto, esta opción permite varias soluciones alternativas para permitir que git funcione mejor en sistemas de archivos que no distinguen entre mayúsculas y minúsculas, como FAT. Por ejemplo, si un listado de directorio encuentra makefilecuando git espera Makefile, git asumirá que es realmente el mismo archivo y continuará recordándolo como Makefile.

El valor predeterminado es falso, excepto que git-clone (1) o git-init (1) probarán y establecerán core.ignorecaseverdadero si es apropiado cuando se crea el repositorio.

Sistemas de archivos que no distinguen entre mayúsculas y minúsculas

Los dos sistemas operativos más populares que tienen sistemas de archivos que no distinguen entre mayúsculas y minúsculas que conozco son

  • Ventanas
  • OS X

fuente
99
En una nota al margen, no creo que Mac OS X sea insensible a mayúsculas y minúsculas. En cambio, es el sistema de archivos que determina la distinción entre mayúsculas y minúsculas. Al formatear una partición HFS +, los usuarios pueden elegir si hacerla sensible a mayúsculas o minúsculas. La mayúscula y minúscula es el valor predeterminado.
spaaarky21
225
Parece que vale la pena señalar en esta respuesta que configurar esta opción falseen un sistema de archivos que no distingue entre mayúsculas y minúsculas es una mala idea . Esto no es necesariamente obvio. Por ejemplo, acabo de probar esto en mi Mac, pensando que solucionaría mis problemas, luego cambié el nombre de un archivo de productPageCtrl.jsa ProductPageCtrl.js. git statusvi un nuevo archivo llamado ProductPageCtrl.jspero no pensé que se productPageCtrl.jshubiera eliminado. Cuando agregué los nuevos archivos, me comprometí y empujé a GitHub, el repositorio de GitHub ahora contenía ambos archivos a pesar de que mi (supuestamente actualizado) repositorio local tenía solo uno.
Mark Amery
55
@ MarkAmery Eso se parece mucho a un error en su cliente Git. ¿Presentaste un informe?
Domi
24
@Domi, esto no es un error, este es el comportamiento esperado. De hecho, es una mala idea establecer esto en falso en un sistema de archivos insensible porque esto es lo que sucede. La razón por la cual git no vio que se eliminó el archivo en minúsculas es que el sistema de archivos no lo informa como eliminado, ya que ignora el caso, mientras que git no tiene esta opción configurada como falsa. No es que los nombres de archivo no tengan minúsculas o minúsculas en ntfs o gordos, es solo que la búsqueda de nombre de archivo ignora las mayúsculas y minúsculas.
ohcibi
15
@Domi git es lo suficientemente inteligente. Es por eso que no debe establecer esto en falso en un sistema de archivos sin distinción entre mayúsculas y minúsculas. Use git mvpara mover el archivo y ver cómo lo maneja git. Si mueve el archivo sin git, no hay nada que git pueda hacer ya que el sistema de archivos no dice la verdad a git. Este es un problema de ntfs / fat / hfs y similares y no de git / linux.
ohcibi
158

Usando SourceTree pude hacer todo esto desde la interfaz de usuario

  1. Renombrar FILE.ext awhatever.ext
  2. Etapa de ese archivo
  3. Ahora cambie el nombre whatever.ext afile.ext
  4. Etapa ese archivo de nuevo

Es un poco tedioso, pero si solo necesita hacerlo en algunos archivos, es bastante rápido

CBarr
fuente
55
Lo mismo con git bash
Alex78191
3
"Organizar ese archivo" es la parte importante: ninguna de las otras respuestas anteriores me funcionó. En realidad, funcionó con el viejo símbolo del sistema de Windows.
Vlad Sabev
1
No me di cuenta de que esto funcionaba en el área de preparación. Pero en mi caso, quería modificar los nombres de las carpetas y algunos archivos dentro de esas carpetas. Así que primero cambié el nombre de todas las carpetas a nombres temporales. Confirmó los nuevos nombres (todos los archivos dentro) y los archivos "eliminados". Git los marcó a todos como "renombrados". Luego cambió el nombre de todas esas carpetas a sus nuevas versiones de casos y las confirmó nuevamente. Finalmente, fusionó esos 2 commits. Pero en base a lo que escribió, podría haber hecho todo a través del área de clasificación directamente, sin crear 2 commits + merge.
ThermoX
3
Funciona también con gitkraken en el nombre de la carpeta.
Philippe Matray
Escribí un script de Python 3 para hacer este trabajo tedioso: stackoverflow.com/a/58159822/4934640
usuario el
126

Esto es lo que hice en OS X:

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

Dos pasos porque de lo contrario recibí un error de "archivo existe". Quizás se pueda hacer en un solo paso agregando --cachedo algo así.

Sijmen Mulder
fuente
21
como sugiere la respuesta principal, -f(force) es la bandera que estás buscando
rperryng
55
@rperryng: no, el -findicador no ayuda en caso de que el FS subyacente no distinga entre mayúsculas y minúsculas. Sin embargo, la solución de dos pasos funcionó para mí
HEKTO
Usando un FS insensible a mayúsculas y minúsculas (en Mac) y -ffuncionó! Gracias por el consejo
caesarsol
Esto también funcionó con una carpeta en Windows sin la -fbandera.
nich
git -c "core.ignorecase=false" add .considerará los archivos cuyo caso ha sido cambiado para commit.
nietonfir
67

A veces es útil cambiar temporalmente la sensibilidad a mayúsculas y minúsculas de Git:

Método n. ° 1: cambiar la distinción entre mayúsculas y minúsculas para un solo comando:

git -c core.ignorecase=true checkout mybranchpara desactivar mayúsculas y minúsculas para un solo checkoutcomando. O más en general: . (Gracias a VonC por sugerir esto en los comentarios).git -c core.ignorecase= <<true or false>> <<command>>

Método n. ° 2: cambie la distinción entre mayúsculas y minúsculas para varios comandos:

Para cambiar la configuración por más tiempo (por ejemplo, si se deben ejecutar varios comandos antes de volver a cambiarla):

  1. git config core.ignorecase(esto devuelve la configuración actual, por ejemplo false).
  2. git config core.ignorecase <<true or false>> - establecer la nueva configuración deseada.
  3. ... Ejecute varios otros comandos ...
  4. git config core.ignorecase <<false or true>> - restablecer el valor de configuración a su configuración anterior.
Steve Chambers
fuente
1
¿Por qué no directamente git -c core.ignorecase=<true or false> checkout <<branch>>? Nada para restablecer después.
VonC
2
Tuve una experiencia extraña del trabajo core.ignorecase propuesto al cambiar de minúsculas a mayúsculas, pero no de mayúsculas a minúsculas. Parece que la única solución confiable es dejar de usar un sistema operativo que no reconoce el caso del nombre de archivo.
aspiringGuru
¿Hay alguna razón por la que debería ser un cambio temporal? ¿Causaría algún problema si solo dejo la configuración cambiada a mayúsculas y minúsculas?
cytsunny
Esto puede depender de algunos factores, en particular si el sistema de archivos de destino distingue entre mayúsculas y minúsculas; consulte en.wikipedia.org/wiki/Case_sensitivity#In_filesystems . El cambio temporal puede ser necesario si el sistema de archivos de implementación tiene mayúsculas y minúsculas diferentes al sistema de archivos utilizado para el desarrollo. También en mi caso, trabajo en un equipo donde se espera que todos tengan la misma configuración de Git (es decir, distingue entre mayúsculas y minúsculas), por lo que si lo apago, debe ser temporal.
Steve Chambers
44

En OSX, para evitar este problema y evitar otros problemas con el desarrollo en un sistema de archivos que no distingue entre mayúsculas y minúsculas, puede usar la Utilidad de Discos para crear una imagen de disco / unidad virtual sensible a mayúsculas y minúsculas .

Ejecute la utilidad de disco, cree una nueva imagen de disco y use la siguiente configuración (o cambie como desee, pero manténgala entre mayúsculas y minúsculas):

Captura de pantalla de Mac Disk Utility

Asegúrate de decirle a git que ahora está en un FS sensible a mayúsculas y minúsculas:

git config core.ignorecase false
usuario1821510
fuente
15
No, nuclear está ejecutando una unidad de arranque totalmente sensible a mayúsculas y minúsculas en OSX. Tendrá que vivir sin aplicaciones mal escritas (ejem, Adobe) o ejecutarlas en su propia máquina virtual, pero vale la pena si codifica principalmente para sistemas * nix.
Mike Marcacci
1
Esta es la única opción que funciona correctamente. He intentado el resto y terminas en apuros de una forma u otra. Resuelva el problema correctamente haciendo esto.
John Hunt
2
Tenga en cuenta que Disk Utility tiene un error OS X 10.11: no creará imágenes sensibles a mayúsculas y minúsculas. Debe usar la herramienta de línea de comandos hdiutil. apple.stackexchange.com/questions/217915/…
dellsala
77
Con APFS en High Sierra, esto es aún más fácil. Haga clic en el icono de una unidad con un signo más y agregue un volumen sensible a mayúsculas y minúsculas sin límites de tamaño. Simplemente comparte espacio con el volumen principal y se monta en / Volumes / volume-name.
Michael Fox
21

Intenté las siguientes soluciones de las otras respuestas y no funcionaron:

Si su repositorio está alojado de forma remota (GitHub, GitLab, BitBucket), puede cambiar el nombre del archivo en origen (GitHub.com) y forzar el cambio de nombre de arriba a abajo.

Las instrucciones a continuación pertenecen a GitHub, sin embargo, la idea general detrás de ellas debería aplicarse a cualquier plataforma remota de alojamiento de repositorios. Tenga en cuenta que el tipo de archivo que está intentando cambiar el nombre es importante, es decir, si es un tipo de archivo que GitHub considera editable (código, texto, etc.) o no editable (imagen, binario, etc.) dentro del navegador.

  1. Visita GitHub.com
  2. Navegue a su repositorio en GitHub.com y seleccione la sucursal en la que está trabajando
  3. Con la herramienta de navegación de archivos del sitio, navegue hasta el archivo que desea cambiar de nombre
  4. ¿GitHub le permite editar el archivo dentro del navegador?
    • a.) Editable
      1. Haga clic en el icono "Editar este archivo" (parece un lápiz)
      2. Cambiar el nombre del archivo en la entrada de texto del nombre de archivo
    • b.) No editable
      1. Abra el botón "Descargar" en una nueva pestaña y guarde el archivo en su computadora
      2. Cambiar el nombre del archivo descargado
      3. En la pestaña anterior en GitHub.com, haga clic en el icono "Eliminar este archivo" (parece una papelera)
      4. Asegúrese de que branchnameesté seleccionado el botón de opción "Confirmar directamente a la rama" y haga clic en el botón "Confirmar cambios"
      5. Dentro del mismo directorio en GitHub.com, haga clic en el botón "Subir archivos"
      6. Cargue el archivo renombrado de su computadora
  5. Asegúrese de que branchnameesté seleccionado el botón de opción "Confirmar directamente a la rama" y haga clic en el botón "Confirmar cambios"
  6. Localmente, pagar / buscar / extraer la rama
  7. Hecho
gmeben
fuente
Cambié el nombre directamente en BitBucket y funcionó. Gracias.
rsc
Bueno saber. Teóricamente, esta técnica debería funcionar en cualquier plataforma de alojamiento de repositorio, pero me interesaría saber si hay alguna con la que no funcionaría.
Gmeben
No funciona para archivos que no se pueden editar en el navegador, como imágenes o PDF; no hay opción de edición, obviamente.
Abhijit Sarkar
@AbhijitSarkar Buen punto. Actualicé mi respuesta para esos casos. Probé y verifiqué que estas instrucciones funcionan.
gmeben
¿Alguien logra cambiar el nombre de un directorio de esta manera?
Solvitieg
21

Similar a la respuesta de @ Sijmen, esto es lo que funcionó para mí en OSX al cambiar el nombre de un directorio (inspirado en esta respuesta de otra publicación):

git mv CSS CSS2
git mv CSS2 css

Simplemente hacerlo git mv CSS cssdio el error de argumento no válido: fatal: renaming '/static/CSS' failed: Invalid argumentquizás porque el sistema de archivos de OSX no distingue entre mayúsculas y minúsculas

ps BTW si está utilizando Django, collectstatic tampoco reconocería la diferencia de mayúsculas y minúsculas y tendría que hacer lo anterior, manualmente, también en el directorio raíz estático

Anupam
fuente
19

1) cambiar el nombre del archivo Name.jpganame1.jpg

2) confirmar el archivo eliminado Name.jpg

3) renombrar archivo name1.jpganame.jpg

4) ammend agregó el archivo name.jpgal commit anterior

git add
git commit --amend
razon
fuente
2
Recibo esto fatal: bad source, source=name1.jpg, destination=name.jpgen el paso 3. ¿Tiene alguna sugerencia? Thx
Anthony Kong
1
No puedes hacer un commit, solo git add.
Alex78191
Parece muy hacky, ¿no? O parches de mono.
jeromej
18

Usé los siguientes pasos:

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

Para mi es una solución simple

Andrewvergel
fuente
Esta es la solución Y a diferencia de las otras respuestas, funciona bien cuando está realizando cambios de nombre por lotes. En glamourphilly.org necesitábamos cambiar cada .Jpg a .jpg. En Finder puedes hacer cambios de nombre de lote como ese y esta respuesta te permite verificarlo.
William Entriken
11

Podemos usar el comando git mv. Ejemplo a continuación, si cambiamos el nombre del archivo abcDEF.js a abcdef.js, entonces podemos ejecutar el siguiente comando desde la terminal

git mv -f .\abcDEF.js  .\abcdef.js
Sandeep Shukla
fuente
8

Mac OSX High Sierra 10.13 soluciona esto de alguna manera. Simplemente haga una partición APFS virtual para sus proyectos git, por defecto no tiene límite de tamaño y no ocupa espacio.

  1. En la Utilidad de Discos, haga clic en el botón + mientras se selecciona el disco Contenedor
  2. Seleccione APFS (mayúsculas y minúsculas) en formato
  3. Nombralo Sensitive
  4. Lucro
  5. Opcional: haga una carpeta en Sensitive llamada gityln -s /Volumes/Sensitive/git /Users/johndoe/git

Tu unidad estará en /Volumes/Sensitive/

ingrese la descripción de la imagen aquí

¿Cómo confirmo cambios de nombre de archivo que distinguen entre mayúsculas y minúsculas en Git?

Ray Foss
fuente
Me encanta esta sugerencia, resuelve el problema de manera elegante e indolora sin recurrir a soluciones desagradables. ¡Gracias!
Phil Gleghorn
4

Me he enfrentado a este problema varias veces en MacOS. Git distingue entre mayúsculas y minúsculas, pero Mac solo conserva las mayúsculas y minúsculas.

Alguien comete un archivo: Foobar.javay después de unos días decide cambiarle el nombre FooBar.java. Cuando extrae el último código, falla conThe following untracked working tree files would be overwritten by checkout...

La única forma confiable que he visto que soluciona esto es:

  1. git rm Foobar.java
  2. Comprometelo con un mensaje que no te puedes perder git commit -m 'TEMP COMMIT!!'
  3. Halar
  4. Esto abrirá un conflicto que lo obligará a fusionar el conflicto, porque su cambio lo eliminó, pero el otro cambio cambió su nombre (de ahí el problema)
    1. Acepte su cambio, que es la "eliminación"
    2. git rebase --continue
  5. Ahora suelte su solución git rebase -i HEAD~2y dropelTEMP COMMIT!!
  6. Confirme que el archivo ahora se llama FooBar.java
Ashwin Jayaprakash
fuente
3

Cuando ha cambiado mucho el nombre de los archivos y algunos de ellos son solo un cambio de carcasa, es difícil recordar cuál es cuál. manualmente "git moving" el archivo puede ser bastante trabajo. Entonces, lo que haría durante mis tareas de cambio de nombre de archivo son:

  1. eliminar todos los archivos y carpetas que no sean git a una carpeta / repositorio diferente.
  2. confirmar la carpeta git vacía actual (esto se mostrará como todos los archivos eliminados)
  3. agregue todos los archivos nuevamente a la carpeta / repositorio original de git.
  4. confirmar la carpeta git actual no vacía.

Esto solucionará todos los problemas del caso sin intentar averiguar qué archivos o carpetas ha cambiado de nombre.

Ricardo Virtudazo Jr
fuente
¿Por qué no git commmit --amenden el párrafo 4? De lo contrario, habrá una confirmación adicional con la eliminación de todos los archivos. O puedes usar git rebase -icon calabaza.
Alex78191
1

Si nada funcionó, use git rm filename para eliminar el archivo del disco y agregarlo nuevamente.

Gopal Pandey
fuente
0

Tomé @CBarr respuesta y escribió un script en Python 3 de hacerlo con una lista de archivos:

#!/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()
usuario
fuente