¿Cuál es el propósito de git-mv?

13 minutos de lectura

¿Cual es el proposito de git mv
mauricio scheffer

Por lo que entiendo, Git realmente no necesita rastrear expediente operaciones de renombrar/mover/copiar, entonces, ¿cuál es el propósito real de git mv? La página del manual no es especialmente descriptiva…

¿Está obsoleto? ¿Es un comando interno, no destinado a ser utilizado por usuarios regulares?

git mv oldname newname

es solo una abreviatura de:

mv oldname newname
git add newname
git rm oldname

es decir, actualiza automáticamente el índice para las rutas antiguas y nuevas.

  • También tiene algunos dispositivos de seguridad incorporados.

    – Jakub Narębski

    8 de julio de 2009 a las 0:16

  • Gracias @CharlesBailey – ¿Git entonces considera los archivos newNameFile y oldNameFile como diferentes? En caso afirmativo, ¿qué sucede si queremos fusionarlos? Digamos que ramificamos un proyecto ant en la rama A y creamos la Rama B y luego mavenizamos los proyectos en B. Los nombres de los archivos son los mismos pero se colocan en diferentes rutas a medida que cambia la estructura del proyecto. Digamos que ambas ramas crecieron durante algún tiempo en paralelo. En algún momento, si queremos fusionar los proyectos, ¿cómo sabrá git que es el mismo archivo que acaba de renombrar su ruta? (si “git mv” == “git add + git rm”)

    – Rosa

    27 de diciembre de 2012 a las 0:22

  • @SergeyOrshanskiy Si la detección automática falla para mv oldname newname; git add newname; git rm oldnametambién saldrá mal para git mv oldname newname (ver esta respuesta).

    – Ajedi32

    11 de junio de 2014 a las 21:28

  • Tenga en cuenta que git mv es ligeramente diferente de la mv oldname newname; git add newname; git rm oldnameen el sentido de que si realizó cambios en el archivo antes git mving, esos cambios no se realizarán hasta que usted git add el archivo nuevo

    – Ajedi32

    11/06/2014 a las 21:31

  • git mv está haciendo algo diferente, ya que maneja los cambios en el caso del nombre de archivo (foo.txt a Foo.txt) mientras que esos comandos no se ejecutan individualmente (en OSX)

    – grae.kindel

    02/09/2016 a las 19:37


¿Cual es el proposito de git mv
Adán Nofsinger

Desde el GitFaq oficial:

Git tiene un comando de cambio de nombre git mv, pero eso es solo una conveniencia. El efecto es indistinguible de eliminar el archivo y agregar otro con diferente nombre y el mismo contenido

  • Entonces, ¿pierdes el historial de archivos? Supuse que el cambio de nombre mantendría el historial antiguo de ese directorio…

    –Will Hancock

    12 de abril de 2013 a las 9:52

  • Bueno, sí y no. Lea el enlace oficial de GitFaq anterior sobre cambios de nombre y luego lea el extenso correo electrónico de Linus Torvald sobre por qué no le gusta la noción de una herramienta SCM que rastrea archivos: permalink.gmane.org/gmane.comp.version-control.git/217

    –Adam Nofsinger

    7 mayo 2013 a las 15:05

  • @WillHancock He usado git un poco más ahora y puedo responderle de manera más definitiva: dependiendo de su cliente git y sus opciones, podrá rastrear el archivo más allá del cambio de nombre si el archivo cambió internamente lo suficiente como para considerarlo un rebautizar. Sin embargo, si cambia demasiado el archivo Y le cambia el nombre, git no lo detectará; en cierto sentido, está diciendo “no, también podría considerar que es un archivo completamente diferente”.

    –Adam Nofsinger

    6 de marzo de 2015 a las 22:09

  • @AdamNofsinger, ¿cuánto es exactamente “demasiado”? Si se rastrea un posible cambio de nombre en “tiempo de búsqueda” como ha dicho Torvalds, entonces debe haber una definición clara de un cambio de nombre específico para cada cliente, por ejemplo, el 90% de los caracteres o líneas han cambiado… ¿Es así?

    – osolmaz

    23 de septiembre de 2015 a las 13:46

  • @AdamNofsinger ese enlace está muerto. Aquí hay un espejo: web.archive.org/web/20150209075907/http://…

    –Carl Walsh

    14 de noviembre de 2017 a las 7:33

1646957833 514 ¿Cual es el proposito de git mv
sergey orshansky

Git solo está tratando de adivinar por ti lo que estás tratando de hacer. Está haciendo todo lo posible por preservar la historia intacta. Por supuesto, no es perfecto. Entonces git mv le permite ser explícito con su intención y evitar algunos errores.

Considere este ejemplo. Comenzando con un repositorio vacío,

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
mv a c
mv b a
git status

Resultado:

# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   a
#   deleted:    b
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   c
no changes added to commit (use "git add" and/or "git commit -a")

Detección automática fallida 🙁 ¿O lo hizo?

$ git add *
$ git commit -m "change"
$ git log c

commit 0c5425be1121c20cc45df04734398dfbac689c39
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

y luego

$ git log --follow c

Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:56 2013 -0400

    change

commit 50c2a4604a27be2a1f4b95399d5e0f96c3dbf70a
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:24:45 2013 -0400

    initial commit

Ahora intente en su lugar (recuerde eliminar el .git carpeta al experimentar):

git init
echo "First" >a
echo "Second" >b
git add *
git commit -m "initial commit"
git mv a c
git status

Hasta aquí todo bien:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   renamed:    a -> c


git mv b a
git status

Ahora, nadie es perfecto:

# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   modified:   a
#   deleted:    b
#   new file:   c
#

¿En serio? Pero por supuesto…

git add *
git commit -m "change"
git log c
git log --follow c

…y el resultado es el mismo que el anterior: sólo --follow muestra la historia completa.


Ahora, tenga cuidado con el cambio de nombre, ya que Cualquiera de las opciones aún puede producir efectos extraños.. Ejemplo:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git commit -m "first move"
git mv b a
git commit -m "second move"

git log --follow a

commit 81b80f5690deec1864ebff294f875980216a059d
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:35:58 2013 -0400

    second move

commit f284fba9dc8455295b1abdaae9cc6ee941b66e7f
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:34:54 2013 -0400

    initial b

Compáralo con:

git init
echo "First" >a
git add a
git commit -m "initial a"
echo "Second" >b
git add b
git commit -m "initial b"

git mv a c
git mv b a
git commit -m "both moves at the same time"

git log --follow a

Resultado:

commit 84bf29b01f32ea6b746857e0d8401654c4413ecd
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:37:13 2013 -0400

    both moves at the same time

commit ec0de3c5358758ffda462913f6e6294731400455
Author: Sergey Orshanskiy <*****@gmail.com>
Date:   Sat Oct 12 00:36:52 2013 -0400

    initial a

Ups… Ahora la historia se remonta a inicial una en lugar de b inicial, Cuál está mal. Entonces, cuando hicimos dos movimientos a la vez, Git se confundió y no rastreó los cambios correctamente. Por cierto, en mis experimentos sucedió lo mismo cuando eliminé/creé archivos en lugar de usar git mv. Proceda con cuidado; has sido advertido…

  • +1 por la explicación detallada. Estuve buscando problemas que podrían ocurrir en el historial de registro si los archivos se mueven en git, su respuesta fue realmente interesante. ¡Gracias! Por cierto, ¿conoces algún otro peligro que debamos evitar al mover archivos en git? (o cualquier referencia que pueda señalar … no tuve mucha suerte al buscarlo en Google)

    – pabrantes

    21 de marzo de 2014 a las 16:24


  • Bueno, mis ejemplos son pesimistas. Cuando los archivos están vacíos, es mucho más difícil interpretar correctamente los cambios. Me imagino que si solo te comprometes después de cada conjunto de cambios de nombre, deberías estar bien.

    – Serguéi Orshanskiy

    23 de marzo de 2014 a las 1:43

1646957834 478 ¿Cual es el proposito de git mv
coronel pánico

Como dice @Charles, git mv es una abreviatura.

La verdadera pregunta aquí es “Otros sistemas de control de versiones (por ejemplo, Subversion y Perforce) tratan los cambios de nombre de archivos de manera especial. ¿Por qué Git no lo hace?”

Linus explica en http://permalink.gmane.org/gmane.comp.version-control.git/217 con tacto característico:

Por favor, detén esta basura de “rastrear archivos”. Pistas de Git exactamente lo que importa, a saber, “colecciones de archivos”. Nada más es relevante, e incluso
pensando que sea relevante solo limita tu visión del mundo. Observe cómo la noción de “anotar” de CVS siempre inevitablemente termina limitando cómo la gente lo usa. Creo que es una mierda totalmente inútil, y describí algo que creo que es un millón de veces más útil, y todo se vino abajo.
exactamente porque no estoy limitando mi pensamiento al modelo equivocado del mundo.

Hay un caso de nicho donde git mv sigue siendo muy útil: cuando desea cambiar las mayúsculas y minúsculas de un nombre de archivo en un sistema de archivos que no distingue entre mayúsculas y minúsculas. Tanto APFS (mac) como NTFS (windows) no distinguen entre mayúsculas y minúsculas de forma predeterminada (pero conservan mayúsculas y minúsculas).

greg.kindel menciona esto en un comentario sobre la respuesta de CB Bailey.

Suponga que está trabajando en una Mac y tiene un archivo Mytest.txt administrado por git. Quiere cambiar el nombre del archivo a MyTest.txt.

Tu podrías intentar:

$ mv Mytest.txt MyTest.txt
overwrite MyTest.txt? (y/n [n]) y
$ git status
On branch master
Your branch is up to date with 'origin/master'.

nothing to commit, working tree clean

Oh querido. Git no reconoce que haya habido ningún cambio en el archivo.

pudo solucione esto cambiando el nombre del archivo por completo y luego renombrándolo de nuevo:

$ mv Mytest.txt temp.txt
$ git rm Mytest.txt
rm 'Mytest.txt'
$ mv temp.txt MyTest.txt
$ git add MyTest.txt 
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt

¡Viva!

O podría ahorrarse todas esas molestias usando git mv:

$ git mv Mytest.txt MyTest.txt
$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    renamed:    Mytest.txt -> MyTest.txt

1646957835 206 ¿Cual es el proposito de git mv
dhardy

Hay otro uso que tengo para git mv no mencionado anteriormente.

Desde que descubrí git add -p (modo parche de git add; ver http://git-scm.com/docs/git-add), me gusta usarlo para revisar los cambios a medida que los agrego al índice. Por lo tanto, mi flujo de trabajo se convierte en (1) trabajar en el código, (2) revisar y agregar al índice, (3) confirmar.

Cómo git mv encajar? Si mueve un archivo directamente y luego usa git rm y git add, todos los cambios se agregan al índice, y usar git diff para ver los cambios es menos fácil (antes de confirmar). Utilizando git mvsin embargo, agrega la nueva ruta al índice pero no los cambios realizados en el archivo, lo que permite git diff y git add -p para trabajar como de costumbre.

git mv mueve el archivo, actualizando el índice para registrar la ruta del archivo reemplazado, así como también actualizando los submódulos de git afectados. A diferencia de un movimiento manual, también detecta cambios de nombre de mayúsculas y minúsculas que, de otro modo, git no detectaría como un cambio.

Es similar (aunque no idéntico) en comportamiento a mover el archivo externamente a git, eliminando la ruta anterior del índice usando git rmy agregando el nuevo al índice usando git add.

Respuesta Motivación

Esta pregunta tiene muchas respuestas parciales geniales. Esta respuesta es un intento de combinarlos en una sola respuesta cohesiva. Además, una cosa que no se menciona en ninguna de las otras respuestas es el hecho de que el página man en realidad responde principalmente a la pregunta, pero quizás sea menos obvio de lo que podría ser.

Explicación detallada

En la página del manual se mencionan tres efectos diferentes:

  1. El archivo, directorio o enlace simbólico se mueve en el sistema de archivos:

    git-mv: mueve o cambia el nombre de un archivo, un directorio o un enlace simbólico

  2. Se actualiza el índice, agregando la nueva ruta y eliminando la anterior:

    El índice se actualiza después de completarse con éxito, pero aún se debe confirmar el cambio.

  3. Los submódulos movidos se actualizan para funcionar en la nueva ubicación:

    Mover un submódulo usando un gitfile (lo que significa que fueron clonados con una versión de Git 1.7.8 o posterior) actualizará la configuración de gitfile y core.worktree para que el submódulo funcione en la nueva ubicación. También intentará actualizar la configuración submodule..path en el módulos git(5) archivo y etapa ese archivo (a menos que se use -n).

Como se menciona en esta respuesta, git mv es muy similar a mover el archivo, agregar la nueva ruta al índice y eliminar la ruta anterior del índice:

mv oldname newname
git add newname
git rm oldname

Sin embargo, como señala esta respuesta, git mv no es estrictamente idéntico a este en el comportamiento. Mover el archivo a través de git mv agrega la nueva ruta al índice, pero no cualquier contenido modificado en el archivo. El uso de los tres comandos individuales, por otro lado, agrega el archivo completo al índice, incluido cualquier contenido modificado. Esto podría ser relevante cuando se usa un flujo de trabajo que parchea el índice, en lugar de agregar todos los cambios en el archivo.

Además, como se menciona en esta respuesta y este comentario, git mv tiene el beneficio adicional de manejar cambios de nombre solo de mayúsculas y minúsculas en sistemas de archivos que son no distingue entre mayúsculas y minúsculas pero conservación de casos, como suele ser el caso en los sistemas de archivos actuales de macOS y Windows. Por ejemplo, en dichos sistemas, git no detectaría que el nombre del archivo ha cambiado después de mover un archivo a través de mv Mytest.txt MyTest.txtmientras que usando git mv Mytest.txt MyTest.txt actualizaría con éxito su nombre.

  • Cómo git mv en las versiones más nuevas de git permite la reubicación simplificada de los submódulos es una mejora masiva del flujo de trabajo.

    – civilización abierta

    6 de marzo de 2021 a las 5:21

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad