¿Es posible mover / renombrar archivos en Git y mantener su historial?

667

Me gustaría cambiar el nombre / mover un subárbol de proyecto en Git moviéndolo de

/project/xyz

a

/components/xyz

Si uso un plano git mv project components, xyz projectse pierde todo el historial de confirmaciones . ¿Hay alguna manera de mover esto de tal manera que se mantenga la historia?

sgargan
fuente
2
Solo quiero señalar que acabo de probar mover archivos a través del sistema de archivos, y después de confirmar (a través de intellij) puedo ver todo el historial (incluido el historial cuando estaba en una ubicación diferente) al ver el historial (nuevamente en intellij). Supongo que intellij no está haciendo nada particularmente especial para hacer eso, por lo que es bueno saber que al menos se puede rastrear la historia.
BT
Para las reglas seguidas por Git al detectar un cambio de nombre de directorio, vea mi respuesta a continuación
VonC
Escribí una respuesta aquí. Espero que funcione. stackoverflow.com/questions/10828267/…
Mahmut EFE el

Respuestas:

651

Git detecta los cambios de nombre en lugar de persistir en la operación con la confirmación, por lo que si usa git mvo mvno importa.

El logcomando toma un --followargumento que continúa el historial antes de una operación de cambio de nombre, es decir, busca contenido similar utilizando la heurística:

http://git-scm.com/docs/git-log

Para buscar el historial completo, use el siguiente comando:

git log --follow ./path/to/file
Troels Thomsen
fuente
63
Sospecho que esto es una consideración de rendimiento. Si no necesita el historial completo, seguramente llevará más tiempo escanear el contenido. La forma más fácil es configurar un alias git config alias.logf "log --follow"y simplemente escribir git logf ./path/to/file.
Troels Thomsen
13
@TroelsThomsen este e-mail por Linus Torvalds, vinculado desde esta respuesta , indica que se trata de una opción de diseño intencional de Git, ya que es supuestamente mucho más potente que el seguimiento de los cambios de nombre, etc.
Emil Lundberg
127
Esta respuesta es un poco engañosa. Git "detecta cambios de nombre", pero muy tarde en el juego; la pregunta es cómo garantizar que Git rastrea los cambios de nombre, y alguien que lea esto puede inferir fácilmente que Git los detecta automáticamente y lo toma nota. No es asi. Git no tiene un manejo real de los cambios de nombre, y en su lugar hay herramientas de combinación / registro que intentan descubrir qué sucedió, y rara vez lo hacen bien. Linus tiene un argumento equivocado pero vehemente de por qué git nunca debería hacerlo de la manera correcta y rastrear los cambios de nombre explícitamente. Entonces, estamos atrapados aquí.
Chris Moschini
29
Importante: si cambia el nombre de un directorio, por ejemplo, durante el cambio de nombre de un paquete Java, asegúrese de ejecutar dos confirmaciones, primero para el comando 'git mv {old} {new}', segundo para las actualizaciones de todos los archivos Java que hacen referencia al Se cambió el directorio del paquete. De lo contrario, git no puede rastrear los archivos individuales incluso con el parámetro --follow.
nn4l
44
Aunque Linus probablemente comete muy pocos errores, este parece ser uno. Simplemente cambiar el nombre de una carpeta hace que se cargue un delta masivo en GitHub. Lo que me hace tener cuidado al cambiar el nombre de mis carpetas ... pero esa es una camisa de fuerza bastante grande para un programador. Ocasionalmente, DEBO redefinir el significado de algo o cambiar la forma en que se clasifican las cosas. Linus: "En otras palabras, tengo razón. Siempre tengo razón, pero a veces tengo más razón que otras. Y maldita sea, cuando digo 'los archivos no importan', realmente tengo razón ( tm) ". ... Tengo mis dudas sobre eso.
Gabe Halsmer
94

Es posible cambiar el nombre de un archivo y mantener el historial intacto, aunque hace que se cambie el nombre del archivo a lo largo de todo el historial del repositorio. Esto es probablemente solo para los amantes obsesivos de git-log, y tiene algunas implicaciones serias, que incluyen:

  • Podría estar reescribiendo un historial compartido, que es lo más importante que NO HAGA mientras usa Git. Si alguien más ha clonado el repositorio, lo romperá haciendo esto. Tendrán que volver a clonar para evitar dolores de cabeza. Esto podría estar bien si el cambio de nombre es lo suficientemente importante, pero tendrá que considerar esto con cuidado, ¡podría terminar molestando a toda una comunidad de código abierto!
  • Si ha hecho referencia al archivo usando su nombre anterior anteriormente en el historial del repositorio, está rompiendo efectivamente las versiones anteriores. Para remediar esto, tendrás que hacer un poco más de salto de aro. No es imposible, simplemente tedioso y posiblemente no valga la pena.

Ahora, como todavía estás conmigo, probablemente seas un desarrollador en solitario que renombra un archivo completamente aislado. ¡Muevamos un archivo usando filter-tree!

Suponga que va a mover un archivo olda una carpeta diry darle el nombrenew

Esto podría hacerse git mv old dir/new && git add -u dir/new, pero eso rompe la historia.

En lugar:

git filter-branch --tree-filter 'if [ -f old ]; then mkdir dir && mv old dir/new; fi' HEAD

será rehacer cada commit en el ramo, la ejecución del comando en las garrapatas para cada iteración. Muchas cosas pueden salir mal cuando haces esto. Normalmente pruebo para ver si el archivo está presente (de lo contrario, todavía no está allí para moverse) y luego realizo los pasos necesarios para calzar el árbol a mi gusto. Aquí puede atravesar archivos para alterar las referencias al archivo, etc. ¡Déjate fuera! :)

Cuando se completa, el archivo se mueve y el registro está intacto. Te sientes como un pirata ninja.

También; El directorio mkdir solo es necesario si mueve el archivo a una nueva carpeta, por supuesto. El if evitará la creación de esta carpeta antes en el historial que el archivo existente.

Øystein Steimler
fuente
57
Como un obsesivo git-log-lover, no iría por esto. Los archivos no fueron nombrados así en esos momentos, por lo tanto, la historia refleja una situación que nunca existió. ¡Quién sabe qué pruebas podrían romper en el pasado! El riesgo de romper versiones anteriores es en casi todos los casos, no vale la pena.
Vincent
77
@ Vincent Tienes toda la razón, y traté de ser lo más claro posible sobre la improbabilidad de que esta solución sea adecuada. También creo que estamos hablando de dos significados de la palabra "historia" en este caso, aprecio ambos.
Øystein Steimler
66
Encuentro que hay situaciones en las que uno podría necesitar esto. Digamos que desarrollé algo en mi rama personal, que ahora quiero fusionar aguas arriba. Pero descubro que el nombre de archivo no es apropiado, así que lo cambio para toda mi rama personal. De esa manera puedo mantener un historial limpio y apropiado y tener el nombre correcto desde el principio.
user2291758
3
@ user2291758 ese es mi caso de uso. ¡Estos comandos git más potentes son peligrosos, pero eso no significa que no tengan casos de uso muy convincentes si sabes lo que estás haciendo!
philix
1
si es posible, usar el --index-filtercambio de nombre será mucho más rápido ya que el árbol no tendrá que desprotegerse y volver a ingresar en cada confirmación. --index-filteractúa directamente en cada índice de confirmación.
Thomas Guyot-Sionnest
87

No.

La respuesta corta es NO . No es posible cambiar el nombre de un archivo en Git y recordar el historial. Y es un dolor.

Se rumorea que git log --follow--find-copies-harderfuncionará, pero no funciona para mí, incluso si no hay cambios en el contenido del archivo, y los movimientos se han realizado con git mv.

(Al principio utilicé Eclipse para cambiar el nombre y los paquetes de actualización en una sola operación, que pueden haber confundido Git. Pero eso es una cosa muy común de hacer. --followParece que no funciona si sólo mvse lleva a cabo y luego una commity mvno está demasiado lejos.)

Linus dice que se supone que debe comprender todo el contenido de un proyecto de software de manera integral, sin necesidad de rastrear archivos individuales. Bueno, tristemente, mi pequeño cerebro no puede hacer eso.

Es realmente molesto que tantas personas hayan repetido sin pensar la afirmación de que Git rastrea automáticamente los movimientos. Han perdido mi tiempo. Git no hace tal cosa. Por diseño (!) Git no rastrea los movimientos en absoluto.

Mi solución es cambiar el nombre de los archivos a sus ubicaciones originales. Cambie el software para que se ajuste al control de fuente. Con Git parece que solo necesitas "corregirlo" la primera vez.

Desafortunadamente, eso rompe Eclipse, que parece usar --follow. git log --followa veces no muestra el historial completo de archivos con historiales de cambio de nombre complicados, aunque lo git loghace. (No se por que.)

(Hay algunos trucos demasiado inteligentes que se remontan y vuelven a comprometer el trabajo anterior, pero son bastante atemorizantes. Ver GitHub-Gist: emiller / git-mv-with-history ).

Manejable
fuente
2
Creo que tienes razón. Solo estaba tratando de usar php-cs-fixer para reformatear la fuente de mi proyecto Laravel 5, pero insiste en cambiar la mayúscula de las cláusulas de espacio de nombres para que coincida con el valor en minúscula de la carpeta de la aplicación. Pero los espacios de nombres (o las autocargas del compositor) solo funcionan con CamelCase. Necesito cambiar la capitalización de la carpeta a la aplicación, pero esto hace que mis cambios se pierdan. Este es el ejemplo más trivial, pero muestra cómo la heurística git no puede seguir ni siquiera los cambios de nombre más simples (--follow y --find-copies-hardder deberían ser la regla, no la excepción).
Zack Morris
66
git -1, subversión +1
Cosmin
¿Sigue siendo cierto? Esa es una razón más para que me quede con tfs por ahora, mantener el historial de un archivo movido / renombrado es imprescindible en un proyecto grande.
Cesar
@Cesar Si por "recordar la historia", quiere decir "seguir los cambios de nombre al ver el registro" (que es lo único que debería importarnos), ¡esto nunca fue cierto! Git no "registra" los cambios de nombre, pero las herramientas pueden detectarlos fácilmente y presentarnos cambios de nombre y movimientos. Si "no funciona" para alguien, él / ella debe cambiar las herramientas que está usando. Hay muchas GUI Git maravillosas que tienen esta capacidad.
Mohammad Dehghan
La respuesta corta es sí. La versión actual de Git también admite "git log --follow". y estoy de acuerdo con @MohammadDehghan
insung
43
git log --follow [file]

le mostrará la historia a través de cambios de nombre.

Erik Hesselink
fuente
29
Parece que esto requiere que confirmes solo el cambio de nombre antes de comenzar a modificar el archivo. Si mueve el archivo (en el shell) y luego lo cambia, todas las apuestas están desactivadas.
yoyo
22
@yoyo: eso es porque git no rastrea los cambios de nombre, los detecta. A git mvbásicamente hace a git rm && git add. Hay opciones como -M90/ --find-renames=90para considerar que un archivo cambie de nombre cuando sea 90% idéntico.
vdboor
22

Hago:

git mv {old} {new}
git add -u {new}
James M. Greene
fuente
3
El -u no parece hacer nada por mí, ¿se supone que debe actualizar el historial?
jeremy
1
Quizás quieres el comportamiento de en su -Alugar? Nuevamente, vea aquí: git-scm.com/docs/git-add
James M. Greene
1
Agrega los archivos, sin embargo, no actualiza el historial, por lo que 'nombre de archivo de registro de git' muestra el historial completo. Solo muestra el historial completo si todavía usa la opción --follow.
Jeremy
3
Hice un refactorizador complicado que movió un directorio de inclusión (usando mv, no git mv) y luego cambié muchas rutas #include dentro de los archivos renombrados. git no pudo encontrar suficiente similitud para rastrear la historia. Pero git add -u era justo lo que necesitaba. El estado de git ahora indica "renombrado" donde antes mostraba "eliminado" y "nuevo archivo".
AndyJost
1
Hay muchas preguntas sobre SO que abordan el propósito de git add -u. Los documentos de Git tienden a ser inútiles, y son el último lugar donde me gustaría mirar. Aquí hay una publicación que se muestra git add -uen acción: stackoverflow.com/a/2117202 .
nobar
17

Me gustaría cambiar el nombre / mover un subárbol de proyecto en Git moviéndolo de

/project/xyz

a

/ componentes / xyz

Si uso un plano git mv project components, xyzse pierde todo el historial de confirmación del proyecto.

No (8 años después, Git 2.19, Q3 2018), porque Git detectará el cambio de nombre del directorio , y esto ahora está mejor documentado.

Consulte commit b00bf1c , commit 1634688 , commit 0661e49 , commit 4d34dff , commit 983f464 , commit c840e1a , commit 9929430 (27 de junio de 2018) y commit d4e8062 , commit 5dacd4a (25 de junio de 2018) por Elijah Newren ( newren) .
(Fusionada por Junio ​​C Hamano - gitster- en commit 0ce5a69 , 24 jul 2018)

Eso ahora se explica en Documentation/technical/directory-rename-detection.txt:

Ejemplo:

Cuando todos x/a, x/by se x/chan movido a z/a, z/by z/c, es probable que los x/dagregados mientras tanto también deseen moverse al z/dtomar la pista de que todo el directorio ' x' se movió a ' z'.

Pero son muchos otros casos, como:

un lado del historial cambia el nombre x -> zy el otro cambia el nombre de algún archivo x/e, lo que provoca la necesidad de que la fusión haga un cambio de nombre transitivo.

Para simplificar la detección de cambio de nombre de directorio, Git aplica esas reglas:

un par de reglas básicas limitan cuando se aplica la detección de cambio de nombre del directorio:

  1. Si todavía existe un directorio dado en ambos lados de una fusión, no consideramos que haya cambiado de nombre.
  2. Si un subconjunto de archivos a renombrar tiene un archivo o directorio en el camino (o estaría en el camino el uno del otro), "apague" el cambio de nombre del directorio para esas subrutas específicas e informe el conflicto al usuario .
  3. Si el otro lado del historial cambió el nombre de un directorio a una ruta que su lado del historial renombró, entonces ignore ese cambio de nombre particular del otro lado del historial para cualquier cambio de nombre de directorio implícito (pero advierta al usuario).

Puede ver muchas pruebas en t/t6043-merge-rename-directories.sh, que también señalan que:

  • a) Si los cambios de nombre dividen un directorio en dos o más, el directorio con más cambios de nombre, "gana".
  • b) Evite la detección de cambio de nombre de directorio para una ruta, si esa ruta es la fuente de un cambio de nombre a ambos lados de una fusión.
  • c) Solo aplique el cambio de nombre de directorio implícito a los directorios si el otro lado de la historia es el que realiza el cambio de nombre.
VonC
fuente
15

Objetivo

  • Uso (inspirado en Smar , tomado de Exherbo )git am
  • Agregar historial de confirmación de archivos copiados / movidos
  • De un directorio a otro
  • O de un repositorio a otro

Limitación

  • Las etiquetas y ramas no se guardan
  • El historial se corta al cambiar el nombre del archivo de ruta (cambio de nombre del directorio)

Resumen

  1. Extraiga el historial en formato de correo electrónico utilizando
    git log --pretty=email -p --reverse --full-index --binary
  2. Reorganice el árbol de archivos y actualice los nombres de archivo
  3. Agregar nueva historia usando
    cat extracted-history | git am --committer-date-is-author-date

1. Extraiga el historial en formato de correo electrónico

Ejemplo: historia Extracto de file3, file4yfile5

my_repo
├── dirA
│   ├── file1
│   └── file2
├── dirB            ^
│   ├── subdir      | To be moved
│   │   ├── file3   | with history
│   │   └── file4   | 
│   └── file5       v
└── dirC
    ├── file6
    └── file7

Establecer / limpiar el destino

export historydir=/tmp/mail/dir       # Absolute path
rm -rf "$historydir"    # Caution when cleaning the folder

Extraiga el historial de cada archivo en formato de correo electrónico

cd my_repo/dirB
find -name .git -prune -o -type d -o -exec bash -c 'mkdir -p "$historydir/${0%/*}" && git log --pretty=email -p --stat --reverse --full-index --binary -- "$0" > "$historydir/$0"' {} ';'

Lamentablemente opción --followo --find-copies-harderno se puede combinar con --reverse. Es por eso que el historial se corta cuando se cambia el nombre del archivo (o cuando se cambia el nombre de un directorio principal).

Historial temporal en formato de correo electrónico:

/tmp/mail/dir
    ├── subdir
    │   ├── file3
    │   └── file4
    └── file5

Dan Bonachea sugiere invertir los bucles del comando git log generation en este primer paso: en lugar de ejecutar git log una vez por archivo, ejecútelo exactamente una vez con una lista de archivos en la línea de comando y genere un único registro unificado. De esta manera, las confirmaciones que modifican varios archivos siguen siendo una única confirmación en el resultado, y todas las nuevas confirmaciones mantienen su orden relativo original. Tenga en cuenta que esto también requiere cambios en el segundo paso a continuación al reescribir nombres de archivo en el registro (ahora unificado).


2. Reorganice el árbol de archivos y actualice los nombres de archivo

Suponga que desea mover estos tres archivos en este otro repositorio (puede ser el mismo repositorio).

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB              # New tree
│   ├── dirB1         # from subdir
│   │   ├── file33    # from file3
│   │   └── file44    # from file4
│   └── dirB2         # new dir
│        └── file5    # from file5
└── dirH
    └── file77

Por lo tanto, reorganice sus archivos:

cd /tmp/mail/dir
mkdir -p dirB/dirB1
mv subdir/file3 dirB/dirB1/file33
mv subdir/file4 dirB/dirB1/file44
mkdir -p dirB/dirB2
mv file5 dirB/dirB2

Tu historial temporal es ahora:

/tmp/mail/dir
    └── dirB
        ├── dirB1
        │   ├── file33
        │   └── file44
        └── dirB2
             └── file5

Cambie también los nombres de archivo dentro del historial:

cd "$historydir"
find * -type f -exec bash -c 'sed "/^diff --git a\|^--- a\|^+++ b/s:\( [ab]\)/[^ ]*:\1/$0:g" -i "$0"' {} ';'

3. Aplicar nuevo historial

Su otro repositorio es:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
└── dirH
    └── file77

Aplicar confirmaciones de archivos de historial temporales:

cd my_other_repo
find "$historydir" -type f -exec cat {} + | git am --committer-date-is-author-date

--committer-date-is-author-dateconserva las marcas de tiempo de confirmación originales ( comentario de Dan Bonachea ).

Su otro repositorio es ahora:

my_other_repo
├── dirF
│   ├── file55
│   └── file56
├── dirB
│   ├── dirB1
│   │   ├── file33
│   │   └── file44
│   └── dirB2
│        └── file5
└── dirH
    └── file77

Use git statuspara ver la cantidad de confirmaciones listas para ser empujadas :-)


Truco adicional: verifique los archivos renombrados / movidos dentro de su repositorio

Para enumerar los archivos que han cambiado de nombre:

find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow {} ';' | grep '=>'

Más personalizaciones: puede completar el comando git logcon las opciones --find-copies-hardero --reverse. También puede eliminar las dos primeras columnas utilizando cut -f3-y agrupando el patrón completo '{. * =>. *}'.

find -name .git -prune -o -exec git log --pretty=tformat:'' --numstat --follow --find-copies-harder --reverse {} ';' | cut -f3- | grep '{.* => .*}'
olibre
fuente
44
CUIDADO: Esta técnica divide las confirmaciones que cambian 2 o más archivos en confirmaciones fragmentadas separadas, y además codifica su orden al ordenar por nombre de archivo (para que los fragmentos de una confirmación original no aparezcan adyacentes en el historial lineal). Por lo tanto, el historial resultante solo es "correcto" archivo por archivo. Si está moviendo más de un archivo, NINGUNO de los nuevos commits en el historial resultante representa una instantánea consistente de los archivos movidos que alguna vez existieron en el historial del repositorio original.
Dan Bonachea
2
Hola @DanBonachea. Gracias por sus interesantes comentarios. He migrado con éxito algunos repositorios que contienen varios archivos usando esta técnica (incluso con archivos renombrados y archivos movidos a través de directorios). ¿Qué sugieres cambiar en esta respuesta? ¿Crees que deberíamos agregar un banner de ADVERTENCIA en la parte superior de esta respuesta que explique las limitaciones de esta técnica? Saludos
olibre
2
Adapte esta técnica para evitar el problema invirtiendo los bucles del comando git log generation en el paso 1. Es decir. en lugar de ejecutar git log una vez por archivo, ejecútelo exactamente una vez con una lista de archivos en la línea de comando y genere un único registro unificado. De esta forma, las confirmaciones que modifican 2 o más archivos siguen siendo una confirmación única en el resultado, y todas las confirmaciones nuevas mantienen su orden relativo original. Tenga en cuenta que esto también requiere cambios en el paso 2 al reescribir nombres de archivo en el registro (ahora unificado). También usé git am --committer-date-is-author-date para preservar las marcas de tiempo de confirmación originales.
Dan Bonachea
1
Gracias por tu experimentación y compartir. He actualizado un poco la respuesta para otros lectores. Sin embargo, me he tomado el tiempo para probar su procesamiento. Siéntase libre de editar esta respuesta si desea proporcionar ejemplos de líneas de comando. Saludos;)
olibre
4

Seguí este proceso de varios pasos para mover el código al directorio principal y retener el historial.

Paso 0: creó un 'historial' de rama desde 'maestro' para su custodia

Paso 1: Utilicé la herramienta git-filter-repo para reescribir el historial. Este comando debajo movió la carpeta 'FolderwithContentOfInterest' a un nivel superior y modificó el historial de confirmación relevante

git filter-repo --path-rename ParentFolder/FolderwithContentOfInterest/:FolderwithContentOfInterest/ --force

Paso 2: En este momento, el repositorio de GitHub perdió su ruta de repositorio remoto. Referencia remota agregada

git remote add origin [email protected]:MyCompany/MyRepo.git

Paso 3: extraer información en el repositorio

git pull

Paso 4: conecte la rama local perdida con la rama de origen

git branch --set-upstream-to=origin/history history

Paso 5: solucione el conflicto de fusión de la estructura de carpetas si se le solicita

Paso 6: ¡ Empuja !

git push

Nota: El historial modificado y la carpeta movida parecen estar ya confirmados. enter code here

Hecho. ¡El código se mueve al directorio padre / deseado manteniendo el historial intacto!

Parag Bangad
fuente
2

Si bien el núcleo de Git, la plomería de Git no realiza un seguimiento de los cambios de nombre, el historial que muestra con la "porcelana" del registro de Git puede detectarlos si lo desea.

Para un git loguso determinado, la opción -M:

git log -p -M

Con una versión actual de Git.

Esto también funciona para otros comandos git diff.

Hay opciones para hacer las comparaciones más o menos rigurosas. Si cambia el nombre de un archivo sin realizar cambios significativos al mismo tiempo, facilita que Git log y sus amigos detecten el cambio de nombre. Por esta razón, algunas personas cambian el nombre de los archivos en una confirmación y los cambian en otra.

Hay un costo en el uso de la CPU cada vez que le pide a Git que encuentre dónde se han renombrado los archivos, por lo tanto, si lo usa o no, y cuándo, depende de usted.

Si desea que siempre se informe su historial con la detección de cambio de nombre en un repositorio particular, puede usar:

git config diff.renames 1

Se detectan archivos que se mueven de un directorio a otro . Aquí hay un ejemplo:

commit c3ee8dfb01e357eba1ab18003be1490a46325992
Author: John S. Gruber <[email protected]>
Date:   Wed Feb 22 22:20:19 2017 -0500

    test rename again

diff --git a/yyy/power.py b/zzz/power.py
similarity index 100%
rename from yyy/power.py
rename to zzz/power.py

commit ae181377154eca800832087500c258a20c95d1c3
Author: John S. Gruber <[email protected]>
Date:   Wed Feb 22 22:19:17 2017 -0500

    rename test

diff --git a/power.py b/yyy/power.py
similarity index 100%
rename from power.py
rename to yyy/power.py

Tenga en cuenta que esto funciona siempre que use diff, no solo con git log. Por ejemplo:

$ git diff HEAD c3ee8df
diff --git a/power.py b/zzz/power.py
similarity index 100%
rename from power.py
rename to zzz/power.py

Como prueba, realicé un pequeño cambio en un archivo en una rama de características y lo confirmé y luego en la rama maestra cambié el nombre del archivo, confirmé y luego hice un pequeño cambio en otra parte del archivo y lo confirmé. Cuando fui a la rama de características y fusioné desde master, la fusión cambió el nombre del archivo y fusionó los cambios. Aquí está el resultado de la fusión:

 $ git merge -v master
 Auto-merging single
 Merge made by the 'recursive' strategy.
  one => single | 4 ++++
  1 file changed, 4 insertions(+)
  rename one => single (67%)

El resultado fue un directorio de trabajo con el archivo renombrado y ambos cambios de texto realizados. Por lo tanto, es posible que Git haga lo correcto a pesar del hecho de que no rastrea explícitamente los cambios de nombre.

Esta es una respuesta tardía a una pregunta anterior, por lo que las otras respuestas pueden haber sido correctas para la versión de Git en ese momento.

John S Gruber
fuente
1

Primero cree un commit independiente con solo un cambio de nombre.

Luego, cualquier cambio eventual al contenido del archivo se coloca en la confirmación por separado.

Jakub Pawlowski
fuente
1

Para cambiar el nombre de un directorio o archivo (no sé mucho sobre casos complejos, por lo que puede haber algunas advertencias):

git filter-repo --path-rename OLD_NAME:NEW_NAME

Para cambiar el nombre de un directorio en archivos que lo mencionan (es posible usar devoluciones de llamada, pero no sé cómo):

git filter-repo --replace-text expressions.txt

expressions.txtes un archivo lleno de líneas como literal:OLD_NAME==>NEW_NAME(es posible usar RE con Python regex:o glob con glob:).

Para cambiar el nombre de un directorio en mensajes de confirmaciones:

git-filter-repo --message-callback 'return message.replace(b"OLD_NAME", b"NEW_NAME")'

Las expresiones regulares de Python también son compatibles, pero deben escribirse en Python, manualmente.

Si el repositorio es original, sin control remoto, deberá agregarlo --forcepara forzar una reescritura. (Es posible que desee crear una copia de seguridad de su repositorio antes de hacer esto).

Si no desea conservar las referencias (se mostrarán en el historial de ramas de la GUI de Git), deberá agregarlas --replace-refs delete-no-add.

Pugsley
fuente
0

Simplemente mueva el archivo y el escenario con:

git add .

Antes de confirmar puede verificar el estado:

git status

Eso mostrará:

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        renamed:    old-folder/file.txt -> new-folder/file.txt

Probé con Git versión 2.26.1.

Extraído de la página de ayuda de GitHub .

Júnior
fuente
-3

Hago mover los archivos y luego hago

git add -A

que ponen en el área de almacenamiento todos los archivos borrados / nuevos. Aquí git se da cuenta de que el archivo se mueve.

git commit -m "my message"
git push

No sé por qué, pero esto funciona para mí.

Xelian
fuente
El truco aquí es que no tiene que cambiar una sola letra, incluso si cambia algo y presiona Ctrl + Z, el historial se romperá. Entonces, en ese caso, si escribe algo, revierta el archivo y muévalo nuevamente y realice un solo add-> commit para él.
Xelian